1 /* Implementation of GUI terminal on the Mac OS.
2 Copyright (C) 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008 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 3, 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 #include <Quickdraw.h>
40 #include <ToolUtils.h>
44 #include <Resources.h>
46 #include <TextUtils.h>
51 #if defined (__MRC__) || (__MSL__ >= 0x6000)
52 #include <ControlDefinitions.h>
58 #endif /* not TARGET_API_MAC_CARBON */
71 #include "dispextern.h"
73 #include "termhooks.h"
80 #include "intervals.h"
86 /* Non-nil means Emacs uses toolkit scroll bars. */
88 Lisp_Object Vx_toolkit_scroll_bars
;
90 /* If non-zero, the text will be rendered using Core Graphics text
91 rendering which may anti-alias the text. */
92 int mac_use_core_graphics
;
94 /* Non-zero means make use of UNDERLINE_POSITION font properties.
95 (Not yet supported.) */
96 int x_use_underline_position_properties
;
98 /* Non-zero means to draw the underline at the same place as the descent line. */
100 int x_underline_at_descent_line
;
102 /* This is a chain of structures for all the X displays currently in
105 struct x_display_info
*x_display_list
;
107 /* This is a list of cons cells, each of the form (NAME
108 FONT-LIST-CACHE . RESOURCE-DATABASE), one for each element of
109 x_display_list and in the same order. NAME is the name of the
110 frame. FONT-LIST-CACHE records previous values returned by
111 x-list-fonts. RESOURCE-DATABASE preserves the X Resource Database
112 equivalent, which is implemented with a Lisp object, for the
115 Lisp_Object x_display_name_list
;
117 /* This is display since Mac does not support multiple ones. */
118 struct mac_display_info one_mac_display_info
;
120 /* Frame being updated by update_frame. This is declared in term.c.
121 This is set by update_begin and looked at by all the XT functions.
122 It is zero while not inside an update. In that case, the XT
123 functions assume that `selected_frame' is the frame to apply to. */
125 extern struct frame
*updating_frame
;
127 /* This is a frame waiting to be auto-raised, within XTread_socket. */
129 struct frame
*pending_autoraise_frame
;
133 Formerly, we used PointerMotionHintMask (in standard_event_mask)
134 so that we would have to call XQueryPointer after each MotionNotify
135 event to ask for another such event. However, this made mouse tracking
136 slow, and there was a bug that made it eventually stop.
138 Simply asking for MotionNotify all the time seems to work better.
140 In order to avoid asking for motion events and then throwing most
141 of them away or busy-polling the server for mouse positions, we ask
142 the server for pointer motion hints. This means that we get only
143 one event per group of mouse movements. "Groups" are delimited by
144 other kinds of events (focus changes and button clicks, for
145 example), or by XQueryPointer calls; when one of these happens, we
146 get another MotionNotify event the next time the mouse moves. This
147 is at least as efficient as getting motion events when mouse
148 tracking is on, and I suspect only negligibly worse when tracking
151 /* Where the mouse was last time we reported a mouse event. */
153 Rect last_mouse_glyph
;
154 FRAME_PTR last_mouse_glyph_frame
;
156 /* The scroll bar in which the last X motion event occurred.
158 If the last X motion event occurred in a scroll bar, we set this so
159 XTmouse_position can know whether to report a scroll bar motion or
162 If the last X motion event didn't occur in a scroll bar, we set
163 this to Qnil, to tell XTmouse_position to return an ordinary motion
166 Lisp_Object last_mouse_scroll_bar
;
168 /* This is a hack. We would really prefer that XTmouse_position would
169 return the time associated with the position it returns, but there
170 doesn't seem to be any way to wrest the time-stamp from the server
171 along with the position query. So, we just keep track of the time
172 of the last movement we received, and return that in hopes that
173 it's somewhat accurate. */
175 Time last_mouse_movement_time
;
177 struct scroll_bar
*tracked_scroll_bar
= NULL
;
179 /* Incremented by XTread_socket whenever it really tries to read
183 int volatile input_signal_count
;
185 int input_signal_count
;
188 extern Lisp_Object Vsystem_name
;
190 extern Lisp_Object Qeql
;
192 /* A mask of extra modifier bits to put into every keyboard char. */
194 extern EMACS_INT extra_keyboard_modifiers
;
196 /* The keysyms to use for the various modifiers. */
198 static Lisp_Object Qalt
, Qhyper
, Qsuper
, Qcontrol
, Qmeta
, Qmodifier_value
;
200 extern int inhibit_window_system
;
202 #if __MRC__ && !TARGET_API_MAC_CARBON
203 QDGlobals qd
; /* QuickDraw global information structure. */
206 struct mac_display_info
*mac_display_info_for_display (Display
*);
207 static void x_update_window_end
P_ ((struct window
*, int, int));
208 int x_catch_errors
P_ ((Display
*));
209 void x_uncatch_errors
P_ ((Display
*, int));
210 void x_lower_frame
P_ ((struct frame
*));
211 void x_scroll_bar_clear
P_ ((struct frame
*));
212 int x_had_errors_p
P_ ((Display
*));
213 void x_wm_set_size_hint
P_ ((struct frame
*, long, int));
214 void x_raise_frame
P_ ((struct frame
*));
215 void x_set_window_size
P_ ((struct frame
*, int, int, int));
216 void x_wm_set_window_state
P_ ((struct frame
*, int));
217 void x_wm_set_icon_pixmap
P_ ((struct frame
*, int));
218 void mac_initialize
P_ ((void));
219 static void x_font_min_bounds
P_ ((XFontStruct
*, int *, int *));
220 static int x_compute_min_glyph_bounds
P_ ((struct frame
*));
221 static void x_update_end
P_ ((struct frame
*));
222 static void XTframe_up_to_date
P_ ((struct frame
*));
223 static void XTset_terminal_modes
P_ ((void));
224 static void XTreset_terminal_modes
P_ ((void));
225 static void x_clear_frame
P_ ((void));
226 static void frame_highlight
P_ ((struct frame
*));
227 static void frame_unhighlight
P_ ((struct frame
*));
228 static void x_new_focus_frame
P_ ((struct x_display_info
*, struct frame
*));
229 static void XTframe_rehighlight
P_ ((struct frame
*));
230 static void x_frame_rehighlight
P_ ((struct x_display_info
*));
231 static void x_draw_hollow_cursor
P_ ((struct window
*, struct glyph_row
*));
232 static void x_draw_bar_cursor
P_ ((struct window
*, struct glyph_row
*, int,
233 enum text_cursor_kinds
));
235 static void x_clip_to_row
P_ ((struct window
*, struct glyph_row
*, int, GC
));
236 static void x_update_begin
P_ ((struct frame
*));
237 static void x_update_window_begin
P_ ((struct window
*));
238 static void x_after_update_window_line
P_ ((struct glyph_row
*));
240 static XCharStruct
*mac_per_char_metric
P_ ((XFontStruct
*, XChar2b
*, int));
241 static void XSetFont
P_ ((Display
*, GC
, XFontStruct
*));
243 extern void mac_toolbox_initialize
P_ ((void));
244 extern void x_scroll_bar_report_motion
P_ ((struct frame
**, Lisp_Object
*,
245 enum scroll_bar_part
*,
246 Lisp_Object
*, Lisp_Object
*,
249 extern void mac_flush_display_optional
P_ ((struct frame
*));
252 #define GC_FORE_COLOR(gc) (&(gc)->fore_color)
253 #define GC_BACK_COLOR(gc) (&(gc)->back_color)
254 #define GC_FONT(gc) ((gc)->xgcv.font)
255 #define FRAME_NORMAL_GC(f) ((f)->output_data.mac->normal_gc)
257 #define CG_SET_FILL_COLOR(context, color) \
258 CGContextSetRGBFillColor (context, \
259 RED_FROM_ULONG (color) / 255.0f, \
260 GREEN_FROM_ULONG (color) / 255.0f, \
261 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
262 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
263 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
264 #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
266 if (CGColorGetTypeID != NULL) \
267 CGContextSetFillColorWithColor (context, cg_color); \
269 CG_SET_FILL_COLOR (context, color); \
272 #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
273 CGContextSetFillColorWithColor (context, cg_color)
276 #define CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
277 CG_SET_FILL_COLOR (context, color)
279 #define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, gc) \
280 CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
282 #define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, gc) \
283 CG_SET_FILL_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.background, \
287 #define CG_SET_STROKE_COLOR(context, color) \
288 CGContextSetRGBStrokeColor (context, \
289 RED_FROM_ULONG (color) / 255.0f, \
290 GREEN_FROM_ULONG (color) / 255.0f, \
291 BLUE_FROM_ULONG (color) / 255.0f, 1.0f)
292 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
293 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
294 #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
296 if (CGColorGetTypeID != NULL) \
297 CGContextSetStrokeColorWithColor (context, cg_color); \
299 CG_SET_STROKE_COLOR (context, color); \
302 #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
303 CGContextSetStrokeColorWithColor (context, cg_color)
306 #define CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR(context, color, cg_color) \
307 CG_SET_STROKE_COLOR (context, color)
309 #define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, gc) \
310 CG_SET_STROKE_COLOR_MAYBE_WITH_CGCOLOR (context, (gc)->xgcv.foreground, \
314 /* Fringe bitmaps. */
316 static int max_fringe_bmp
= 0;
317 static CGImageRef
*fringe_bmp
= 0;
319 static CGColorSpaceRef mac_cg_color_space_rgb
;
320 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
321 static CGColorRef mac_cg_color_black
;
327 mac_cg_color_space_rgb
= CGColorSpaceCreateDeviceRGB ();
328 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
329 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
330 /* Don't check the availability of CGColorCreate; this symbol is
331 defined even in Mac OS X 10.1. */
332 if (CGColorGetTypeID
!= NULL
)
335 float rgba
[] = {0.0f
, 0.0f
, 0.0f
, 1.0f
};
337 mac_cg_color_black
= CGColorCreate (mac_cg_color_space_rgb
, rgba
);
341 #endif /* USE_CG_DRAWING */
343 /* X display function emulation */
345 /* Mac version of XDrawLine. */
348 mac_draw_line (f
, gc
, x1
, y1
, x2
, y2
)
354 CGContextRef context
;
355 float gx1
= x1
, gy1
= y1
, gx2
= x2
, gy2
= y2
;
358 gx1
+= 0.5f
, gx2
+= 0.5f
;
360 gy1
+= 0.5f
, gy2
+= 0.5f
;
362 context
= mac_begin_cg_clip (f
, gc
);
363 CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context
, gc
);
364 CGContextBeginPath (context
);
365 CGContextMoveToPoint (context
, gx1
, gy1
);
366 CGContextAddLineToPoint (context
, gx2
, gy2
);
367 CGContextClosePath (context
);
368 CGContextStrokePath (context
);
386 mac_begin_clip (f
, gc
);
387 RGBForeColor (GC_FORE_COLOR (gc
));
390 mac_end_clip (f
, gc
);
394 /* Mac version of XDrawLine (to Pixmap). */
397 XDrawLine (display
, p
, gc
, x1
, y1
, x2
, y2
)
421 GetGWorld (&old_port
, &old_gdh
);
424 RGBForeColor (GC_FORE_COLOR (gc
));
426 LockPixels (GetGWorldPixMap (p
));
429 UnlockPixels (GetGWorldPixMap (p
));
431 SetGWorld (old_port
, old_gdh
);
436 mac_erase_rectangle (f
, gc
, x
, y
, width
, height
)
440 unsigned int width
, height
;
444 CGContextRef context
;
446 context
= mac_begin_cg_clip (f
, gc
);
447 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context
, gc
);
448 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
455 mac_begin_clip (f
, gc
);
456 RGBBackColor (GC_BACK_COLOR (gc
));
457 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
459 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
460 mac_end_clip (f
, gc
);
466 /* Mac version of XClearArea. */
469 mac_clear_area (f
, x
, y
, width
, height
)
472 unsigned int width
, height
;
474 mac_erase_rectangle (f
, FRAME_NORMAL_GC (f
), x
, y
, width
, height
);
477 /* Mac version of XClearWindow. */
485 CGContextRef context
;
486 GC gc
= FRAME_NORMAL_GC (f
);
488 context
= mac_begin_cg_clip (f
, NULL
);
489 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context
, gc
);
490 CGContextFillRect (context
, CGRectMake (0, 0, FRAME_PIXEL_WIDTH (f
),
491 FRAME_PIXEL_HEIGHT (f
)));
494 #else /* !USE_CG_DRAWING */
495 mac_begin_clip (f
, NULL
);
496 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
497 #if TARGET_API_MAC_CARBON
501 GetWindowPortBounds (FRAME_MAC_WINDOW (f
), &r
);
504 #else /* not TARGET_API_MAC_CARBON */
505 EraseRect (&(FRAME_MAC_WINDOW (f
)->portRect
));
506 #endif /* not TARGET_API_MAC_CARBON */
507 mac_end_clip (f
, NULL
);
512 /* Mac replacement for XCopyArea. */
516 mac_draw_cg_image (image
, f
, gc
, src_x
, src_y
, width
, height
,
517 dest_x
, dest_y
, overlay_p
)
522 unsigned int width
, height
;
523 int dest_x
, dest_y
, overlay_p
;
525 CGContextRef context
;
526 float port_height
= FRAME_PIXEL_HEIGHT (f
);
527 CGRect dest_rect
= CGRectMake (dest_x
, dest_y
, width
, height
);
529 context
= mac_begin_cg_clip (f
, gc
);
532 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context
, gc
);
533 CGContextFillRect (context
, dest_rect
);
535 CGContextClipToRect (context
, dest_rect
);
536 CGContextScaleCTM (context
, 1, -1);
537 CGContextTranslateCTM (context
, 0, -port_height
);
538 if (CGImageIsMask (image
))
539 CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context
, gc
);
540 CGContextDrawImage (context
,
541 CGRectMake (dest_x
- src_x
,
542 port_height
- (dest_y
- src_y
543 + CGImageGetHeight (image
)),
544 CGImageGetWidth (image
),
545 CGImageGetHeight (image
)),
550 #else /* !USE_CG_DRAWING */
553 mac_draw_bitmap (f
, gc
, x
, y
, width
, height
, bits
, overlay_p
)
556 int x
, y
, width
, height
;
557 unsigned short *bits
;
563 bitmap
.rowBytes
= sizeof(unsigned short);
564 bitmap
.baseAddr
= (char *)bits
;
565 SetRect (&(bitmap
.bounds
), 0, 0, width
, height
);
567 mac_begin_clip (f
, gc
);
568 RGBForeColor (GC_FORE_COLOR (gc
));
569 RGBBackColor (GC_BACK_COLOR (gc
));
570 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
571 #if TARGET_API_MAC_CARBON
577 CopyBits (&bitmap
, GetPortBitMapForCopyBits (port
),
578 &(bitmap
.bounds
), &r
, overlay_p
? srcOr
: srcCopy
, 0);
579 UnlockPortBits (port
);
581 #else /* not TARGET_API_MAC_CARBON */
582 CopyBits (&bitmap
, &(FRAME_MAC_WINDOW (f
)->portBits
), &(bitmap
.bounds
), &r
,
583 overlay_p
? srcOr
: srcCopy
, 0);
584 #endif /* not TARGET_API_MAC_CARBON */
585 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
586 mac_end_clip (f
, gc
);
588 #endif /* !USE_CG_DRAWING */
591 /* Mac replacement for XCreateBitmapFromBitmapData. */
594 mac_create_bitmap_from_bitmap_data (bitmap
, bits
, w
, h
)
599 static const unsigned char swap_nibble
[16]
600 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
601 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
602 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
603 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
607 w1
= (w
+ 7) / 8; /* nb of 8bits elt in X bitmap */
608 bitmap
->rowBytes
= ((w
+ 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
609 bitmap
->baseAddr
= xmalloc (bitmap
->rowBytes
* h
);
610 bzero (bitmap
->baseAddr
, bitmap
->rowBytes
* h
);
611 for (i
= 0; i
< h
; i
++)
613 p
= bitmap
->baseAddr
+ i
* bitmap
->rowBytes
;
614 for (j
= 0; j
< w1
; j
++)
616 /* Bitswap XBM bytes to match how Mac does things. */
617 unsigned char c
= *bits
++;
618 *p
++ = (unsigned char)((swap_nibble
[c
& 0xf] << 4)
619 | (swap_nibble
[(c
>>4) & 0xf]));
623 SetRect (&(bitmap
->bounds
), 0, 0, w
, h
);
628 mac_free_bitmap (bitmap
)
631 xfree (bitmap
->baseAddr
);
636 XCreatePixmap (display
, w
, width
, height
, depth
)
639 unsigned int width
, height
;
646 SetPortWindowPort (w
);
648 SetRect (&r
, 0, 0, width
, height
);
649 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
652 err
= NewGWorld (&pixmap
, depth
, &r
, NULL
, NULL
, 0);
653 #if !defined (WORDS_BIG_ENDIAN) && USE_CG_DRAWING
655 /* CreateCGImageFromPixMaps requires ARGB format. */
656 err
= QTNewGWorld (&pixmap
, k32ARGBPixelFormat
, &r
, NULL
, NULL
, 0);
665 XCreatePixmapFromBitmapData (display
, w
, data
, width
, height
, fg
, bg
, depth
)
669 unsigned int width
, height
;
670 unsigned long fg
, bg
;
680 gc
= XCreateGC (display
, w
, 0, NULL
);
682 pixmap
= XCreatePixmap (display
, w
, width
, height
, depth
);
686 GetGWorld (&old_port
, &old_gdh
);
687 SetGWorld (pixmap
, NULL
);
688 mac_create_bitmap_from_bitmap_data (&bitmap
, data
, width
, height
);
689 XSetForeground (display
, gc
, fg
);
690 XSetBackground (display
, gc
, bg
);
691 RGBForeColor (GC_FORE_COLOR (gc
));
692 RGBBackColor (GC_BACK_COLOR (gc
));
693 LockPixels (GetGWorldPixMap (pixmap
));
694 #if TARGET_API_MAC_CARBON
695 CopyBits (&bitmap
, GetPortBitMapForCopyBits (pixmap
),
696 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
697 #else /* not TARGET_API_MAC_CARBON */
698 CopyBits (&bitmap
, &(((GrafPtr
)pixmap
)->portBits
),
699 &bitmap
.bounds
, &bitmap
.bounds
, srcCopy
, 0);
700 #endif /* not TARGET_API_MAC_CARBON */
701 UnlockPixels (GetGWorldPixMap (pixmap
));
702 SetGWorld (old_port
, old_gdh
);
703 mac_free_bitmap (&bitmap
);
710 XFreePixmap (display
, pixmap
)
714 DisposeGWorld (pixmap
);
718 /* Mac replacement for XFillRectangle. */
721 mac_fill_rectangle (f
, gc
, x
, y
, width
, height
)
725 unsigned int width
, height
;
728 CGContextRef context
;
730 context
= mac_begin_cg_clip (f
, gc
);
731 CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context
, gc
);
732 CGContextFillRect (context
, CGRectMake (x
, y
, width
, height
));
737 mac_begin_clip (f
, gc
);
738 RGBForeColor (GC_FORE_COLOR (gc
));
739 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
740 PaintRect (&r
); /* using foreground color of gc */
741 mac_end_clip (f
, gc
);
746 /* Mac replacement for XDrawRectangle: dest is a window. */
749 mac_draw_rectangle (f
, gc
, x
, y
, width
, height
)
753 unsigned int width
, height
;
756 CGContextRef context
;
758 context
= mac_begin_cg_clip (f
, gc
);
759 CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context
, gc
);
760 CGContextStrokeRect (context
,
761 CGRectMake (x
+ 0.5f
, y
+ 0.5f
, width
, height
));
766 mac_begin_clip (f
, gc
);
767 RGBForeColor (GC_FORE_COLOR (gc
));
768 SetRect (&r
, x
, y
, x
+ width
+ 1, y
+ height
+ 1);
769 FrameRect (&r
); /* using foreground color of gc */
770 mac_end_clip (f
, gc
);
776 mac_invert_rectangle (f
, x
, y
, width
, height
)
779 unsigned int width
, height
;
783 mac_begin_clip (f
, NULL
);
784 SetRect (&r
, x
, y
, x
+ width
, y
+ height
);
786 mac_end_clip (f
, NULL
);
792 atsu_get_text_layout_with_text_ptr (text
, text_length
, style
, text_layout
)
793 ConstUniCharArrayPtr text
;
794 UniCharCount text_length
;
796 ATSUTextLayout
*text_layout
;
799 static ATSUTextLayout saved_text_layout
= NULL
;
801 if (saved_text_layout
== NULL
)
803 static const UniCharCount lengths
[] = {kATSUToTextEnd
};
804 static const ATSUAttributeTag tags
[] = {kATSULineLayoutOptionsTag
};
805 static const ByteCount sizes
[] = {sizeof (ATSLineLayoutOptions
)};
806 static ATSLineLayoutOptions line_layout
=
807 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
808 kATSLineDisableAllLayoutOperations
| kATSLineUseDeviceMetrics
809 | kATSLineUseQDRendering
811 kATSLineIsDisplayOnly
| kATSLineFractDisable
814 static const ATSUAttributeValuePtr values
[] = {&line_layout
};
816 err
= ATSUCreateTextLayoutWithTextPtr (text
,
817 kATSUFromTextBeginning
,
823 err
= ATSUSetLayoutControls (saved_text_layout
,
824 sizeof (tags
) / sizeof (tags
[0]),
825 tags
, sizes
, values
);
827 err
= ATSUSetTransientFontMatching (saved_text_layout
, true);
831 err
= ATSUSetRunStyle (saved_text_layout
, style
,
832 kATSUFromTextBeginning
, kATSUToTextEnd
);
834 err
= ATSUSetTextPointerLocation (saved_text_layout
, text
,
835 kATSUFromTextBeginning
,
841 *text_layout
= saved_text_layout
;
847 mac_draw_image_string_atsui (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
848 overstrike_p
, bytes_per_char
)
853 int nchars
, bg_width
, overstrike_p
, bytes_per_char
;
856 ATSUTextLayout text_layout
;
858 xassert (bytes_per_char
== 2);
860 #ifndef WORDS_BIG_ENDIAN
863 UniChar
*text
= (UniChar
*)buf
;
865 for (i
= 0; i
< nchars
; i
++)
866 text
[i
] = EndianU16_BtoN (text
[i
]);
869 err
= atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr
)buf
,
871 GC_FONT (gc
)->mac_style
,
876 if (!mac_use_core_graphics
)
879 mac_begin_clip (f
, gc
);
880 RGBForeColor (GC_FORE_COLOR (gc
));
885 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
886 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
887 RGBBackColor (GC_BACK_COLOR (gc
));
889 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
892 ATSUDrawText (text_layout
,
893 kATSUFromTextBeginning
, kATSUToTextEnd
,
894 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
898 ATSUDrawText (text_layout
,
899 kATSUFromTextBeginning
, kATSUToTextEnd
,
900 kATSUUseGrafPortPenLoc
, kATSUUseGrafPortPenLoc
);
902 mac_end_clip (f
, gc
);
907 static CGContextRef context
;
908 float port_height
= FRAME_PIXEL_HEIGHT (f
);
909 static const ATSUAttributeTag tags
[] = {kATSUCGContextTag
};
910 static const ByteCount sizes
[] = {sizeof (CGContextRef
)};
911 static const ATSUAttributeValuePtr values
[] = {&context
};
914 context
= mac_begin_cg_clip (f
, gc
);
919 QDBeginCGContext (port
, &context
);
920 if (gc
->n_clip_rects
|| bg_width
)
922 CGContextTranslateCTM (context
, 0, port_height
);
923 CGContextScaleCTM (context
, 1, -1);
924 if (gc
->n_clip_rects
)
925 CGContextClipToRects (context
, gc
->clip_rects
,
930 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context
, gc
);
931 CGContextFillRect (context
,
932 CGRectMake (x
, y
- FONT_BASE (GC_FONT (gc
)),
934 FONT_HEIGHT (GC_FONT (gc
))));
936 CGContextScaleCTM (context
, 1, -1);
937 CGContextTranslateCTM (context
, 0, -port_height
);
941 CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context
, gc
);
942 err
= ATSUSetLayoutControls (text_layout
,
943 sizeof (tags
) / sizeof (tags
[0]),
944 tags
, sizes
, values
);
947 ATSUDrawText (text_layout
,
948 kATSUFromTextBeginning
, kATSUToTextEnd
,
949 Long2Fix (x
), Long2Fix (port_height
- y
));
951 ATSUDrawText (text_layout
,
952 kATSUFromTextBeginning
, kATSUToTextEnd
,
953 Long2Fix (x
+ 1), Long2Fix (port_height
- y
));
959 CGContextSynchronize (context
);
960 QDEndCGContext (port
, &context
);
963 /* This doesn't work on Mac OS X 10.1. */
964 ATSUClearLayoutControls (text_layout
,
965 sizeof (tags
) / sizeof (tags
[0]), tags
);
967 ATSUSetLayoutControls (text_layout
,
968 sizeof (tags
) / sizeof (tags
[0]),
969 tags
, sizes
, values
);
974 #endif /* USE_ATSUI */
978 mac_draw_image_string_qd (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
979 overstrike_p
, bytes_per_char
)
984 int nchars
, bg_width
, overstrike_p
, bytes_per_char
;
986 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
990 mac_begin_clip (f
, gc
);
991 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
992 if (mac_use_core_graphics
)
993 savedFlags
= SwapQDTextFlags (kQDUseCGTextRendering
);
995 RGBForeColor (GC_FORE_COLOR (gc
));
999 RGBBackColor (GC_BACK_COLOR (gc
));
1005 /* We prefer not to use srcCopy text transfer mode on Mac OS X
1007 - Screen is double-buffered. (In srcCopy mode, a text is drawn
1008 into an offscreen graphics world first. So performance gain
1009 cannot be expected.)
1010 - It lowers rendering quality.
1011 - Some fonts leave garbage on cursor movement. */
1016 RGBBackColor (GC_BACK_COLOR (gc
));
1017 SetRect (&r
, x
, y
- FONT_BASE (GC_FONT (gc
)),
1018 x
+ bg_width
, y
+ FONT_DESCENT (GC_FONT (gc
)));
1023 TextFont (GC_FONT (gc
)->mac_fontnum
);
1024 TextSize (GC_FONT (gc
)->mac_fontsize
);
1025 TextFace (GC_FONT (gc
)->mac_fontface
);
1027 DrawText (buf
, 0, nchars
* bytes_per_char
);
1032 DrawText (buf
, 0, nchars
* bytes_per_char
);
1035 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1036 mac_end_clip (f
, gc
);
1038 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1039 if (mac_use_core_graphics
)
1040 SwapQDTextFlags(savedFlags
);
1046 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1047 overstrike_p
, bytes_per_char
)
1052 int nchars
, bg_width
, overstrike_p
, bytes_per_char
;
1055 if (GC_FONT (gc
)->mac_style
)
1056 mac_draw_image_string_atsui (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1057 overstrike_p
, bytes_per_char
);
1059 #endif /* USE_ATSUI */
1060 mac_draw_image_string_qd (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1061 overstrike_p
, bytes_per_char
);
1065 /* Mac replacement for XDrawImageString. */
1068 mac_draw_image_string (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1073 int nchars
, bg_width
, overstrike_p
;
1075 mac_draw_string_common (f
, gc
, x
, y
, buf
, nchars
, bg_width
,
1080 /* Mac replacement for XDrawImageString16. */
1083 mac_draw_image_string_16 (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1088 int nchars
, bg_width
, overstrike_p
;
1090 mac_draw_string_common (f
, gc
, x
, y
, (char *) buf
, nchars
, bg_width
,
1095 /* Mac replacement for XQueryTextExtents, but takes a character. If
1096 STYLE is NULL, measurement is done by QuickDraw Text routines for
1097 the font of the current graphics port. If CG_GLYPH is not NULL,
1098 *CG_GLYPH is set to the glyph ID or 0 if it cannot be obtained. */
1101 mac_query_char_extents (style
, c
,
1102 font_ascent_return
, font_descent_return
,
1103 overall_return
, cg_glyph
)
1110 int *font_ascent_return
, *font_descent_return
;
1111 XCharStruct
*overall_return
;
1112 #if USE_CG_TEXT_DRAWING
1118 OSStatus err
= noErr
;
1125 ATSUTextLayout text_layout
;
1128 err
= atsu_get_text_layout_with_text_ptr (&ch
, 1, style
, &text_layout
);
1130 && (font_ascent_return
|| font_descent_return
|| overall_return
))
1132 ATSTrapezoid glyph_bounds
;
1134 err
= ATSUGetGlyphBounds (text_layout
, 0, 0,
1135 kATSUFromTextBeginning
, kATSUToTextEnd
,
1136 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
1137 kATSUseFractionalOrigins
,
1139 kATSUseDeviceOrigins
,
1141 1, &glyph_bounds
, NULL
);
1144 xassert (glyph_bounds
.lowerRight
.x
- glyph_bounds
.lowerLeft
.x
1145 == glyph_bounds
.upperRight
.x
- glyph_bounds
.upperLeft
.x
);
1147 width
= Fix2Long (glyph_bounds
.upperRight
.x
1148 - glyph_bounds
.upperLeft
.x
);
1149 if (font_ascent_return
)
1150 *font_ascent_return
= -Fix2Long (glyph_bounds
.upperLeft
.y
);
1151 if (font_descent_return
)
1152 *font_descent_return
= Fix2Long (glyph_bounds
.lowerLeft
.y
);
1155 if (err
== noErr
&& overall_return
)
1157 err
= ATSUMeasureTextImage (text_layout
,
1158 kATSUFromTextBeginning
, kATSUToTextEnd
,
1159 0, 0, &char_bounds
);
1161 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1162 #if USE_CG_TEXT_DRAWING
1163 if (err
== noErr
&& cg_glyph
)
1166 ATSUGlyphInfoArray glyph_info_array
;
1167 ByteCount count
= sizeof (ATSUGlyphInfoArray
);
1169 err1
= ATSUMatchFontsToText (text_layout
, kATSUFromTextBeginning
,
1170 kATSUToTextEnd
, NULL
, NULL
, NULL
);
1172 err1
= ATSUGetGlyphInfo (text_layout
, kATSUFromTextBeginning
,
1173 kATSUToTextEnd
, &count
,
1176 /* Make sure that we don't have to make layout
1178 && glyph_info_array
.glyphs
[0].deltaY
== 0.0f
1179 && glyph_info_array
.glyphs
[0].idealX
== 0.0f
1180 && glyph_info_array
.glyphs
[0].screenX
== 0)
1182 xassert (glyph_info_array
.glyphs
[0].glyphID
);
1183 *cg_glyph
= glyph_info_array
.glyphs
[0].glyphID
;
1194 if (font_ascent_return
|| font_descent_return
)
1198 GetFontInfo (&font_info
);
1199 if (font_ascent_return
)
1200 *font_ascent_return
= font_info
.ascent
;
1201 if (font_descent_return
)
1202 *font_descent_return
= font_info
.descent
;
1208 width
= CharWidth (ch
);
1209 QDTextBounds (1, &ch
, &char_bounds
);
1210 STORE_XCHARSTRUCT (*overall_return
, width
, char_bounds
);
1218 /* Mac replacement for XTextExtents16. Only sets horizontal metrics. */
1221 mac_text_extents_16 (font_struct
, string
, nchars
, overall_return
)
1222 XFontStruct
*font_struct
;
1225 XCharStruct
*overall_return
;
1228 short width
= 0, lbearing
= 0, rbearing
= 0;
1231 for (i
= 0; i
< nchars
; i
++)
1233 pcm
= mac_per_char_metric (font_struct
, string
, 0);
1235 width
+= FONT_WIDTH (font_struct
);
1238 lbearing
= min (lbearing
, width
+ pcm
->lbearing
);
1239 rbearing
= max (rbearing
, width
+ pcm
->rbearing
);
1240 width
+= pcm
->width
;
1245 overall_return
->lbearing
= lbearing
;
1246 overall_return
->rbearing
= rbearing
;
1247 overall_return
->width
= width
;
1249 /* What's the meaning of the return value of XTextExtents16? */
1253 #if USE_CG_TEXT_DRAWING
1254 static int cg_text_anti_aliasing_threshold
= 8;
1257 init_cg_text_anti_aliasing_threshold ()
1263 CFPreferencesGetAppIntegerValue (CFSTR ("AppleAntiAliasingThreshold"),
1264 kCFPreferencesCurrentApplication
,
1267 cg_text_anti_aliasing_threshold
= threshold
;
1271 mac_draw_image_string_cg (f
, gc
, x
, y
, buf
, nchars
, bg_width
, overstrike_p
)
1276 int nchars
, bg_width
, overstrike_p
;
1278 float port_height
, gx
, gy
;
1280 CGContextRef context
;
1284 if (!mac_use_core_graphics
|| GC_FONT (gc
)->cg_font
== NULL
)
1287 port_height
= FRAME_PIXEL_HEIGHT (f
);
1289 gy
= port_height
- y
;
1290 glyphs
= (CGGlyph
*)buf
;
1291 advances
= alloca (sizeof (CGSize
) * nchars
);
1292 if (advances
== NULL
)
1294 for (i
= 0; i
< nchars
; i
++)
1296 XCharStruct
*pcm
= mac_per_char_metric (GC_FONT (gc
), buf
, 0);
1298 advances
[i
].width
= pcm
->width
;
1299 advances
[i
].height
= 0;
1300 glyphs
[i
] = GC_FONT (gc
)->cg_glyphs
[buf
->byte2
];
1305 context
= mac_begin_cg_clip (f
, gc
);
1307 QDBeginCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)), &context
);
1308 if (gc
->n_clip_rects
|| bg_width
)
1310 CGContextTranslateCTM (context
, 0, port_height
);
1311 CGContextScaleCTM (context
, 1, -1);
1312 if (gc
->n_clip_rects
)
1313 CGContextClipToRects (context
, gc
->clip_rects
, gc
->n_clip_rects
);
1317 CG_SET_FILL_COLOR_WITH_GC_BACKGROUND (context
, gc
);
1320 CGRectMake (gx
, y
- FONT_BASE (GC_FONT (gc
)),
1321 bg_width
, FONT_HEIGHT (GC_FONT (gc
))));
1323 CGContextScaleCTM (context
, 1, -1);
1324 CGContextTranslateCTM (context
, 0, -port_height
);
1328 CG_SET_FILL_COLOR_WITH_GC_FOREGROUND (context
, gc
);
1329 CGContextSetFont (context
, GC_FONT (gc
)->cg_font
);
1330 CGContextSetFontSize (context
, GC_FONT (gc
)->mac_fontsize
);
1331 CGContextSetTextMatrix (context
, CGAffineTransformIdentity
);
1332 if (GC_FONT (gc
)->mac_fontsize
<= cg_text_anti_aliasing_threshold
)
1333 CGContextSetShouldAntialias (context
, false);
1334 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1335 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1336 if (CGContextShowGlyphsWithAdvances
!= NULL
)
1339 CGContextSetTextPosition (context
, gx
, gy
);
1340 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1343 CGContextSetTextPosition (context
, gx
+ 1.0f
, gy
);
1344 CGContextShowGlyphsWithAdvances (context
, glyphs
, advances
, nchars
);
1347 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1348 else /* CGContextShowGlyphsWithAdvances == NULL */
1350 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
1351 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1353 for (i
= 0; i
< nchars
; i
++)
1355 CGContextShowGlyphsAtPoint (context
, gx
, gy
, glyphs
+ i
, 1);
1357 CGContextShowGlyphsAtPoint (context
, gx
+ 1.0f
, gy
, glyphs
+ i
, 1);
1358 gx
+= advances
[i
].width
;
1363 mac_end_cg_clip (f
);
1365 CGContextSynchronize (context
);
1366 QDEndCGContext (GetWindowPort (FRAME_MAC_WINDOW (f
)), &context
);
1375 /* Mac replacement for XCopyArea: dest must be window. */
1378 mac_copy_area (src
, f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1383 unsigned int width
, height
;
1388 mac_begin_clip (f
, gc
);
1390 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1391 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1393 ForeColor (blackColor
);
1394 BackColor (whiteColor
);
1396 LockPixels (GetGWorldPixMap (src
));
1397 #if TARGET_API_MAC_CARBON
1402 LockPortBits (port
);
1403 CopyBits (GetPortBitMapForCopyBits (src
),
1404 GetPortBitMapForCopyBits (port
),
1405 &src_r
, &dest_r
, srcCopy
, 0);
1406 UnlockPortBits (port
);
1408 #else /* not TARGET_API_MAC_CARBON */
1409 CopyBits (&(((GrafPtr
)src
)->portBits
), &(FRAME_MAC_WINDOW (f
)->portBits
),
1410 &src_r
, &dest_r
, srcCopy
, 0);
1411 #endif /* not TARGET_API_MAC_CARBON */
1412 UnlockPixels (GetGWorldPixMap (src
));
1414 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1416 mac_end_clip (f
, gc
);
1421 mac_copy_area_with_mask (src
, mask
, f
, gc
, src_x
, src_y
,
1422 width
, height
, dest_x
, dest_y
)
1427 unsigned int width
, height
;
1432 mac_begin_clip (f
, gc
);
1434 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1435 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1437 ForeColor (blackColor
);
1438 BackColor (whiteColor
);
1440 LockPixels (GetGWorldPixMap (src
));
1441 LockPixels (GetGWorldPixMap (mask
));
1442 #if TARGET_API_MAC_CARBON
1447 LockPortBits (port
);
1448 CopyMask (GetPortBitMapForCopyBits (src
), GetPortBitMapForCopyBits (mask
),
1449 GetPortBitMapForCopyBits (port
),
1450 &src_r
, &src_r
, &dest_r
);
1451 UnlockPortBits (port
);
1453 #else /* not TARGET_API_MAC_CARBON */
1454 CopyMask (&(((GrafPtr
)src
)->portBits
), &(((GrafPtr
)mask
)->portBits
),
1455 &(FRAME_MAC_WINDOW (f
)->portBits
), &src_r
, &src_r
, &dest_r
);
1456 #endif /* not TARGET_API_MAC_CARBON */
1457 UnlockPixels (GetGWorldPixMap (mask
));
1458 UnlockPixels (GetGWorldPixMap (src
));
1460 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1462 mac_end_clip (f
, gc
);
1464 #endif /* !USE_CG_DRAWING */
1467 /* Mac replacement for XCopyArea: used only for scrolling. */
1469 #if TARGET_API_MAC_CARBON
1470 /* Defined in mactoolbox.c. */
1471 extern void mac_scroll_area
P_ ((struct frame
*, GC
, int, int,
1472 unsigned int, unsigned int, int, int));
1473 #else /* not TARGET_API_MAC_CARBON */
1475 mac_scroll_area (f
, gc
, src_x
, src_y
, width
, height
, dest_x
, dest_y
)
1479 unsigned int width
, height
;
1483 WindowRef w
= FRAME_MAC_WINDOW (f
);
1485 mac_begin_clip (f
, gc
);
1487 SetRect (&src_r
, src_x
, src_y
, src_x
+ width
, src_y
+ height
);
1488 SetRect (&dest_r
, dest_x
, dest_y
, dest_x
+ width
, dest_y
+ height
);
1490 /* In Color QuickDraw, set ForeColor and BackColor as follows to avoid
1491 color mapping in CopyBits. Otherwise, it will be slow. */
1492 ForeColor (blackColor
);
1493 BackColor (whiteColor
);
1494 CopyBits (&(w
->portBits
), &(w
->portBits
), &src_r
, &dest_r
, srcCopy
, 0);
1496 RGBBackColor (GC_BACK_COLOR (FRAME_NORMAL_GC (f
)));
1498 mac_end_clip (f
, gc
);
1500 #endif /* not TARGET_API_MAC_CARBON */
1503 /* Mac replacement for XChangeGC. */
1506 XChangeGC (display
, gc
, mask
, xgcv
)
1512 if (mask
& GCForeground
)
1513 XSetForeground (display
, gc
, xgcv
->foreground
);
1514 if (mask
& GCBackground
)
1515 XSetBackground (display
, gc
, xgcv
->background
);
1517 XSetFont (display
, gc
, xgcv
->font
);
1521 /* Mac replacement for XCreateGC. */
1524 XCreateGC (display
, d
, mask
, xgcv
)
1530 GC gc
= xmalloc (sizeof (*gc
));
1532 bzero (gc
, sizeof (*gc
));
1533 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1534 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1535 if (CGColorGetTypeID
!= NULL
)
1538 gc
->cg_fore_color
= gc
->cg_back_color
= mac_cg_color_black
;
1539 CGColorRetain (gc
->cg_fore_color
);
1540 CGColorRetain (gc
->cg_back_color
);
1543 XChangeGC (display
, gc
, mask
, xgcv
);
1549 /* Used in xfaces.c. */
1552 XFreeGC (display
, gc
)
1556 if (gc
->clip_region
)
1557 DisposeRgn (gc
->clip_region
);
1558 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1559 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1560 if (CGColorGetTypeID
!= NULL
)
1563 CGColorRelease (gc
->cg_fore_color
);
1564 CGColorRelease (gc
->cg_back_color
);
1571 /* Mac replacement for XGetGCValues. */
1574 XGetGCValues (display
, gc
, mask
, xgcv
)
1580 if (mask
& GCForeground
)
1581 xgcv
->foreground
= gc
->xgcv
.foreground
;
1582 if (mask
& GCBackground
)
1583 xgcv
->background
= gc
->xgcv
.background
;
1585 xgcv
->font
= gc
->xgcv
.font
;
1589 /* Mac replacement for XSetForeground. */
1592 XSetForeground (display
, gc
, color
)
1595 unsigned long color
;
1597 if (gc
->xgcv
.foreground
!= color
)
1599 gc
->xgcv
.foreground
= color
;
1600 gc
->fore_color
.red
= RED16_FROM_ULONG (color
);
1601 gc
->fore_color
.green
= GREEN16_FROM_ULONG (color
);
1602 gc
->fore_color
.blue
= BLUE16_FROM_ULONG (color
);
1603 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1604 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1605 if (CGColorGetTypeID
!= NULL
)
1608 CGColorRelease (gc
->cg_fore_color
);
1611 gc
->cg_fore_color
= mac_cg_color_black
;
1612 CGColorRetain (gc
->cg_fore_color
);
1618 rgba
[0] = gc
->fore_color
.red
/ 65535.0f
;
1619 rgba
[1] = gc
->fore_color
.green
/ 65535.0f
;
1620 rgba
[2] = gc
->fore_color
.blue
/ 65535.0f
;
1622 gc
->cg_fore_color
= CGColorCreate (mac_cg_color_space_rgb
, rgba
);
1630 /* Mac replacement for XSetBackground. */
1633 XSetBackground (display
, gc
, color
)
1636 unsigned long color
;
1638 if (gc
->xgcv
.background
!= color
)
1640 gc
->xgcv
.background
= color
;
1641 gc
->back_color
.red
= RED16_FROM_ULONG (color
);
1642 gc
->back_color
.green
= GREEN16_FROM_ULONG (color
);
1643 gc
->back_color
.blue
= BLUE16_FROM_ULONG (color
);
1644 #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
1645 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
1646 if (CGColorGetTypeID
!= NULL
)
1649 CGColorRelease (gc
->cg_back_color
);
1652 gc
->cg_back_color
= mac_cg_color_black
;
1653 CGColorRetain (gc
->cg_back_color
);
1659 rgba
[0] = gc
->back_color
.red
/ 65535.0f
;
1660 rgba
[1] = gc
->back_color
.green
/ 65535.0f
;
1661 rgba
[2] = gc
->back_color
.blue
/ 65535.0f
;
1663 gc
->cg_back_color
= CGColorCreate (mac_cg_color_space_rgb
, rgba
);
1671 /* Mac replacement for XSetFont. */
1674 XSetFont (display
, gc
, font
)
1679 gc
->xgcv
.font
= font
;
1683 /* Mac replacement for XSetClipRectangles. */
1686 mac_set_clip_rectangles (display
, gc
, rectangles
, n
)
1694 xassert (n
>= 0 && n
<= MAX_CLIP_RECTS
);
1696 gc
->n_clip_rects
= n
;
1699 if (gc
->clip_region
== NULL
)
1700 gc
->clip_region
= NewRgn ();
1701 RectRgn (gc
->clip_region
, rectangles
);
1704 RgnHandle region
= NewRgn ();
1706 for (i
= 1; i
< n
; i
++)
1708 RectRgn (region
, rectangles
+ i
);
1709 UnionRgn (gc
->clip_region
, region
, gc
->clip_region
);
1711 DisposeRgn (region
);
1714 #if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING)
1715 for (i
= 0; i
< n
; i
++)
1717 Rect
*rect
= rectangles
+ i
;
1719 gc
->clip_rects
[i
] = CGRectMake (rect
->left
, rect
->top
,
1720 rect
->right
- rect
->left
,
1721 rect
->bottom
- rect
->top
);
1727 /* Mac replacement for XSetClipMask. */
1730 mac_reset_clip_rectangles (display
, gc
)
1734 gc
->n_clip_rects
= 0;
1737 /* Remove calls to XFlush by defining XFlush to an empty replacement.
1738 Calls to XFlush should be unnecessary because the X output buffer
1739 is flushed automatically as needed by calls to XPending,
1740 XNextEvent, or XWindowEvent according to the XFlush man page.
1741 XTread_socket calls XPending. Removing XFlush improves
1744 #define XFlush(DISPLAY) (void) 0
1747 /***********************************************************************
1748 Starting and ending an update
1749 ***********************************************************************/
1751 /* Start an update of frame F. This function is installed as a hook
1752 for update_begin, i.e. it is called when update_begin is called.
1753 This function is called prior to calls to x_update_window_begin for
1754 each window being updated. */
1761 mac_update_begin (f
);
1766 /* Start update of window W. Set the global variable updated_window
1767 to the window being updated and set output_cursor to the cursor
1771 x_update_window_begin (w
)
1774 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1775 struct mac_display_info
*display_info
= FRAME_MAC_DISPLAY_INFO (f
);
1778 set_output_cursor (&w
->cursor
);
1782 if (f
== display_info
->mouse_face_mouse_frame
)
1784 /* Don't do highlighting for mouse motion during the update. */
1785 display_info
->mouse_face_defer
= 1;
1787 /* If F needs to be redrawn, simply forget about any prior mouse
1789 if (FRAME_GARBAGED_P (f
))
1790 display_info
->mouse_face_window
= Qnil
;
1792 #if 0 /* Rows in a current matrix containing glyphs in mouse-face have
1793 their mouse_face_p flag set, which means that they are always
1794 unequal to rows in a desired matrix which never have that
1795 flag set. So, rows containing mouse-face glyphs are never
1796 scrolled, and we don't have to switch the mouse highlight off
1797 here to prevent it from being scrolled. */
1799 /* Can we tell that this update does not affect the window
1800 where the mouse highlight is? If so, no need to turn off.
1801 Likewise, don't do anything if the frame is garbaged;
1802 in that case, the frame's current matrix that we would use
1803 is all wrong, and we will redisplay that line anyway. */
1804 if (!NILP (display_info
->mouse_face_window
)
1805 && w
== XWINDOW (display_info
->mouse_face_window
))
1809 for (i
= 0; i
< w
->desired_matrix
->nrows
; ++i
)
1810 if (MATRIX_ROW_ENABLED_P (w
->desired_matrix
, i
))
1813 if (i
< w
->desired_matrix
->nrows
)
1814 clear_mouse_face (display_info
);
1823 /* Draw a vertical window border from (x,y0) to (x,y1) */
1826 mac_draw_vertical_window_border (w
, x
, y0
, y1
)
1830 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1833 face
= FACE_FROM_ID (f
, VERTICAL_BORDER_FACE_ID
);
1835 XSetForeground (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
1838 mac_draw_line (f
, f
->output_data
.mac
->normal_gc
, x
, y0
, x
, y1
);
1841 /* End update of window W (which is equal to updated_window).
1843 Draw vertical borders between horizontally adjacent windows, and
1844 display W's cursor if CURSOR_ON_P is non-zero.
1846 MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
1847 glyphs in mouse-face were overwritten. In that case we have to
1848 make sure that the mouse-highlight is properly redrawn.
1850 W may be a menu bar pseudo-window in case we don't have X toolkit
1851 support. Such windows don't have a cursor, so don't display it
1855 x_update_window_end (w
, cursor_on_p
, mouse_face_overwritten_p
)
1857 int cursor_on_p
, mouse_face_overwritten_p
;
1859 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (XFRAME (w
->frame
));
1861 if (!w
->pseudo_window_p
)
1866 display_and_set_cursor (w
, 1, output_cursor
.hpos
,
1868 output_cursor
.x
, output_cursor
.y
);
1870 if (draw_window_fringes (w
, 1))
1871 x_draw_vertical_border (w
);
1876 /* If a row with mouse-face was overwritten, arrange for
1877 XTframe_up_to_date to redisplay the mouse highlight. */
1878 if (mouse_face_overwritten_p
)
1880 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
1881 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
1882 dpyinfo
->mouse_face_window
= Qnil
;
1885 updated_window
= NULL
;
1889 /* End update of frame F. This function is installed as a hook in
1896 /* Mouse highlight may be displayed again. */
1897 FRAME_MAC_DISPLAY_INFO (f
)->mouse_face_defer
= 0;
1901 XFlush (FRAME_MAC_DISPLAY (f
));
1906 /* This function is called from various places in xdisp.c whenever a
1907 complete update has been performed. The global variable
1908 updated_window is not available here. */
1911 XTframe_up_to_date (f
)
1914 if (FRAME_MAC_P (f
))
1916 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
1918 if (dpyinfo
->mouse_face_deferred_gc
1919 || f
== dpyinfo
->mouse_face_mouse_frame
)
1922 if (dpyinfo
->mouse_face_mouse_frame
)
1923 note_mouse_highlight (dpyinfo
->mouse_face_mouse_frame
,
1924 dpyinfo
->mouse_face_mouse_x
,
1925 dpyinfo
->mouse_face_mouse_y
);
1926 dpyinfo
->mouse_face_deferred_gc
= 0;
1930 mac_frame_up_to_date (f
);
1935 /* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
1936 arrow bitmaps, or clear the fringes if no bitmaps are required
1937 before DESIRED_ROW is made current. The window being updated is
1938 found in updated_window. This function is called from
1939 update_window_line only if it is known that there are differences
1940 between bitmaps to be drawn between current row and DESIRED_ROW. */
1943 x_after_update_window_line (desired_row
)
1944 struct glyph_row
*desired_row
;
1946 struct window
*w
= updated_window
;
1952 if (!desired_row
->mode_line_p
&& !w
->pseudo_window_p
)
1953 desired_row
->redraw_fringe_bitmaps_p
= 1;
1955 /* When a window has disappeared, make sure that no rest of
1956 full-width rows stays visible in the internal border. Could
1957 check here if updated_window is the leftmost/rightmost window,
1958 but I guess it's not worth doing since vertically split windows
1959 are almost never used, internal border is rarely set, and the
1960 overhead is very small. */
1961 if (windows_or_buffers_changed
1962 && desired_row
->full_width_p
1963 && (f
= XFRAME (w
->frame
),
1964 width
= FRAME_INTERNAL_BORDER_WIDTH (f
),
1966 && (height
= desired_row
->visible_height
,
1969 int y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (0, desired_row
->y
));
1971 /* Internal border is drawn below the tool bar. */
1972 if (WINDOWP (f
->tool_bar_window
)
1973 && w
== XWINDOW (f
->tool_bar_window
))
1977 mac_clear_area (f
, 0, y
, width
, height
);
1978 mac_clear_area (f
, FRAME_PIXEL_WIDTH (f
) - width
, y
, width
, height
);
1984 /* Draw the bitmap WHICH in one of the left or right fringes of
1985 window W. ROW is the glyph row for which to display the bitmap; it
1986 determines the vertical position at which the bitmap has to be
1990 x_draw_fringe_bitmap (w
, row
, p
)
1992 struct glyph_row
*row
;
1993 struct draw_fringe_bitmap_params
*p
;
1995 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
1996 Display
*display
= FRAME_MAC_DISPLAY (f
);
1997 struct face
*face
= p
->face
;
1999 int overlay_p
= p
->overlay_p
;
2004 int bx
= p
->bx
, by
= p
->by
, nx
= p
->nx
, ny
= p
->ny
;
2006 #if 0 /* MAC_TODO: stipple */
2007 /* In case the same realized face is used for fringes and
2008 for something displayed in the text (e.g. face `region' on
2009 mono-displays, the fill style may have been changed to
2010 FillSolid in x_draw_glyph_string_background. */
2012 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
2014 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
2017 /* If the fringe is adjacent to the left (right) scroll bar of a
2018 leftmost (rightmost, respectively) window, then extend its
2019 background to the gap between the fringe and the bar. */
2020 if ((WINDOW_LEFTMOST_P (w
)
2021 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
2022 || (WINDOW_RIGHTMOST_P (w
)
2023 && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
)))
2025 int sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
2029 int left
= WINDOW_SCROLL_BAR_AREA_X (w
);
2030 int width
= (WINDOW_CONFIG_SCROLL_BAR_COLS (w
)
2031 * FRAME_COLUMN_WIDTH (f
));
2034 && (left
+ width
== p
->x
2035 || p
->x
+ p
->wd
== left
))
2037 /* Bitmap fills the fringe and we need background
2039 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
2043 by
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
,
2045 ny
= row
->visible_height
;
2050 if (left
+ width
== bx
)
2052 bx
= left
+ sb_width
;
2053 nx
+= width
- sb_width
;
2055 else if (bx
+ nx
== left
)
2056 nx
+= width
- sb_width
;
2063 mac_erase_rectangle (f
, face
->gc
, bx
, by
, nx
, ny
);
2064 /* The fringe background has already been filled. */
2068 #if 0 /* MAC_TODO: stipple */
2070 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
2073 #endif /* MAC_OSX */
2075 /* Must clip because of partially visible lines. */
2076 rowY
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
2079 /* Adjust position of "bottom aligned" bitmap on partially
2080 visible last row. */
2082 int oldVH
= row
->visible_height
;
2083 row
->visible_height
= p
->h
;
2084 row
->y
-= rowY
- p
->y
;
2085 x_clip_to_row (w
, row
, -1, face
->gc
);
2087 row
->visible_height
= oldVH
;
2090 x_clip_to_row (w
, row
, -1, face
->gc
);
2093 if (p
->bx
>= 0 && !p
->overlay_p
)
2095 #if 0 /* MAC_TODO: stipple */
2096 /* In case the same realized face is used for fringes and
2097 for something displayed in the text (e.g. face `region' on
2098 mono-displays, the fill style may have been changed to
2099 FillSolid in x_draw_glyph_string_background. */
2101 XSetFillStyle (FRAME_X_DISPLAY (f
), face
->gc
, FillOpaqueStippled
);
2103 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->background
);
2106 mac_erase_rectangle (f
, face
->gc
, p
->bx
, p
->by
, p
->nx
, p
->ny
);
2108 #if 0 /* MAC_TODO: stipple */
2110 XSetForeground (FRAME_X_DISPLAY (f
), face
->gc
, face
->foreground
);
2113 #endif /* !MAC_OSX */
2117 && p
->which
< max_fringe_bmp
2123 XGetGCValues (display
, face
->gc
, GCForeground
, &gcv
);
2124 XSetForeground (display
, face
->gc
,
2126 ? (p
->overlay_p
? face
->background
2127 : f
->output_data
.mac
->cursor_pixel
)
2128 : face
->foreground
));
2130 mac_draw_cg_image (fringe_bmp
[p
->which
], f
, face
->gc
, 0, p
->dh
,
2131 p
->wd
, p
->h
, p
->x
, p
->y
, overlay_p
);
2133 mac_draw_bitmap (f
, face
->gc
, p
->x
, p
->y
,
2134 p
->wd
, p
->h
, p
->bits
+ p
->dh
, overlay_p
);
2136 XSetForeground (display
, face
->gc
, gcv
.foreground
);
2139 mac_reset_clip_rectangles (display
, face
->gc
);
2144 mac_define_fringe_bitmap (which
, bits
, h
, wd
)
2146 unsigned short *bits
;
2150 CGDataProviderRef provider
;
2152 if (which
>= max_fringe_bmp
)
2155 max_fringe_bmp
= which
+ 20;
2156 fringe_bmp
= (CGImageRef
*) xrealloc (fringe_bmp
, max_fringe_bmp
* sizeof (CGImageRef
));
2157 while (i
< max_fringe_bmp
)
2158 fringe_bmp
[i
++] = 0;
2161 for (i
= 0; i
< h
; i
++)
2166 provider
= CGDataProviderCreateWithData (NULL
, bits
,
2167 sizeof (unsigned short) * h
, NULL
);
2170 fringe_bmp
[which
] = CGImageMaskCreate (wd
, h
, 1, 1,
2171 sizeof (unsigned short),
2173 CGDataProviderRelease (provider
);
2180 mac_destroy_fringe_bitmap (which
)
2183 if (which
>= max_fringe_bmp
)
2186 if (fringe_bmp
[which
])
2189 CGImageRelease (fringe_bmp
[which
]);
2192 fringe_bmp
[which
] = 0;
2197 /* This is called when starting Emacs and when restarting after
2198 suspend. When starting Emacs, no window is mapped. And nothing
2199 must be done to Emacs's own window if it is suspended (though that
2203 XTset_terminal_modes ()
2207 /* This is called when exiting or suspending Emacs. Exiting will make
2208 the windows go away, and suspending requires no action. */
2211 XTreset_terminal_modes ()
2217 /***********************************************************************
2219 ***********************************************************************/
2221 /* Function prototypes of this page. */
2223 static XCharStruct
*x_per_char_metric
P_ ((XFontStruct
*, XChar2b
*));
2224 static int mac_encode_char
P_ ((int, XChar2b
*, struct font_info
*, int *));
2228 pcm_init (pcm
, count
)
2232 bzero (pcm
, sizeof (XCharStruct
) * count
);
2233 while (--count
>= 0)
2235 pcm
->descent
= PCM_INVALID
;
2240 static enum pcm_status
2241 pcm_get_status (pcm
)
2242 const XCharStruct
*pcm
;
2244 int height
= pcm
->ascent
+ pcm
->descent
;
2246 /* Negative height means some special status. */
2247 return height
>= 0 ? PCM_VALID
: height
;
2250 /* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
2251 is not contained in the font. */
2253 static INLINE XCharStruct
*
2254 x_per_char_metric (font
, char2b
)
2258 /* The result metric information. */
2259 XCharStruct
*pcm
= NULL
;
2261 xassert (font
&& char2b
);
2264 if (font
->mac_style
)
2266 XCharStruct
**row
= font
->bounds
.rows
+ char2b
->byte1
;
2270 *row
= xmalloc (sizeof (XCharStruct
) * 0x100);
2271 pcm_init (*row
, 0x100);
2273 pcm
= *row
+ char2b
->byte2
;
2274 if (pcm_get_status (pcm
) != PCM_VALID
)
2277 mac_query_char_extents (font
->mac_style
,
2278 (char2b
->byte1
<< 8) + char2b
->byte2
,
2279 NULL
, NULL
, pcm
, NULL
);
2286 if (font
->bounds
.per_char
!= NULL
)
2288 if (font
->min_byte1
== 0 && font
->max_byte1
== 0)
2290 /* min_char_or_byte2 specifies the linear character index
2291 corresponding to the first element of the per_char array,
2292 max_char_or_byte2 is the index of the last character. A
2293 character with non-zero CHAR2B->byte1 is not in the font.
2294 A character with byte2 less than min_char_or_byte2 or
2295 greater max_char_or_byte2 is not in the font. */
2296 if (char2b
->byte1
== 0
2297 && char2b
->byte2
>= font
->min_char_or_byte2
2298 && char2b
->byte2
<= font
->max_char_or_byte2
)
2299 pcm
= font
->bounds
.per_char
2300 + (char2b
->byte2
- font
->min_char_or_byte2
);
2304 /* If either min_byte1 or max_byte1 are nonzero, both
2305 min_char_or_byte2 and max_char_or_byte2 are less than
2306 256, and the 2-byte character index values corresponding
2307 to the per_char array element N (counting from 0) are:
2309 byte1 = N/D + min_byte1
2310 byte2 = N\D + min_char_or_byte2
2314 D = max_char_or_byte2 - min_char_or_byte2 + 1
2315 / = integer division
2316 \ = integer modulus */
2317 if (char2b
->byte1
>= font
->min_byte1
2318 && char2b
->byte1
<= font
->max_byte1
2319 && char2b
->byte2
>= font
->min_char_or_byte2
2320 && char2b
->byte2
<= font
->max_char_or_byte2
)
2322 pcm
= (font
->bounds
.per_char
2323 + ((font
->max_char_or_byte2
- font
->min_char_or_byte2
+ 1)
2324 * (char2b
->byte1
- font
->min_byte1
))
2325 + (char2b
->byte2
- font
->min_char_or_byte2
));
2331 /* If the per_char pointer is null, all glyphs between the first
2332 and last character indexes inclusive have the same
2333 information, as given by both min_bounds and max_bounds. */
2334 if (char2b
->byte2
>= font
->min_char_or_byte2
2335 && char2b
->byte2
<= font
->max_char_or_byte2
)
2336 pcm
= &font
->max_bounds
;
2342 return ((pcm
== NULL
2344 #if 0 /* Show hollow boxes for zero-width glyphs such as combining diacritics. */
2345 && (pcm
->rbearing
- pcm
->lbearing
) == 0
2354 static XCharStruct
*
2355 mac_per_char_metric (font
, char2b
, font_type
)
2360 return x_per_char_metric (font
, char2b
);
2364 Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
2365 the two-byte form of C. Encoding is returned in *CHAR2B. */
2368 mac_encode_char (c
, char2b
, font_info
, two_byte_p
)
2371 struct font_info
*font_info
;
2374 int charset
= CHAR_CHARSET (c
);
2375 XFontStruct
*font
= font_info
->font
;
2377 /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
2378 This may be either a program in a special encoder language or a
2380 if (font_info
->font_encoder
)
2382 /* It's a program. */
2383 struct ccl_program
*ccl
= font_info
->font_encoder
;
2385 check_ccl_update (ccl
);
2386 if (CHARSET_DIMENSION (charset
) == 1)
2388 ccl
->reg
[0] = charset
;
2389 ccl
->reg
[1] = char2b
->byte2
;
2394 ccl
->reg
[0] = charset
;
2395 ccl
->reg
[1] = char2b
->byte1
;
2396 ccl
->reg
[2] = char2b
->byte2
;
2399 ccl_driver (ccl
, NULL
, NULL
, 0, 0, NULL
);
2401 /* We assume that MSBs are appropriately set/reset by CCL
2403 if (font
->max_byte1
== 0) /* 1-byte font */
2404 char2b
->byte1
= 0, char2b
->byte2
= ccl
->reg
[1];
2406 char2b
->byte1
= ccl
->reg
[1], char2b
->byte2
= ccl
->reg
[2];
2408 else if (font_info
->encoding
[charset
])
2410 /* Fixed encoding scheme. See fontset.h for the meaning of the
2411 encoding numbers. */
2412 int enc
= font_info
->encoding
[charset
];
2414 if ((enc
== 1 || enc
== 2)
2415 && CHARSET_DIMENSION (charset
) == 2)
2416 char2b
->byte1
|= 0x80;
2418 if (enc
== 1 || enc
== 3)
2419 char2b
->byte2
|= 0x80;
2425 ENCODE_SJIS (char2b
->byte1
, char2b
->byte2
, sjis1
, sjis2
);
2426 char2b
->byte1
= sjis1
;
2427 char2b
->byte2
= sjis2
;
2432 *two_byte_p
= ((XFontStruct
*) (font_info
->font
))->max_byte1
> 0;
2434 return FONT_TYPE_UNKNOWN
;
2439 /***********************************************************************
2441 ***********************************************************************/
2445 static void x_set_glyph_string_clipping
P_ ((struct glyph_string
*));
2446 static void x_set_glyph_string_gc
P_ ((struct glyph_string
*));
2447 static void x_draw_glyph_string_background
P_ ((struct glyph_string
*,
2449 static void x_draw_glyph_string_foreground
P_ ((struct glyph_string
*));
2450 static void x_draw_composite_glyph_string_foreground
P_ ((struct glyph_string
*));
2451 static void x_draw_glyph_string_box
P_ ((struct glyph_string
*));
2452 static void x_draw_glyph_string
P_ ((struct glyph_string
*));
2453 static void mac_compute_glyph_string_overhangs
P_ ((struct glyph_string
*));
2454 static void x_set_cursor_gc
P_ ((struct glyph_string
*));
2455 static void x_set_mode_line_face_gc
P_ ((struct glyph_string
*));
2456 static void x_set_mouse_face_gc
P_ ((struct glyph_string
*));
2457 /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap,
2458 unsigned long *, double, int));*/
2459 static void x_setup_relief_color
P_ ((struct frame
*, struct relief
*,
2460 double, int, unsigned long));
2461 static void x_setup_relief_colors
P_ ((struct glyph_string
*));
2462 static void x_draw_image_glyph_string
P_ ((struct glyph_string
*));
2463 static void x_draw_image_relief
P_ ((struct glyph_string
*));
2464 static void x_draw_image_foreground
P_ ((struct glyph_string
*));
2465 static void x_clear_glyph_string_rect
P_ ((struct glyph_string
*, int,
2467 static void x_draw_relief_rect
P_ ((struct frame
*, int, int, int, int,
2468 int, int, int, int, int, int,
2470 static void x_draw_box_rect
P_ ((struct glyph_string
*, int, int, int, int,
2471 int, int, int, Rect
*));
2474 static void x_check_font
P_ ((struct frame
*, XFontStruct
*));
2478 /* Set S->gc to a suitable GC for drawing glyph string S in cursor
2483 struct glyph_string
*s
;
2485 if (s
->font
== FRAME_FONT (s
->f
)
2486 && s
->face
->background
== FRAME_BACKGROUND_PIXEL (s
->f
)
2487 && s
->face
->foreground
== FRAME_FOREGROUND_PIXEL (s
->f
)
2489 s
->gc
= s
->f
->output_data
.mac
->cursor_gc
;
2492 /* Cursor on non-default face: must merge. */
2496 xgcv
.background
= s
->f
->output_data
.mac
->cursor_pixel
;
2497 xgcv
.foreground
= s
->face
->background
;
2499 /* If the glyph would be invisible, try a different foreground. */
2500 if (xgcv
.foreground
== xgcv
.background
)
2501 xgcv
.foreground
= s
->face
->foreground
;
2502 if (xgcv
.foreground
== xgcv
.background
)
2503 xgcv
.foreground
= s
->f
->output_data
.mac
->cursor_foreground_pixel
;
2504 if (xgcv
.foreground
== xgcv
.background
)
2505 xgcv
.foreground
= s
->face
->foreground
;
2507 /* Make sure the cursor is distinct from text in this face. */
2508 if (xgcv
.background
== s
->face
->background
2509 && xgcv
.foreground
== s
->face
->foreground
)
2511 xgcv
.background
= s
->face
->foreground
;
2512 xgcv
.foreground
= s
->face
->background
;
2515 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2516 xgcv
.font
= s
->font
;
2517 mask
= GCForeground
| GCBackground
| GCFont
;
2519 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2520 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2523 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2524 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2526 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2531 /* Set up S->gc of glyph string S for drawing text in mouse face. */
2534 x_set_mouse_face_gc (s
)
2535 struct glyph_string
*s
;
2540 /* What face has to be used last for the mouse face? */
2541 face_id
= FRAME_X_DISPLAY_INFO (s
->f
)->mouse_face_face_id
;
2542 face
= FACE_FROM_ID (s
->f
, face_id
);
2544 face
= FACE_FROM_ID (s
->f
, MOUSE_FACE_ID
);
2546 if (s
->first_glyph
->type
== CHAR_GLYPH
)
2547 face_id
= FACE_FOR_CHAR (s
->f
, face
, s
->first_glyph
->u
.ch
);
2549 face_id
= FACE_FOR_CHAR (s
->f
, face
, 0);
2550 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
2551 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2553 /* If font in this face is same as S->font, use it. */
2554 if (s
->font
== s
->face
->font
)
2555 s
->gc
= s
->face
->gc
;
2558 /* Otherwise construct scratch_cursor_gc with values from FACE
2563 xgcv
.background
= s
->face
->background
;
2564 xgcv
.foreground
= s
->face
->foreground
;
2565 IF_DEBUG (x_check_font (s
->f
, s
->font
));
2566 xgcv
.font
= s
->font
;
2567 mask
= GCForeground
| GCBackground
| GCFont
;
2569 if (FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
)
2570 XChangeGC (s
->display
, FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
,
2573 FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
2574 = XCreateGC (s
->display
, s
->window
, mask
, &xgcv
);
2576 s
->gc
= FRAME_MAC_DISPLAY_INFO (s
->f
)->scratch_cursor_gc
;
2579 xassert (s
->gc
!= 0);
2583 /* Set S->gc of glyph string S to a GC suitable for drawing a mode line.
2584 Faces to use in the mode line have already been computed when the
2585 matrix was built, so there isn't much to do, here. */
2588 x_set_mode_line_face_gc (s
)
2589 struct glyph_string
*s
;
2591 s
->gc
= s
->face
->gc
;
2595 /* Set S->gc of glyph string S for drawing that glyph string. Set
2596 S->stippled_p to a non-zero value if the face of S has a stipple
2600 x_set_glyph_string_gc (s
)
2601 struct glyph_string
*s
;
2603 PREPARE_FACE_FOR_DISPLAY (s
->f
, s
->face
);
2605 if (s
->hl
== DRAW_NORMAL_TEXT
)
2607 s
->gc
= s
->face
->gc
;
2608 s
->stippled_p
= s
->face
->stipple
!= 0;
2610 else if (s
->hl
== DRAW_INVERSE_VIDEO
)
2612 x_set_mode_line_face_gc (s
);
2613 s
->stippled_p
= s
->face
->stipple
!= 0;
2615 else if (s
->hl
== DRAW_CURSOR
)
2617 x_set_cursor_gc (s
);
2620 else if (s
->hl
== DRAW_MOUSE_FACE
)
2622 x_set_mouse_face_gc (s
);
2623 s
->stippled_p
= s
->face
->stipple
!= 0;
2625 else if (s
->hl
== DRAW_IMAGE_RAISED
2626 || s
->hl
== DRAW_IMAGE_SUNKEN
)
2628 s
->gc
= s
->face
->gc
;
2629 s
->stippled_p
= s
->face
->stipple
!= 0;
2633 s
->gc
= s
->face
->gc
;
2634 s
->stippled_p
= s
->face
->stipple
!= 0;
2637 /* GC must have been set. */
2638 xassert (s
->gc
!= 0);
2642 /* Set clipping for output of glyph string S. S may be part of a mode
2643 line or menu if we don't have X toolkit support. */
2646 x_set_glyph_string_clipping (s
)
2647 struct glyph_string
*s
;
2649 Rect rects
[MAX_CLIP_RECTS
];
2652 n
= get_glyph_string_clip_rects (s
, rects
, MAX_CLIP_RECTS
);
2653 mac_set_clip_rectangles (s
->display
, s
->gc
, rects
, n
);
2658 Compute left and right overhang of glyph string S. If S is a glyph
2659 string for a composition, assume overhangs don't exist. */
2662 mac_compute_glyph_string_overhangs (s
)
2663 struct glyph_string
*s
;
2665 if (!(s
->cmp
== NULL
2666 && s
->first_glyph
->type
== CHAR_GLYPH
))
2671 || s
->font
->mac_style
2677 mac_text_extents_16 (s
->font
, s
->char2b
, s
->nchars
, &cs
);
2678 s
->right_overhang
= cs
.rbearing
> cs
.width
? cs
.rbearing
- cs
.width
: 0;
2679 s
->left_overhang
= cs
.lbearing
< 0 ? -cs
.lbearing
: 0;
2684 MacFontStruct
*font
= s
->font
;
2686 mac_begin_clip (s
->f
, NULL
);
2688 TextFont (font
->mac_fontnum
);
2689 TextSize (font
->mac_fontsize
);
2690 TextFace (font
->mac_fontface
);
2692 QDTextBounds (s
->nchars
* 2, (char *)s
->char2b
, &r
);
2694 mac_end_clip (s
->f
, NULL
);
2696 s
->right_overhang
= r
.right
> s
->width
? r
.right
- s
->width
: 0;
2697 s
->left_overhang
= r
.left
< 0 ? -r
.left
: 0;
2702 /* Fill rectangle X, Y, W, H with background color of glyph string S. */
2705 x_clear_glyph_string_rect (s
, x
, y
, w
, h
)
2706 struct glyph_string
*s
;
2709 mac_erase_rectangle (s
->f
, s
->gc
, x
, y
, w
, h
);
2713 /* Draw the background of glyph_string S. If S->background_filled_p
2714 is non-zero don't draw it. FORCE_P non-zero means draw the
2715 background even if it wouldn't be drawn normally. This is used
2716 when a string preceding S draws into the background of S, or S
2717 contains the first component of a composition. */
2720 x_draw_glyph_string_background (s
, force_p
)
2721 struct glyph_string
*s
;
2724 /* Nothing to do if background has already been drawn or if it
2725 shouldn't be drawn in the first place. */
2726 if (!s
->background_filled_p
)
2728 int box_line_width
= max (s
->face
->box_line_width
, 0);
2730 #if 0 /* MAC_TODO: stipple */
2733 /* Fill background with a stipple pattern. */
2734 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
2735 XFillRectangle (s
->display
, s
->window
, s
->gc
, s
->x
,
2736 s
->y
+ box_line_width
,
2737 s
->background_width
,
2738 s
->height
- 2 * box_line_width
);
2739 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
2740 s
->background_filled_p
= 1;
2744 if (FONT_HEIGHT (s
->font
) < s
->height
- 2 * box_line_width
2745 || s
->font_not_found_p
2746 || s
->extends_to_end_of_line_p
2749 x_clear_glyph_string_rect (s
, s
->x
, s
->y
+ box_line_width
,
2750 s
->background_width
,
2751 s
->height
- 2 * box_line_width
);
2752 s
->background_filled_p
= 1;
2758 /* Draw the foreground of glyph string S. */
2761 x_draw_glyph_string_foreground (s
)
2762 struct glyph_string
*s
;
2766 /* If first glyph of S has a left box line, start drawing the text
2767 of S to the right of that box line. */
2768 if (s
->face
->box
!= FACE_NO_BOX
2769 && s
->first_glyph
->left_box_line_p
)
2770 x
= s
->x
+ abs (s
->face
->box_line_width
);
2774 /* Draw characters of S as rectangles if S's font could not be
2776 if (s
->font_not_found_p
)
2778 for (i
= 0; i
< s
->nchars
; ++i
)
2780 struct glyph
*g
= s
->first_glyph
+ i
;
2781 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2782 g
->pixel_width
- 1, s
->height
- 1);
2783 x
+= g
->pixel_width
;
2788 char *char1b
= (char *) s
->char2b
;
2789 int boff
= s
->font_info
->baseline_offset
;
2791 if (s
->font_info
->vertical_centering
)
2792 boff
= VCENTER_BASELINE_OFFSET (s
->font
, s
->f
) - boff
;
2794 /* If we can use 8-bit functions, condense S->char2b. */
2797 && GC_FONT (s
->gc
)->mac_style
== NULL
2800 for (i
= 0; i
< s
->nchars
; ++i
)
2801 char1b
[i
] = s
->char2b
[i
].byte2
;
2803 /* Draw text with XDrawString if background has already been
2804 filled. Otherwise, use XDrawImageString. (Note that
2805 XDrawImageString is usually faster than XDrawString.) Always
2806 use XDrawImageString when drawing the cursor so that there is
2807 no chance that characters under a box cursor are invisible. */
2809 || (s
->background_filled_p
&& s
->hl
!= DRAW_CURSOR
))
2810 bg_width
= 0; /* Corresponds to XDrawString. */
2812 bg_width
= s
->background_width
; /* Corresponds to XDrawImageString. */
2816 || GC_FONT (s
->gc
)->mac_style
2819 #if USE_CG_TEXT_DRAWING
2821 && mac_draw_image_string_cg (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2822 s
->char2b
, s
->nchars
, bg_width
,
2823 s
->face
->overstrike
))
2827 mac_draw_image_string_16 (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2828 s
->char2b
, s
->nchars
, bg_width
,
2829 s
->face
->overstrike
);
2831 mac_draw_image_string (s
->f
, s
->gc
, x
, s
->ybase
- boff
,
2832 char1b
, s
->nchars
, bg_width
,
2833 s
->face
->overstrike
);
2837 /* Draw the foreground of composite glyph string S. */
2840 x_draw_composite_glyph_string_foreground (s
)
2841 struct glyph_string
*s
;
2845 /* If first glyph of S has a left box line, start drawing the text
2846 of S to the right of that box line. */
2847 if (s
->face
->box
!= FACE_NO_BOX
2848 && s
->first_glyph
->left_box_line_p
)
2849 x
= s
->x
+ abs (s
->face
->box_line_width
);
2853 /* S is a glyph string for a composition. S->gidx is the index of
2854 the first character drawn for glyphs of this composition.
2855 S->gidx == 0 means we are drawing the very first character of
2856 this composition. */
2858 /* Draw a rectangle for the composition if the font for the very
2859 first character of the composition could not be loaded. */
2860 if (s
->font_not_found_p
)
2863 mac_draw_rectangle (s
->f
, s
->gc
, x
, s
->y
,
2864 s
->width
- 1, s
->height
- 1);
2868 for (i
= 0; i
< s
->nchars
; i
++, ++s
->gidx
)
2869 if (mac_per_char_metric (GC_FONT (s
->gc
), s
->char2b
+ i
, 0) == NULL
)
2870 /* This is a nonexistent or zero-width glyph such as a
2871 combining diacritic. Draw a rectangle. */
2872 mac_draw_rectangle (s
->f
, s
->gc
,
2873 x
+ s
->cmp
->offsets
[s
->gidx
* 2], s
->y
,
2874 FONT_WIDTH (GC_FONT (s
->gc
)) - 1, s
->height
- 1);
2876 mac_draw_image_string_16 (s
->f
, s
->gc
,
2877 x
+ s
->cmp
->offsets
[s
->gidx
* 2],
2878 s
->ybase
- s
->cmp
->offsets
[s
->gidx
* 2 + 1],
2879 s
->char2b
+ i
, 1, 0, s
->face
->overstrike
);
2884 #ifdef USE_X_TOOLKIT
2886 static struct frame
*x_frame_of_widget
P_ ((Widget
));
2889 /* Return the frame on which widget WIDGET is used.. Abort if frame
2890 cannot be determined. */
2892 static struct frame
*
2893 x_frame_of_widget (widget
)
2896 struct x_display_info
*dpyinfo
;
2900 dpyinfo
= x_display_info_for_display (XtDisplay (widget
));
2902 /* Find the top-level shell of the widget. Note that this function
2903 can be called when the widget is not yet realized, so XtWindow
2904 (widget) == 0. That's the reason we can't simply use
2905 x_any_window_to_frame. */
2906 while (!XtIsTopLevelShell (widget
))
2907 widget
= XtParent (widget
);
2909 /* Look for a frame with that top-level widget. Allocate the color
2910 on that frame to get the right gamma correction value. */
2911 for (tail
= Vframe_list
; GC_CONSP (tail
); tail
= XCDR (tail
))
2912 if (GC_FRAMEP (XCAR (tail
))
2913 && (f
= XFRAME (XCAR (tail
)),
2914 (f
->output_data
.nothing
!= 1
2915 && FRAME_X_DISPLAY_INFO (f
) == dpyinfo
))
2916 && f
->output_data
.x
->widget
== widget
)
2923 /* Allocate the color COLOR->pixel on the screen and display of
2924 widget WIDGET in colormap CMAP. If an exact match cannot be
2925 allocated, try the nearest color available. Value is non-zero
2926 if successful. This is called from lwlib. */
2929 x_alloc_nearest_color_for_widget (widget
, cmap
, color
)
2934 struct frame
*f
= x_frame_of_widget (widget
);
2935 return x_alloc_nearest_color (f
, cmap
, color
);
2939 #endif /* USE_X_TOOLKIT */
2941 #if 0 /* MAC_TODO */
2943 /* Allocate the color COLOR->pixel on SCREEN of DISPLAY, colormap
2944 CMAP. If an exact match can't be allocated, try the nearest color
2945 available. Value is non-zero if successful. Set *COLOR to the
2949 x_alloc_nearest_color (f
, cmap
, color
)
2954 Display
*display
= FRAME_X_DISPLAY (f
);
2955 Screen
*screen
= FRAME_X_SCREEN (f
);
2958 gamma_correct (f
, color
);
2959 rc
= XAllocColor (display
, cmap
, color
);
2962 /* If we got to this point, the colormap is full, so we're going
2963 to try to get the next closest color. The algorithm used is
2964 a least-squares matching, which is what X uses for closest
2965 color matching with StaticColor visuals. */
2967 unsigned long nearest_delta
= ~0;
2968 int ncells
= XDisplayCells (display
, XScreenNumberOfScreen (screen
));
2969 XColor
*cells
= (XColor
*) alloca (ncells
* sizeof *cells
);
2971 for (i
= 0; i
< ncells
; ++i
)
2973 XQueryColors (display
, cmap
, cells
, ncells
);
2975 for (nearest
= i
= 0; i
< ncells
; ++i
)
2977 long dred
= (color
->red
>> 8) - (cells
[i
].red
>> 8);
2978 long dgreen
= (color
->green
>> 8) - (cells
[i
].green
>> 8);
2979 long dblue
= (color
->blue
>> 8) - (cells
[i
].blue
>> 8);
2980 unsigned long delta
= dred
* dred
+ dgreen
* dgreen
+ dblue
* dblue
;
2982 if (delta
< nearest_delta
)
2985 nearest_delta
= delta
;
2989 color
->red
= cells
[nearest
].red
;
2990 color
->green
= cells
[nearest
].green
;
2991 color
->blue
= cells
[nearest
].blue
;
2992 rc
= XAllocColor (display
, cmap
, color
);
2995 #ifdef DEBUG_X_COLORS
2997 register_color (color
->pixel
);
2998 #endif /* DEBUG_X_COLORS */
3004 /* Allocate color PIXEL on frame F. PIXEL must already be allocated.
3005 It's necessary to do this instead of just using PIXEL directly to
3006 get color reference counts right. */
3009 x_copy_color (f
, pixel
)
3011 unsigned long pixel
;
3015 color
.pixel
= pixel
;
3017 XQueryColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3018 XAllocColor (FRAME_X_DISPLAY (f
), FRAME_X_COLORMAP (f
), &color
);
3020 #ifdef DEBUG_X_COLORS
3021 register_color (pixel
);
3027 /* Allocate color PIXEL on display DPY. PIXEL must already be allocated.
3028 It's necessary to do this instead of just using PIXEL directly to
3029 get color reference counts right. */
3032 x_copy_dpy_color (dpy
, cmap
, pixel
)
3035 unsigned long pixel
;
3039 color
.pixel
= pixel
;
3041 XQueryColor (dpy
, cmap
, &color
);
3042 XAllocColor (dpy
, cmap
, &color
);
3044 #ifdef DEBUG_X_COLORS
3045 register_color (pixel
);
3050 #endif /* MAC_TODO */
3053 /* Brightness beyond which a color won't have its highlight brightness
3056 Nominally, highlight colors for `3d' faces are calculated by
3057 brightening an object's color by a constant scale factor, but this
3058 doesn't yield good results for dark colors, so for colors who's
3059 brightness is less than this value (on a scale of 0-255) have to
3060 use an additional additive factor.
3062 The value here is set so that the default menu-bar/mode-line color
3063 (grey75) will not have its highlights changed at all. */
3064 #define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
3067 /* Allocate a color which is lighter or darker than *COLOR by FACTOR
3068 or DELTA. Try a color with RGB values multiplied by FACTOR first.
3069 If this produces the same color as COLOR, try a color where all RGB
3070 values have DELTA added. Return the allocated color in *COLOR.
3071 DISPLAY is the X display, CMAP is the colormap to operate on.
3072 Value is non-zero if successful. */
3075 mac_alloc_lighter_color (f
, color
, factor
, delta
)
3077 unsigned long *color
;
3084 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
3087 /* Change RGB values by specified FACTOR. Avoid overflow! */
3088 xassert (factor
>= 0);
3089 new = RGB_TO_ULONG (min (0xff, (int) (factor
* RED_FROM_ULONG (*color
))),
3090 min (0xff, (int) (factor
* GREEN_FROM_ULONG (*color
))),
3091 min (0xff, (int) (factor
* BLUE_FROM_ULONG (*color
))));
3093 /* Calculate brightness of COLOR. */
3094 bright
= (2 * RED_FROM_ULONG (*color
) + 3 * GREEN_FROM_ULONG (*color
)
3095 + BLUE_FROM_ULONG (*color
)) / 6;
3097 /* We only boost colors that are darker than
3098 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
3099 if (bright
< HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
)
3100 /* Make an additive adjustment to NEW, because it's dark enough so
3101 that scaling by FACTOR alone isn't enough. */
3103 /* How far below the limit this color is (0 - 1, 1 being darker). */
3104 double dimness
= 1 - (double)bright
/ HIGHLIGHT_COLOR_DARK_BOOST_LIMIT
;
3105 /* The additive adjustment. */
3106 int min_delta
= delta
* dimness
* factor
/ 2;
3109 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color
)) - min_delta
)),
3110 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color
)) - min_delta
)),
3111 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color
)) - min_delta
)));
3113 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta
+ RED_FROM_ULONG (*color
)))),
3114 max (0, min (0xff, (int) (min_delta
+ GREEN_FROM_ULONG (*color
)))),
3115 max (0, min (0xff, (int) (min_delta
+ BLUE_FROM_ULONG (*color
)))));
3119 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta
+ RED_FROM_ULONG (*color
)))),
3120 max (0, min (0xff, (int) (delta
+ GREEN_FROM_ULONG (*color
)))),
3121 max (0, min (0xff, (int) (delta
+ BLUE_FROM_ULONG (*color
)))));
3123 /* MAC_TODO: Map to palette and retry with delta if same? */
3124 /* MAC_TODO: Free colors (if using palette)? */
3135 /* Set up the foreground color for drawing relief lines of glyph
3136 string S. RELIEF is a pointer to a struct relief containing the GC
3137 with which lines will be drawn. Use a color that is FACTOR or
3138 DELTA lighter or darker than the relief's background which is found
3139 in S->f->output_data.x->relief_background. If such a color cannot
3140 be allocated, use DEFAULT_PIXEL, instead. */
3143 x_setup_relief_color (f
, relief
, factor
, delta
, default_pixel
)
3145 struct relief
*relief
;
3148 unsigned long default_pixel
;
3151 struct mac_output
*di
= f
->output_data
.mac
;
3152 unsigned long mask
= GCForeground
;
3153 unsigned long pixel
;
3154 unsigned long background
= di
->relief_background
;
3155 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
3157 /* MAC_TODO: Free colors (if using palette)? */
3159 /* Allocate new color. */
3160 xgcv
.foreground
= default_pixel
;
3162 if (dpyinfo
->n_planes
!= 1
3163 && mac_alloc_lighter_color (f
, &pixel
, factor
, delta
))
3165 relief
->allocated_p
= 1;
3166 xgcv
.foreground
= relief
->pixel
= pixel
;
3169 if (relief
->gc
== 0)
3171 #if 0 /* MAC_TODO: stipple */
3172 xgcv
.stipple
= dpyinfo
->gray
;
3175 relief
->gc
= XCreateGC (NULL
, FRAME_MAC_WINDOW (f
), mask
, &xgcv
);
3178 XChangeGC (NULL
, relief
->gc
, mask
, &xgcv
);
3182 /* Set up colors for the relief lines around glyph string S. */
3185 x_setup_relief_colors (s
)
3186 struct glyph_string
*s
;
3188 struct mac_output
*di
= s
->f
->output_data
.mac
;
3189 unsigned long color
;
3191 if (s
->face
->use_box_color_for_shadows_p
)
3192 color
= s
->face
->box_color
;
3193 else if (s
->first_glyph
->type
== IMAGE_GLYPH
3195 && !IMAGE_BACKGROUND_TRANSPARENT (s
->img
, s
->f
, 0))
3196 color
= IMAGE_BACKGROUND (s
->img
, s
->f
, 0);
3201 /* Get the background color of the face. */
3202 XGetGCValues (s
->display
, s
->gc
, GCBackground
, &xgcv
);
3203 color
= xgcv
.background
;
3206 if (di
->white_relief
.gc
== 0
3207 || color
!= di
->relief_background
)
3209 di
->relief_background
= color
;
3210 x_setup_relief_color (s
->f
, &di
->white_relief
, 1.2, 0x8000,
3211 WHITE_PIX_DEFAULT (s
->f
));
3212 x_setup_relief_color (s
->f
, &di
->black_relief
, 0.6, 0x4000,
3213 BLACK_PIX_DEFAULT (s
->f
));
3218 /* Draw a relief on frame F inside the rectangle given by LEFT_X,
3219 TOP_Y, RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the relief
3220 to draw, it must be >= 0. RAISED_P non-zero means draw a raised
3221 relief. LEFT_P non-zero means draw a relief on the left side of
3222 the rectangle. RIGHT_P non-zero means draw a relief on the right
3223 side of the rectangle. CLIP_RECT is the clipping rectangle to use
3227 x_draw_relief_rect (f
, left_x
, top_y
, right_x
, bottom_y
, width
,
3228 raised_p
, top_p
, bot_p
, left_p
, right_p
, clip_rect
)
3230 int left_x
, top_y
, right_x
, bottom_y
, width
;
3231 int top_p
, bot_p
, left_p
, right_p
, raised_p
;
3234 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
3239 gc
= f
->output_data
.mac
->white_relief
.gc
;
3241 gc
= f
->output_data
.mac
->black_relief
.gc
;
3242 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3246 for (i
= 0; i
< width
; ++i
)
3247 mac_draw_line (f
, gc
,
3248 left_x
+ i
* left_p
, top_y
+ i
,
3249 right_x
+ 1 - i
* right_p
, top_y
+ i
);
3253 for (i
= 0; i
< width
; ++i
)
3254 mac_draw_line (f
, gc
,
3255 left_x
+ i
, top_y
+ i
, left_x
+ i
, bottom_y
- i
+ 1);
3257 mac_reset_clip_rectangles (dpy
, gc
);
3259 gc
= f
->output_data
.mac
->black_relief
.gc
;
3261 gc
= f
->output_data
.mac
->white_relief
.gc
;
3262 mac_set_clip_rectangles (dpy
, gc
, clip_rect
, 1);
3266 for (i
= 0; i
< width
; ++i
)
3267 mac_draw_line (f
, gc
,
3268 left_x
+ i
* left_p
, bottom_y
- i
,
3269 right_x
+ 1 - i
* right_p
, bottom_y
- i
);
3273 for (i
= 0; i
< width
; ++i
)
3274 mac_draw_line (f
, gc
,
3275 right_x
- i
, top_y
+ i
+ 1, right_x
- i
, bottom_y
- i
);
3277 mac_reset_clip_rectangles (dpy
, gc
);
3281 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y,
3282 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to
3283 draw, it must be >= 0. LEFT_P non-zero means draw a line on the
3284 left side of the rectangle. RIGHT_P non-zero means draw a line
3285 on the right side of the rectangle. CLIP_RECT is the clipping
3286 rectangle to use when drawing. */
3289 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3290 left_p
, right_p
, clip_rect
)
3291 struct glyph_string
*s
;
3292 int left_x
, top_y
, right_x
, bottom_y
, width
, left_p
, right_p
;
3297 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3298 XSetForeground (s
->display
, s
->gc
, s
->face
->box_color
);
3299 mac_set_clip_rectangles (s
->display
, s
->gc
, clip_rect
, 1);
3302 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3303 right_x
- left_x
+ 1, width
);
3307 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, top_y
,
3308 width
, bottom_y
- top_y
+ 1);
3311 mac_fill_rectangle (s
->f
, s
->gc
, left_x
, bottom_y
- width
+ 1,
3312 right_x
- left_x
+ 1, width
);
3316 mac_fill_rectangle (s
->f
, s
->gc
, right_x
- width
+ 1,
3317 top_y
, width
, bottom_y
- top_y
+ 1);
3319 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3320 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3324 /* Draw a box around glyph string S. */
3327 x_draw_glyph_string_box (s
)
3328 struct glyph_string
*s
;
3330 int width
, left_x
, right_x
, top_y
, bottom_y
, last_x
, raised_p
;
3331 int left_p
, right_p
;
3332 struct glyph
*last_glyph
;
3335 last_x
= ((s
->row
->full_width_p
&& !s
->w
->pseudo_window_p
)
3336 ? WINDOW_RIGHT_EDGE_X (s
->w
)
3337 : window_box_right (s
->w
, s
->area
));
3339 /* The glyph that may have a right box line. */
3340 last_glyph
= (s
->cmp
|| s
->img
3342 : s
->first_glyph
+ s
->nchars
- 1);
3344 width
= abs (s
->face
->box_line_width
);
3345 raised_p
= s
->face
->box
== FACE_RAISED_BOX
;
3347 right_x
= (s
->row
->full_width_p
&& s
->extends_to_end_of_line_p
3349 : min (last_x
, s
->x
+ s
->background_width
) - 1);
3351 bottom_y
= top_y
+ s
->height
- 1;
3353 left_p
= (s
->first_glyph
->left_box_line_p
3354 || (s
->hl
== DRAW_MOUSE_FACE
3356 || s
->prev
->hl
!= s
->hl
)));
3357 right_p
= (last_glyph
->right_box_line_p
3358 || (s
->hl
== DRAW_MOUSE_FACE
3360 || s
->next
->hl
!= s
->hl
)));
3362 get_glyph_string_clip_rect (s
, &clip_rect
);
3364 if (s
->face
->box
== FACE_SIMPLE_BOX
)
3365 x_draw_box_rect (s
, left_x
, top_y
, right_x
, bottom_y
, width
,
3366 left_p
, right_p
, &clip_rect
);
3369 x_setup_relief_colors (s
);
3370 x_draw_relief_rect (s
->f
, left_x
, top_y
, right_x
, bottom_y
,
3371 width
, raised_p
, 1, 1, left_p
, right_p
, &clip_rect
);
3376 /* Draw foreground of image glyph string S. */
3379 x_draw_image_foreground (s
)
3380 struct glyph_string
*s
;
3383 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3385 /* If first glyph of S has a left box line, start drawing it to the
3386 right of that line. */
3387 if (s
->face
->box
!= FACE_NO_BOX
3388 && s
->first_glyph
->left_box_line_p
3390 x
+= abs (s
->face
->box_line_width
);
3392 /* If there is a margin around the image, adjust x- and y-position
3394 if (s
->slice
.x
== 0)
3395 x
+= s
->img
->hmargin
;
3396 if (s
->slice
.y
== 0)
3397 y
+= s
->img
->vmargin
;
3401 x_set_glyph_string_clipping (s
);
3404 mac_draw_cg_image (s
->img
->data
.ptr_val
,
3405 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3406 s
->slice
.width
, s
->slice
.height
, x
, y
, 1);
3410 mac_copy_area_with_mask (s
->img
->pixmap
, s
->img
->mask
,
3411 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3412 s
->slice
.width
, s
->slice
.height
, x
, y
);
3419 mac_copy_area (s
->img
->pixmap
,
3420 s
->f
, s
->gc
, s
->slice
.x
, s
->slice
.y
,
3421 s
->slice
.width
, s
->slice
.height
, x
, y
);
3424 /* When the image has a mask, we can expect that at
3425 least part of a mouse highlight or a block cursor will
3426 be visible. If the image doesn't have a mask, make
3427 a block cursor visible by drawing a rectangle around
3428 the image. I believe it's looking better if we do
3429 nothing here for mouse-face. */
3430 if (s
->hl
== DRAW_CURSOR
)
3432 int r
= s
->img
->relief
;
3434 mac_draw_rectangle (s
->f
, s
->gc
, x
- r
, y
- r
,
3435 s
->slice
.width
+ r
*2 - 1,
3436 s
->slice
.height
+ r
*2 - 1);
3441 /* Draw a rectangle if image could not be loaded. */
3442 mac_draw_rectangle (s
->f
, s
->gc
, x
, y
,
3443 s
->slice
.width
- 1, s
->slice
.height
- 1);
3447 /* Draw a relief around the image glyph string S. */
3450 x_draw_image_relief (s
)
3451 struct glyph_string
*s
;
3453 int x0
, y0
, x1
, y1
, thick
, raised_p
;
3456 int y
= s
->ybase
- image_ascent (s
->img
, s
->face
, &s
->slice
);
3458 /* If first glyph of S has a left box line, start drawing it to the
3459 right of that line. */
3460 if (s
->face
->box
!= FACE_NO_BOX
3461 && s
->first_glyph
->left_box_line_p
3463 x
+= abs (s
->face
->box_line_width
);
3465 /* If there is a margin around the image, adjust x- and y-position
3467 if (s
->slice
.x
== 0)
3468 x
+= s
->img
->hmargin
;
3469 if (s
->slice
.y
== 0)
3470 y
+= s
->img
->vmargin
;
3472 if (s
->hl
== DRAW_IMAGE_SUNKEN
3473 || s
->hl
== DRAW_IMAGE_RAISED
)
3475 thick
= tool_bar_button_relief
>= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
3476 raised_p
= s
->hl
== DRAW_IMAGE_RAISED
;
3480 thick
= abs (s
->img
->relief
);
3481 raised_p
= s
->img
->relief
> 0;
3486 x1
= x
+ s
->slice
.width
+ thick
- 1;
3487 y1
= y
+ s
->slice
.height
+ thick
- 1;
3489 x_setup_relief_colors (s
);
3490 get_glyph_string_clip_rect (s
, &r
);
3491 x_draw_relief_rect (s
->f
, x0
, y0
, x1
, y1
, thick
, raised_p
,
3493 s
->slice
.y
+ s
->slice
.height
== s
->img
->height
,
3495 s
->slice
.x
+ s
->slice
.width
== s
->img
->width
,
3500 /* Draw part of the background of glyph string S. X, Y, W, and H
3501 give the rectangle to draw. */
3504 x_draw_glyph_string_bg_rect (s
, x
, y
, w
, h
)
3505 struct glyph_string
*s
;
3508 #if 0 /* MAC_TODO: stipple */
3511 /* Fill background with a stipple pattern. */
3512 XSetFillStyle (s
->display
, s
->gc
, FillOpaqueStippled
);
3513 XFillRectangle (s
->display
, s
->window
, s
->gc
, x
, y
, w
, h
);
3514 XSetFillStyle (s
->display
, s
->gc
, FillSolid
);
3517 #endif /* MAC_TODO */
3518 x_clear_glyph_string_rect (s
, x
, y
, w
, h
);
3522 /* Draw image glyph string S.
3525 s->x +-------------------------
3528 | +-------------------------
3531 | | +-------------------
3537 x_draw_image_glyph_string (s
)
3538 struct glyph_string
*s
;
3541 int box_line_hwidth
= abs (s
->face
->box_line_width
);
3542 int box_line_vwidth
= max (s
->face
->box_line_width
, 0);
3545 height
= s
->height
- 2 * box_line_vwidth
;
3548 /* Fill background with face under the image. Do it only if row is
3549 taller than image or if image has a clip mask to reduce
3551 s
->stippled_p
= s
->face
->stipple
!= 0;
3552 if (height
> s
->slice
.height
3556 || s
->img
->pixmap
== 0
3557 || s
->width
!= s
->background_width
)
3560 if (s
->first_glyph
->left_box_line_p
3562 x
+= box_line_hwidth
;
3565 if (s
->slice
.y
== 0)
3566 y
+= box_line_vwidth
;
3568 x_draw_glyph_string_bg_rect (s
, x
, y
, s
->background_width
, height
);
3570 s
->background_filled_p
= 1;
3573 /* Draw the foreground. */
3574 x_draw_image_foreground (s
);
3576 /* If we must draw a relief around the image, do it. */
3578 || s
->hl
== DRAW_IMAGE_RAISED
3579 || s
->hl
== DRAW_IMAGE_SUNKEN
)
3580 x_draw_image_relief (s
);
3584 /* Draw stretch glyph string S. */
3587 x_draw_stretch_glyph_string (s
)
3588 struct glyph_string
*s
;
3590 xassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
3592 if (s
->hl
== DRAW_CURSOR
3593 && !x_stretch_cursor_p
)
3595 /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
3596 as wide as the stretch glyph. */
3597 int width
, background_width
= s
->background_width
;
3598 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3602 background_width
-= left_x
- x
;
3605 width
= min (FRAME_COLUMN_WIDTH (s
->f
), background_width
);
3608 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, width
, s
->height
);
3610 /* Clear rest using the GC of the original non-cursor face. */
3611 if (width
< background_width
)
3614 int w
= background_width
- width
, h
= s
->height
;
3619 if (s
->row
->mouse_face_p
3620 && cursor_in_mouse_face_p (s
->w
))
3622 x_set_mouse_face_gc (s
);
3628 get_glyph_string_clip_rect (s
, &r
);
3629 mac_set_clip_rectangles (s
->display
, gc
, &r
, 1);
3631 #if 0 /* MAC_TODO: stipple */
3632 if (s
->face
->stipple
)
3634 /* Fill background with a stipple pattern. */
3635 XSetFillStyle (s
->display
, gc
, FillOpaqueStippled
);
3636 XFillRectangle (s
->display
, s
->window
, gc
, x
, y
, w
, h
);
3637 XSetFillStyle (s
->display
, gc
, FillSolid
);
3640 #endif /* MAC_TODO */
3641 mac_erase_rectangle (s
->f
, gc
, x
, y
, w
, h
);
3644 else if (!s
->background_filled_p
)
3646 int background_width
= s
->background_width
;
3647 int x
= s
->x
, left_x
= window_box_left_offset (s
->w
, TEXT_AREA
);
3649 /* Don't draw into left margin, fringe or scrollbar area
3650 except for header line and mode line. */
3651 if (x
< left_x
&& !s
->row
->mode_line_p
)
3653 background_width
-= left_x
- x
;
3656 if (background_width
> 0)
3657 x_draw_glyph_string_bg_rect (s
, x
, s
->y
, background_width
, s
->height
);
3660 s
->background_filled_p
= 1;
3664 /* Draw glyph string S. */
3667 x_draw_glyph_string (s
)
3668 struct glyph_string
*s
;
3670 int relief_drawn_p
= 0;
3672 /* If S draws into the background of its successor that does not
3673 draw a cursor, draw the background of the successor first so that
3674 S can draw into it. This makes S->next use XDrawString instead
3675 of XDrawImageString. */
3676 if (s
->next
&& s
->right_overhang
&& !s
->for_overlaps
3677 && s
->next
->hl
!= DRAW_CURSOR
)
3679 xassert (s
->next
->img
== NULL
);
3680 x_set_glyph_string_gc (s
->next
);
3681 x_set_glyph_string_clipping (s
->next
);
3682 x_draw_glyph_string_background (s
->next
, 1);
3685 /* Set up S->gc, set clipping and draw S. */
3686 x_set_glyph_string_gc (s
);
3688 /* Draw relief (if any) in advance for char/composition so that the
3689 glyph string can be drawn over it. */
3690 if (!s
->for_overlaps
3691 && s
->face
->box
!= FACE_NO_BOX
3692 && (s
->first_glyph
->type
== CHAR_GLYPH
3693 || s
->first_glyph
->type
== COMPOSITE_GLYPH
))
3696 x_set_glyph_string_clipping (s
);
3697 x_draw_glyph_string_background (s
, 1);
3698 x_draw_glyph_string_box (s
);
3699 x_set_glyph_string_clipping (s
);
3703 x_set_glyph_string_clipping (s
);
3705 switch (s
->first_glyph
->type
)
3708 x_draw_image_glyph_string (s
);
3712 x_draw_stretch_glyph_string (s
);
3716 if (s
->for_overlaps
)
3717 s
->background_filled_p
= 1;
3719 x_draw_glyph_string_background (s
, 0);
3720 x_draw_glyph_string_foreground (s
);
3723 case COMPOSITE_GLYPH
:
3724 if (s
->for_overlaps
|| s
->gidx
> 0)
3725 s
->background_filled_p
= 1;
3727 x_draw_glyph_string_background (s
, 1);
3728 x_draw_composite_glyph_string_foreground (s
);
3735 if (!s
->for_overlaps
)
3737 /* Draw underline. */
3738 if (s
->face
->underline_p
)
3740 unsigned long tem
, h
;
3744 /* Get the underline thickness. Default is 1 pixel. */
3745 if (!XGetFontProperty (s
->font
, XA_UNDERLINE_THICKNESS
, &h
))
3749 y
= s
->y
+ s
->height
- h
;
3750 if (!x_underline_at_descent_line
)
3752 /* Get the underline position. This is the recommended
3753 vertical offset in pixels from the baseline to the top of
3754 the underline. This is a signed value according to the
3755 specs, and its default is
3757 ROUND ((maximum descent) / 2), with
3758 ROUND(x) = floor (x + 0.5) */
3761 if (x_use_underline_position_properties
3762 && XGetFontProperty (s
->font
, XA_UNDERLINE_POSITION
, &tem
))
3763 y
= s
->ybase
+ (long) tem
;
3767 y
= s
->ybase
+ (s
->face
->font
->max_bounds
.descent
+ 1) / 2;
3770 if (s
->face
->underline_defaulted_p
)
3771 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3772 s
->background_width
, h
);
3776 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3777 XSetForeground (s
->display
, s
->gc
, s
->face
->underline_color
);
3778 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, y
,
3779 s
->background_width
, h
);
3780 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3784 /* Draw overline. */
3785 if (s
->face
->overline_p
)
3787 unsigned long dy
= 0, h
= 1;
3789 if (s
->face
->overline_color_defaulted_p
)
3790 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3791 s
->background_width
, h
);
3795 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3796 XSetForeground (s
->display
, s
->gc
, s
->face
->overline_color
);
3797 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3798 s
->background_width
, h
);
3799 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3803 /* Draw strike-through. */
3804 if (s
->face
->strike_through_p
)
3806 unsigned long h
= 1;
3807 unsigned long dy
= (s
->height
- h
) / 2;
3809 if (s
->face
->strike_through_color_defaulted_p
)
3810 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3815 XGetGCValues (s
->display
, s
->gc
, GCForeground
, &xgcv
);
3816 XSetForeground (s
->display
, s
->gc
, s
->face
->strike_through_color
);
3817 mac_fill_rectangle (s
->f
, s
->gc
, s
->x
, s
->y
+ dy
,
3819 XSetForeground (s
->display
, s
->gc
, xgcv
.foreground
);
3823 /* Draw relief if not yet drawn. */
3824 if (!relief_drawn_p
&& s
->face
->box
!= FACE_NO_BOX
)
3825 x_draw_glyph_string_box (s
);
3828 /* Reset clipping. */
3829 mac_reset_clip_rectangles (s
->display
, s
->gc
);
3832 /* Shift display to make room for inserted glyphs. */
3835 mac_shift_glyphs_for_insert (f
, x
, y
, width
, height
, shift_by
)
3837 int x
, y
, width
, height
, shift_by
;
3839 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
3840 x
, y
, width
, height
,
3844 /* Delete N glyphs at the nominal cursor position. Not implemented
3855 /* Clear entire frame. If updating_frame is non-null, clear that
3856 frame. Otherwise clear the selected frame. */
3866 f
= SELECTED_FRAME ();
3868 /* Clearing the frame will erase any cursor, so mark them all as no
3870 mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f
)));
3871 output_cursor
.hpos
= output_cursor
.vpos
= 0;
3872 output_cursor
.x
= -1;
3874 /* We don't set the output cursor here because there will always
3875 follow an explicit cursor_to. */
3877 mac_clear_window (f
);
3879 /* We have to clear the scroll bars, too. If we have changed
3880 colors or something like that, then they should be notified. */
3881 x_scroll_bar_clear (f
);
3883 XFlush (FRAME_MAC_DISPLAY (f
));
3889 /* Invert the middle quarter of the frame for .15 sec. */
3891 /* We use the select system call to do the waiting, so we have to make
3892 sure it's available. If it isn't, we just won't do visual bells. */
3894 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3897 /* Subtract the `struct timeval' values X and Y, storing the result in
3898 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3901 timeval_subtract (result
, x
, y
)
3902 struct timeval
*result
, x
, y
;
3904 /* Perform the carry for the later subtraction by updating y. This
3905 is safer because on some systems the tv_sec member is unsigned. */
3906 if (x
.tv_usec
< y
.tv_usec
)
3908 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000 + 1;
3909 y
.tv_usec
-= 1000000 * nsec
;
3913 if (x
.tv_usec
- y
.tv_usec
> 1000000)
3915 int nsec
= (y
.tv_usec
- x
.tv_usec
) / 1000000;
3916 y
.tv_usec
+= 1000000 * nsec
;
3920 /* Compute the time remaining to wait. tv_usec is certainly
3922 result
->tv_sec
= x
.tv_sec
- y
.tv_sec
;
3923 result
->tv_usec
= x
.tv_usec
- y
.tv_usec
;
3925 /* Return indication of whether the result should be considered
3927 return x
.tv_sec
< y
.tv_sec
;
3934 /* Get the height not including a menu bar widget. */
3935 int height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, FRAME_LINES (f
));
3936 /* Height of each line to flash. */
3937 int flash_height
= FRAME_LINE_HEIGHT (f
);
3938 /* These will be the left and right margins of the rectangles. */
3939 int flash_left
= FRAME_INTERNAL_BORDER_WIDTH (f
);
3940 int flash_right
= FRAME_PIXEL_WIDTH (f
) - FRAME_INTERNAL_BORDER_WIDTH (f
);
3944 /* Don't flash the area between a scroll bar and the frame
3945 edge it is next to. */
3946 switch (FRAME_VERTICAL_SCROLL_BAR_TYPE (f
))
3948 case vertical_scroll_bar_left
:
3949 flash_left
+= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3952 case vertical_scroll_bar_right
:
3953 flash_right
-= VERTICAL_SCROLL_BAR_WIDTH_TRIM
;
3960 width
= flash_right
- flash_left
;
3964 /* If window is tall, flash top and bottom line. */
3965 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
3967 mac_invert_rectangle (f
, flash_left
,
3968 (FRAME_INTERNAL_BORDER_WIDTH (f
)
3969 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
3970 width
, flash_height
);
3971 mac_invert_rectangle (f
, flash_left
,
3972 (height
- flash_height
3973 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
3974 width
, flash_height
);
3977 /* If it is short, flash it all. */
3978 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
3979 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
3984 struct timeval wakeup
;
3986 EMACS_GET_TIME (wakeup
);
3988 /* Compute time to wait until, propagating carry from usecs. */
3989 wakeup
.tv_usec
+= 150000;
3990 wakeup
.tv_sec
+= (wakeup
.tv_usec
/ 1000000);
3991 wakeup
.tv_usec
%= 1000000;
3993 /* Keep waiting until past the time wakeup or any input gets
3995 while (! detect_input_pending ())
3997 struct timeval current
;
3998 struct timeval timeout
;
4000 EMACS_GET_TIME (current
);
4002 /* Break if result would be negative. */
4003 if (timeval_subtract (¤t
, wakeup
, current
))
4006 /* How long `select' should wait. */
4008 timeout
.tv_usec
= 10000;
4010 /* Try to wait that long--but we might wake up sooner. */
4011 select (0, NULL
, NULL
, NULL
, &timeout
);
4015 /* If window is tall, flash top and bottom line. */
4016 if (height
> 3 * FRAME_LINE_HEIGHT (f
))
4018 mac_invert_rectangle (f
, flash_left
,
4019 (FRAME_INTERNAL_BORDER_WIDTH (f
)
4020 + FRAME_TOOL_BAR_LINES (f
) * FRAME_LINE_HEIGHT (f
)),
4021 width
, flash_height
);
4022 mac_invert_rectangle (f
, flash_left
,
4023 (height
- flash_height
4024 - FRAME_INTERNAL_BORDER_WIDTH (f
)),
4025 width
, flash_height
);
4028 /* If it is short, flash it all. */
4029 mac_invert_rectangle (f
, flash_left
, FRAME_INTERNAL_BORDER_WIDTH (f
),
4030 width
, height
- 2 * FRAME_INTERNAL_BORDER_WIDTH (f
));
4037 #endif /* defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) */
4040 /* Make audible bell. */
4045 struct frame
*f
= SELECTED_FRAME ();
4047 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
4054 mac_alert_sound_play ();
4055 XFlush (FRAME_MAC_DISPLAY (f
));
4061 /* Specify how many text lines, from the top of the window,
4062 should be affected by insert-lines and delete-lines operations.
4063 This, and those operations, are used only within an update
4064 that is bounded by calls to x_update_begin and x_update_end. */
4067 XTset_terminal_window (n
)
4070 /* This function intentionally left blank. */
4075 /***********************************************************************
4077 ***********************************************************************/
4079 /* Perform an insert-lines or delete-lines operation, inserting N
4080 lines or deleting -N lines at vertical position VPOS. */
4083 x_ins_del_lines (vpos
, n
)
4090 /* Scroll part of the display as described by RUN. */
4093 x_scroll_run (w
, run
)
4097 struct frame
*f
= XFRAME (w
->frame
);
4098 int x
, y
, width
, height
, from_y
, to_y
, bottom_y
;
4100 /* Get frame-relative bounding box of the text display area of W,
4101 without mode lines. Include in this box the left and right
4103 window_box (w
, -1, &x
, &y
, &width
, &height
);
4105 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->current_y
);
4106 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, run
->desired_y
);
4107 bottom_y
= y
+ height
;
4111 /* Scrolling up. Make sure we don't copy part of the mode
4112 line at the bottom. */
4113 if (from_y
+ run
->height
> bottom_y
)
4114 height
= bottom_y
- from_y
;
4116 height
= run
->height
;
4120 /* Scolling down. Make sure we don't copy over the mode line.
4122 if (to_y
+ run
->height
> bottom_y
)
4123 height
= bottom_y
- to_y
;
4125 height
= run
->height
;
4130 /* Cursor off. Will be switched on again in x_update_window_end. */
4134 mac_scroll_area (f
, f
->output_data
.mac
->normal_gc
,
4144 /***********************************************************************
4146 ***********************************************************************/
4153 x_update_cursor (f
, 1);
4157 frame_unhighlight (f
)
4160 x_update_cursor (f
, 1);
4163 /* The focus has changed. Update the frames as necessary to reflect
4164 the new situation. Note that we can't change the selected frame
4165 here, because the Lisp code we are interrupting might become confused.
4166 Each event gets marked with the frame in which it occurred, so the
4167 Lisp code can tell when the switch took place by examining the events. */
4170 x_new_focus_frame (dpyinfo
, frame
)
4171 struct x_display_info
*dpyinfo
;
4172 struct frame
*frame
;
4174 struct frame
*old_focus
= dpyinfo
->x_focus_frame
;
4176 if (frame
!= dpyinfo
->x_focus_frame
)
4178 /* Set this before calling other routines, so that they see
4179 the correct value of x_focus_frame. */
4180 dpyinfo
->x_focus_frame
= frame
;
4182 if (old_focus
&& old_focus
->auto_lower
)
4183 x_lower_frame (old_focus
);
4186 selected_frame
= frame
;
4187 XSETFRAME (XWINDOW (selected_frame
->selected_window
)->frame
,
4189 Fselect_window (selected_frame
->selected_window
, Qnil
);
4190 choose_minibuf_frame ();
4193 if (dpyinfo
->x_focus_frame
&& dpyinfo
->x_focus_frame
->auto_raise
)
4194 pending_autoraise_frame
= dpyinfo
->x_focus_frame
;
4196 pending_autoraise_frame
= 0;
4198 #if USE_MAC_FONT_PANEL
4200 mac_set_font_info_for_selection (frame
, DEFAULT_FACE_ID
, 0);
4204 x_frame_rehighlight (dpyinfo
);
4207 /* Handle FocusIn and FocusOut state changes for FRAME.
4208 If FRAME has focus and there exists more than one frame, puts
4209 a FOCUS_IN_EVENT into *BUFP. */
4212 mac_focus_changed (type
, dpyinfo
, frame
, bufp
)
4214 struct mac_display_info
*dpyinfo
;
4215 struct frame
*frame
;
4216 struct input_event
*bufp
;
4218 if (type
== activeFlag
)
4220 if (dpyinfo
->x_focus_event_frame
!= frame
)
4222 x_new_focus_frame (dpyinfo
, frame
);
4223 dpyinfo
->x_focus_event_frame
= frame
;
4225 /* Don't stop displaying the initial startup message
4226 for a switch-frame event we don't need. */
4227 if (GC_NILP (Vterminal_frame
)
4228 && GC_CONSP (Vframe_list
)
4229 && !GC_NILP (XCDR (Vframe_list
)))
4231 bufp
->kind
= FOCUS_IN_EVENT
;
4232 XSETFRAME (bufp
->frame_or_window
, frame
);
4238 if (dpyinfo
->x_focus_event_frame
== frame
)
4240 dpyinfo
->x_focus_event_frame
= 0;
4241 x_new_focus_frame (dpyinfo
, 0);
4246 /* Handle an event saying the mouse has moved out of an Emacs frame. */
4249 x_mouse_leave (dpyinfo
)
4250 struct x_display_info
*dpyinfo
;
4252 x_new_focus_frame (dpyinfo
, dpyinfo
->x_focus_event_frame
);
4255 /* The focus has changed, or we have redirected a frame's focus to
4256 another frame (this happens when a frame uses a surrogate
4257 mini-buffer frame). Shift the highlight as appropriate.
4259 The FRAME argument doesn't necessarily have anything to do with which
4260 frame is being highlighted or un-highlighted; we only use it to find
4261 the appropriate X display info. */
4264 XTframe_rehighlight (frame
)
4265 struct frame
*frame
;
4267 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame
));
4271 x_frame_rehighlight (dpyinfo
)
4272 struct x_display_info
*dpyinfo
;
4274 struct frame
*old_highlight
= dpyinfo
->x_highlight_frame
;
4276 if (dpyinfo
->x_focus_frame
)
4278 dpyinfo
->x_highlight_frame
4279 = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
)))
4280 ? XFRAME (FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
))
4281 : dpyinfo
->x_focus_frame
);
4282 if (! FRAME_LIVE_P (dpyinfo
->x_highlight_frame
))
4284 FRAME_FOCUS_FRAME (dpyinfo
->x_focus_frame
) = Qnil
;
4285 dpyinfo
->x_highlight_frame
= dpyinfo
->x_focus_frame
;
4289 dpyinfo
->x_highlight_frame
= 0;
4291 if (dpyinfo
->x_highlight_frame
!= old_highlight
)
4294 frame_unhighlight (old_highlight
);
4295 if (dpyinfo
->x_highlight_frame
)
4296 frame_highlight (dpyinfo
->x_highlight_frame
);
4302 /* Convert a keysym to its name. */
4305 x_get_keysym_name (keysym
)
4312 value
= XKeysymToString (keysym
);
4323 /* Function to report a mouse movement to the mainstream Emacs code.
4324 The input handler calls this.
4326 We have received a mouse movement event, which is given in *event.
4327 If the mouse is over a different glyph than it was last time, tell
4328 the mainstream emacs code by setting mouse_moved. If not, ask for
4329 another motion event, so we can check again the next time it moves. */
4331 static Point last_mouse_motion_position
;
4332 static Lisp_Object last_mouse_motion_frame
;
4335 note_mouse_movement (frame
, pos
)
4339 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (frame
);
4342 last_mouse_movement_time
= TickCount () * (1000 / 60); /* to milliseconds */
4343 last_mouse_motion_position
= *pos
;
4344 XSETFRAME (last_mouse_motion_frame
, frame
);
4346 if (frame
== dpyinfo
->mouse_face_mouse_frame
4347 && !PtInRect (*pos
, mac_get_frame_bounds (frame
, &r
)))
4349 /* This case corresponds to LeaveNotify in X11. If we move
4350 outside the frame, then we're certainly no longer on any text
4352 clear_mouse_face (dpyinfo
);
4353 dpyinfo
->mouse_face_mouse_frame
= 0;
4354 if (!dpyinfo
->grabbed
)
4355 rif
->define_frame_cursor (frame
,
4356 frame
->output_data
.mac
->nontext_cursor
);
4359 /* Has the mouse moved off the glyph it was on at the last sighting? */
4360 if (frame
!= last_mouse_glyph_frame
4361 || !PtInRect (*pos
, &last_mouse_glyph
))
4363 frame
->mouse_moved
= 1;
4364 last_mouse_scroll_bar
= Qnil
;
4365 note_mouse_highlight (frame
, pos
->h
, pos
->v
);
4366 /* Remember which glyph we're now on. */
4367 remember_mouse_glyph (frame
, pos
->h
, pos
->v
, &last_mouse_glyph
);
4368 last_mouse_glyph_frame
= frame
;
4376 /************************************************************************
4378 ************************************************************************/
4380 /* MAC TODO: This should be called from somewhere (or removed) ++KFS */
4383 redo_mouse_highlight ()
4385 if (!NILP (last_mouse_motion_frame
)
4386 && FRAME_LIVE_P (XFRAME (last_mouse_motion_frame
)))
4387 note_mouse_highlight (XFRAME (last_mouse_motion_frame
),
4388 last_mouse_motion_position
.h
,
4389 last_mouse_motion_position
.v
);
4394 mac_focus_frame (dpyinfo
)
4395 struct mac_display_info
*dpyinfo
;
4397 if (dpyinfo
->x_focus_frame
)
4398 return dpyinfo
->x_focus_frame
;
4400 /* Mac version may get events, such as a menu bar click, even when
4401 all the frames are invisible. In this case, we regard the
4402 event came to the selected frame. */
4403 return SELECTED_FRAME ();
4407 /* Return the current position of the mouse.
4408 *FP should be a frame which indicates which display to ask about.
4410 If the mouse movement started in a scroll bar, set *FP, *BAR_WINDOW,
4411 and *PART to the frame, window, and scroll bar part that the mouse
4412 is over. Set *X and *Y to the portion and whole of the mouse's
4413 position on the scroll bar.
4415 If the mouse movement started elsewhere, set *FP to the frame the
4416 mouse is on, *BAR_WINDOW to nil, and *X and *Y to the character cell
4419 Set *TIME to the server time-stamp for the time at which the mouse
4420 was at this position.
4422 Don't store anything if we don't have a valid set of values to report.
4424 This clears the mouse_moved flag, so we can wait for the next mouse
4428 XTmouse_position (fp
, insist
, bar_window
, part
, x
, y
, time
)
4431 Lisp_Object
*bar_window
;
4432 enum scroll_bar_part
*part
;
4434 unsigned long *time
;
4440 if (! NILP (last_mouse_scroll_bar
) && insist
== 0)
4441 x_scroll_bar_report_motion (fp
, bar_window
, part
, x
, y
, time
);
4444 Lisp_Object frame
, tail
;
4446 /* Clear the mouse-moved flag for every frame on this display. */
4447 FOR_EACH_FRAME (tail
, frame
)
4448 XFRAME (frame
)->mouse_moved
= 0;
4450 last_mouse_scroll_bar
= Qnil
;
4452 if (FRAME_MAC_DISPLAY_INFO (*fp
)->grabbed
&& last_mouse_frame
4453 && FRAME_LIVE_P (last_mouse_frame
))
4454 f1
= last_mouse_frame
;
4456 f1
= mac_focus_frame (FRAME_MAC_DISPLAY_INFO (*fp
));
4460 /* Ok, we found a frame. Store all the values.
4461 last_mouse_glyph is a rectangle used to reduce the
4462 generation of mouse events. To not miss any motion
4463 events, we must divide the frame into rectangles of the
4464 size of the smallest character that could be displayed
4465 on it, i.e. into the same rectangles that matrices on
4466 the frame are divided into. */
4469 mac_get_frame_mouse (f1
, &mouse_pos
);
4470 remember_mouse_glyph (f1
, mouse_pos
.h
, mouse_pos
.v
,
4472 last_mouse_glyph_frame
= f1
;
4477 XSETINT (*x
, mouse_pos
.h
);
4478 XSETINT (*y
, mouse_pos
.v
);
4479 *time
= last_mouse_movement_time
;
4487 /************************************************************************
4488 Scroll bars, general
4489 ************************************************************************/
4491 /* Create a scroll bar and return the scroll bar vector for it. W is
4492 the Emacs window on which to create the scroll bar. TOP, LEFT,
4493 WIDTH and HEIGHT are the pixel coordinates and dimensions of the
4496 static struct scroll_bar
*
4497 x_scroll_bar_create (w
, top
, left
, width
, height
, disp_top
, disp_height
)
4499 int top
, left
, width
, height
, disp_top
, disp_height
;
4501 struct frame
*f
= XFRAME (w
->frame
);
4502 struct scroll_bar
*bar
4503 = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE
), Qnil
));
4508 XSETWINDOW (bar
->window
, w
);
4509 XSETINT (bar
->top
, top
);
4510 XSETINT (bar
->left
, left
);
4511 XSETINT (bar
->width
, width
);
4512 XSETINT (bar
->height
, height
);
4514 bar
->fringe_extended_p
= Qnil
;
4516 bar
->redraw_needed_p
= Qnil
;
4518 SetRect (&r
, left
, disp_top
, left
+ width
, disp_top
+ disp_height
);
4519 mac_create_scroll_bar (bar
, &r
,
4520 #ifdef USE_TOOLKIT_SCROLL_BARS
4527 /* Add bar to its frame's list of scroll bars. */
4528 bar
->next
= FRAME_SCROLL_BARS (f
);
4530 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4531 if (!NILP (bar
->next
))
4532 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4539 /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to
4543 x_scroll_bar_remove (bar
)
4544 struct scroll_bar
*bar
;
4548 /* Destroy the Mac scroll bar control */
4549 mac_dispose_scroll_bar (bar
);
4551 /* Disassociate this scroll bar from its window. */
4552 XWINDOW (bar
->window
)->vertical_scroll_bar
= Qnil
;
4558 /* Set the handle of the vertical scroll bar for WINDOW to indicate
4559 that we are displaying PORTION characters out of a total of WHOLE
4560 characters, starting at POSITION. If WINDOW has no scroll bar,
4564 XTset_vertical_scroll_bar (w
, portion
, whole
, position
)
4566 int portion
, whole
, position
;
4568 struct frame
*f
= XFRAME (w
->frame
);
4569 struct scroll_bar
*bar
;
4570 int top
, height
, left
, sb_left
, width
, sb_width
, disp_top
, disp_height
;
4571 int window_y
, window_height
;
4573 int fringe_extended_p
;
4576 /* Get window dimensions. */
4577 window_box (w
, -1, 0, &window_y
, 0, &window_height
);
4579 width
= WINDOW_CONFIG_SCROLL_BAR_COLS (w
) * FRAME_COLUMN_WIDTH (f
);
4580 height
= window_height
;
4582 /* Compute the left edge of the scroll bar area. */
4583 left
= WINDOW_SCROLL_BAR_AREA_X (w
);
4585 /* Compute the width of the scroll bar which might be less than
4586 the width of the area reserved for the scroll bar. */
4587 if (WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
) > 0)
4588 sb_width
= WINDOW_CONFIG_SCROLL_BAR_WIDTH (w
);
4592 /* Compute the left edge of the scroll bar. */
4593 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
4594 sb_left
= left
+ (WINDOW_RIGHTMOST_P (w
) ? width
- sb_width
: 0);
4596 sb_left
= left
+ (WINDOW_LEFTMOST_P (w
) ? 0 : width
- sb_width
);
4598 /* Adjustments according to Inside Macintosh to make it look nice */
4600 disp_height
= height
;
4607 else if (disp_top
== FRAME_PIXEL_HEIGHT (f
) - 16)
4613 if (sb_left
+ sb_width
== FRAME_PIXEL_WIDTH (f
))
4618 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
4619 fringe_extended_p
= (WINDOW_LEFTMOST_P (w
)
4620 && WINDOW_LEFT_FRINGE_WIDTH (w
)
4621 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
4622 || WINDOW_LEFT_MARGIN_COLS (w
) == 0));
4624 fringe_extended_p
= (WINDOW_RIGHTMOST_P (w
)
4625 && WINDOW_RIGHT_FRINGE_WIDTH (w
)
4626 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
4627 || WINDOW_RIGHT_MARGIN_COLS (w
) == 0));
4630 /* Does the scroll bar exist yet? */
4631 if (NILP (w
->vertical_scroll_bar
))
4635 if (fringe_extended_p
)
4636 mac_clear_area (f
, sb_left
, top
, sb_width
, height
);
4639 mac_clear_area (f
, left
, top
, width
, height
);
4641 bar
= x_scroll_bar_create (w
, top
, sb_left
, sb_width
, height
, disp_top
,
4643 XSETVECTOR (w
->vertical_scroll_bar
, bar
);
4647 /* It may just need to be moved and resized. */
4648 bar
= XSCROLL_BAR (w
->vertical_scroll_bar
);
4652 /* If already correctly positioned, do nothing. */
4653 if (XINT (bar
->left
) == sb_left
4654 && XINT (bar
->top
) == top
4655 && XINT (bar
->width
) == sb_width
4656 && XINT (bar
->height
) == height
4658 && !NILP (bar
->fringe_extended_p
) == fringe_extended_p
4662 if (!NILP (bar
->redraw_needed_p
))
4663 mac_redraw_scroll_bar (bar
);
4669 /* Since toolkit scroll bars are smaller than the space reserved
4670 for them on the frame, we have to clear "under" them. */
4672 if (fringe_extended_p
)
4673 mac_clear_area (f
, sb_left
, top
, sb_width
, height
);
4676 mac_clear_area (f
, left
, top
, width
, height
);
4678 SetRect (&r
, sb_left
+ VERTICAL_SCROLL_BAR_WIDTH_TRIM
, disp_top
,
4679 sb_left
+ sb_width
- VERTICAL_SCROLL_BAR_WIDTH_TRIM
,
4680 disp_top
+ disp_height
);
4681 mac_set_scroll_bar_bounds (bar
, &r
);
4683 /* Remember new settings. */
4684 XSETINT (bar
->left
, sb_left
);
4685 XSETINT (bar
->top
, top
);
4686 XSETINT (bar
->width
, sb_width
);
4687 XSETINT (bar
->height
, height
);
4694 bar
->fringe_extended_p
= fringe_extended_p
? Qt
: Qnil
;
4696 bar
->redraw_needed_p
= Qnil
;
4698 #ifdef USE_TOOLKIT_SCROLL_BARS
4699 x_set_toolkit_scroll_bar_thumb (bar
, portion
, position
, whole
);
4700 #else /* not USE_TOOLKIT_SCROLL_BARS */
4701 /* Set the scroll bar's current state, unless we're currently being
4703 if (NILP (bar
->dragging
))
4705 int top_range
= VERTICAL_SCROLL_BAR_TOP_RANGE (f
, height
);
4708 x_scroll_bar_set_handle (bar
, 0, top_range
, 0);
4711 int start
= ((double) position
* top_range
) / whole
;
4712 int end
= ((double) (position
+ portion
) * top_range
) / whole
;
4713 x_scroll_bar_set_handle (bar
, start
, end
, 0);
4716 #endif /* not USE_TOOLKIT_SCROLL_BARS */
4720 /* The following three hooks are used when we're doing a thorough
4721 redisplay of the frame. We don't explicitly know which scroll bars
4722 are going to be deleted, because keeping track of when windows go
4723 away is a real pain - "Can you say set-window-configuration, boys
4724 and girls?" Instead, we just assert at the beginning of redisplay
4725 that *all* scroll bars are to be removed, and then save a scroll bar
4726 from the fiery pit when we actually redisplay its window. */
4728 /* Arrange for all scroll bars on FRAME to be removed at the next call
4729 to `*judge_scroll_bars_hook'. A scroll bar may be spared if
4730 `*redeem_scroll_bar_hook' is applied to its window before the judgment. */
4733 XTcondemn_scroll_bars (frame
)
4736 /* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
4737 while (! NILP (FRAME_SCROLL_BARS (frame
)))
4740 bar
= FRAME_SCROLL_BARS (frame
);
4741 FRAME_SCROLL_BARS (frame
) = XSCROLL_BAR (bar
)->next
;
4742 XSCROLL_BAR (bar
)->next
= FRAME_CONDEMNED_SCROLL_BARS (frame
);
4743 XSCROLL_BAR (bar
)->prev
= Qnil
;
4744 if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame
)))
4745 XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame
))->prev
= bar
;
4746 FRAME_CONDEMNED_SCROLL_BARS (frame
) = bar
;
4751 /* Un-mark WINDOW's scroll bar for deletion in this judgment cycle.
4752 Note that WINDOW isn't necessarily condemned at all. */
4755 XTredeem_scroll_bar (window
)
4756 struct window
*window
;
4758 struct scroll_bar
*bar
;
4761 /* We can't redeem this window's scroll bar if it doesn't have one. */
4762 if (NILP (window
->vertical_scroll_bar
))
4765 bar
= XSCROLL_BAR (window
->vertical_scroll_bar
);
4767 /* Unlink it from the condemned list. */
4768 f
= XFRAME (WINDOW_FRAME (window
));
4769 if (NILP (bar
->prev
))
4771 /* If the prev pointer is nil, it must be the first in one of
4773 if (EQ (FRAME_SCROLL_BARS (f
), window
->vertical_scroll_bar
))
4774 /* It's not condemned. Everything's fine. */
4776 else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f
),
4777 window
->vertical_scroll_bar
))
4778 FRAME_CONDEMNED_SCROLL_BARS (f
) = bar
->next
;
4780 /* If its prev pointer is nil, it must be at the front of
4781 one or the other! */
4785 XSCROLL_BAR (bar
->prev
)->next
= bar
->next
;
4787 if (! NILP (bar
->next
))
4788 XSCROLL_BAR (bar
->next
)->prev
= bar
->prev
;
4790 bar
->next
= FRAME_SCROLL_BARS (f
);
4792 XSETVECTOR (FRAME_SCROLL_BARS (f
), bar
);
4793 if (! NILP (bar
->next
))
4794 XSETVECTOR (XSCROLL_BAR (bar
->next
)->prev
, bar
);
4797 /* Remove all scroll bars on FRAME that haven't been saved since the
4798 last call to `*condemn_scroll_bars_hook'. */
4801 XTjudge_scroll_bars (f
)
4804 Lisp_Object bar
, next
;
4806 bar
= FRAME_CONDEMNED_SCROLL_BARS (f
);
4808 /* Clear out the condemned list now so we won't try to process any
4809 more events on the hapless scroll bars. */
4810 FRAME_CONDEMNED_SCROLL_BARS (f
) = Qnil
;
4812 for (; ! NILP (bar
); bar
= next
)
4814 struct scroll_bar
*b
= XSCROLL_BAR (bar
);
4816 x_scroll_bar_remove (b
);
4819 b
->next
= b
->prev
= Qnil
;
4822 /* Now there should be no references to the condemned scroll bars,
4823 and they should get garbage-collected. */
4826 /* The screen has been cleared so we may have changed foreground or
4827 background colors, and the scroll bars may need to be redrawn.
4828 Clear out the scroll bars, and ask for expose events, so we can
4832 x_scroll_bar_clear (f
)
4837 /* We can have scroll bars even if this is 0,
4838 if we just turned off scroll bar mode.
4839 But in that case we should not clear them. */
4840 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
))
4841 for (bar
= FRAME_SCROLL_BARS (f
); VECTORP (bar
);
4842 bar
= XSCROLL_BAR (bar
)->next
)
4843 XSCROLL_BAR (bar
)->redraw_needed_p
= Qt
;
4847 /***********************************************************************
4849 ***********************************************************************/
4852 mac_move_window_with_gravity (f
, win_gravity
, left
, top
)
4859 mac_get_window_bounds (f
, &inner
, &outer
);
4861 switch (win_gravity
)
4863 case NorthWestGravity
:
4865 case SouthWestGravity
:
4866 left
+= inner
.left
- outer
.left
;
4872 left
+= ((inner
.left
- outer
.left
) + (inner
.right
- outer
.right
)) / 2;
4875 case NorthEastGravity
:
4877 case SouthEastGravity
:
4878 left
+= inner
.right
- outer
.right
;
4882 switch (win_gravity
)
4884 case NorthWestGravity
:
4886 case NorthEastGravity
:
4887 top
+= inner
.top
- outer
.top
;
4893 top
+= ((inner
.top
- outer
.top
) + (inner
.bottom
- outer
.bottom
)) / 2;
4896 case SouthWestGravity
:
4898 case SouthEastGravity
:
4899 top
+= inner
.bottom
- outer
.bottom
;
4903 mac_move_window (FRAME_MAC_WINDOW (f
), left
, top
, false);
4907 mac_get_window_origin_with_gravity (f
, win_gravity
, left
, top
)
4914 mac_get_window_bounds (f
, &inner
, &outer
);
4916 switch (win_gravity
)
4918 case NorthWestGravity
:
4920 case SouthWestGravity
:
4927 *left
= outer
.left
+ ((outer
.right
- outer
.left
)
4928 - (inner
.right
- inner
.left
)) / 2;
4931 case NorthEastGravity
:
4933 case SouthEastGravity
:
4934 *left
= outer
.right
- (inner
.right
- inner
.left
);
4938 switch (win_gravity
)
4940 case NorthWestGravity
:
4942 case NorthEastGravity
:
4949 *top
= outer
.top
+ ((outer
.bottom
- outer
.top
)
4950 - (inner
.bottom
- inner
.top
)) / 2;
4953 case SouthWestGravity
:
4955 case SouthEastGravity
:
4956 *top
= outer
.bottom
- (inner
.bottom
- inner
.top
);
4962 mac_image_spec_to_cg_image (f
, image
)
4966 if (!valid_image_p (image
))
4970 int img_id
= lookup_image (f
, image
);
4971 struct image
*img
= IMAGE_FROM_ID (f
, img_id
);
4973 prepare_image_for_display (f
, img
);
4975 return img
->data
.ptr_val
;
4978 #endif /* USE_MAC_TOOLBAR */
4981 /***********************************************************************
4983 ***********************************************************************/
4985 /* Set clipping for output in glyph row ROW. W is the window in which
4986 we operate. GC is the graphics context to set clipping in.
4988 ROW may be a text row or, e.g., a mode line. Text rows must be
4989 clipped to the interior of the window dedicated to text display,
4990 mode lines must be clipped to the whole window. */
4993 x_clip_to_row (w
, row
, area
, gc
)
4995 struct glyph_row
*row
;
4999 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5001 int window_x
, window_y
, window_width
;
5003 window_box (w
, area
, &window_x
, &window_y
, &window_width
, 0);
5005 clip_rect
.left
= window_x
;
5006 clip_rect
.top
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
5007 clip_rect
.top
= max (clip_rect
.top
, window_y
);
5008 clip_rect
.right
= clip_rect
.left
+ window_width
;
5009 clip_rect
.bottom
= clip_rect
.top
+ row
->visible_height
;
5011 mac_set_clip_rectangles (FRAME_MAC_DISPLAY (f
), gc
, &clip_rect
, 1);
5015 /* Draw a hollow box cursor on window W in glyph row ROW. */
5018 x_draw_hollow_cursor (w
, row
)
5020 struct glyph_row
*row
;
5022 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
5023 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5024 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5027 struct glyph
*cursor_glyph
;
5030 /* Get the glyph the cursor is on. If we can't tell because
5031 the current matrix is invalid or such, give up. */
5032 cursor_glyph
= get_phys_cursor_glyph (w
);
5033 if (cursor_glyph
== NULL
)
5036 /* Compute frame-relative coordinates for phys cursor. */
5037 get_phys_cursor_geometry (w
, row
, cursor_glyph
, &x
, &y
, &h
);
5038 wd
= w
->phys_cursor_width
;
5040 /* The foreground of cursor_gc is typically the same as the normal
5041 background color, which can cause the cursor box to be invisible. */
5042 xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5043 if (dpyinfo
->scratch_cursor_gc
)
5044 XChangeGC (dpy
, dpyinfo
->scratch_cursor_gc
, GCForeground
, &xgcv
);
5046 dpyinfo
->scratch_cursor_gc
= XCreateGC (dpy
, FRAME_MAC_WINDOW (f
),
5047 GCForeground
, &xgcv
);
5048 gc
= dpyinfo
->scratch_cursor_gc
;
5050 /* Set clipping, draw the rectangle, and reset clipping again. */
5051 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5052 mac_draw_rectangle (f
, gc
, x
, y
, wd
, h
- 1);
5053 mac_reset_clip_rectangles (dpy
, gc
);
5057 /* Draw a bar cursor on window W in glyph row ROW.
5059 Implementation note: One would like to draw a bar cursor with an
5060 angle equal to the one given by the font property XA_ITALIC_ANGLE.
5061 Unfortunately, I didn't find a font yet that has this property set.
5065 x_draw_bar_cursor (w
, row
, width
, kind
)
5067 struct glyph_row
*row
;
5069 enum text_cursor_kinds kind
;
5071 struct frame
*f
= XFRAME (w
->frame
);
5072 struct glyph
*cursor_glyph
;
5074 /* If cursor is out of bounds, don't draw garbage. This can happen
5075 in mini-buffer windows when switching between echo area glyphs
5077 cursor_glyph
= get_phys_cursor_glyph (w
);
5078 if (cursor_glyph
== NULL
)
5081 /* If on an image, draw like a normal cursor. That's usually better
5082 visible than drawing a bar, esp. if the image is large so that
5083 the bar might not be in the window. */
5084 if (cursor_glyph
->type
== IMAGE_GLYPH
)
5086 struct glyph_row
*row
;
5087 row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
);
5088 draw_phys_cursor_glyph (w
, row
, DRAW_CURSOR
);
5092 Display
*dpy
= FRAME_MAC_DISPLAY (f
);
5093 Window window
= FRAME_MAC_WINDOW (f
);
5094 GC gc
= FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
;
5095 unsigned long mask
= GCForeground
| GCBackground
;
5096 struct face
*face
= FACE_FROM_ID (f
, cursor_glyph
->face_id
);
5099 /* If the glyph's background equals the color we normally draw
5100 the bar cursor in, the bar cursor in its normal color is
5101 invisible. Use the glyph's foreground color instead in this
5102 case, on the assumption that the glyph's colors are chosen so
5103 that the glyph is legible. */
5104 if (face
->background
== f
->output_data
.mac
->cursor_pixel
)
5105 xgcv
.background
= xgcv
.foreground
= face
->foreground
;
5107 xgcv
.background
= xgcv
.foreground
= f
->output_data
.mac
->cursor_pixel
;
5110 XChangeGC (dpy
, gc
, mask
, &xgcv
);
5113 gc
= XCreateGC (dpy
, window
, mask
, &xgcv
);
5114 FRAME_MAC_DISPLAY_INFO (f
)->scratch_cursor_gc
= gc
;
5118 width
= FRAME_CURSOR_WIDTH (f
);
5119 width
= min (cursor_glyph
->pixel_width
, width
);
5121 w
->phys_cursor_width
= width
;
5122 x_clip_to_row (w
, row
, TEXT_AREA
, gc
);
5124 if (kind
== BAR_CURSOR
)
5125 mac_fill_rectangle (f
, gc
,
5126 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5127 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
),
5128 width
, row
->height
);
5130 mac_fill_rectangle (f
, gc
,
5131 WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, w
->phys_cursor
.x
),
5132 WINDOW_TO_FRAME_PIXEL_Y (w
, w
->phys_cursor
.y
+
5133 row
->height
- width
),
5134 cursor_glyph
->pixel_width
,
5137 mac_reset_clip_rectangles (dpy
, gc
);
5142 /* RIF: Define cursor CURSOR on frame F. */
5145 mac_define_frame_cursor (f
, cursor
)
5149 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5151 if (dpyinfo
->x_focus_frame
== f
)
5152 SetThemeCursor (cursor
);
5156 /* RIF: Clear area on frame F. */
5159 mac_clear_frame_area (f
, x
, y
, width
, height
)
5161 int x
, y
, width
, height
;
5163 mac_clear_area (f
, x
, y
, width
, height
);
5167 /* RIF: Draw cursor on window W. */
5170 mac_draw_window_cursor (w
, glyph_row
, x
, y
, cursor_type
, cursor_width
, on_p
, active_p
)
5172 struct glyph_row
*glyph_row
;
5174 int cursor_type
, cursor_width
;
5179 w
->phys_cursor_type
= cursor_type
;
5180 w
->phys_cursor_on_p
= 1;
5182 if (glyph_row
->exact_window_width_line_p
5183 && w
->phys_cursor
.hpos
>= glyph_row
->used
[TEXT_AREA
])
5185 glyph_row
->cursor_in_fringe_p
= 1;
5186 draw_fringe_bitmap (w
, glyph_row
, 0);
5189 switch (cursor_type
)
5191 case HOLLOW_BOX_CURSOR
:
5192 x_draw_hollow_cursor (w
, glyph_row
);
5195 case FILLED_BOX_CURSOR
:
5196 draw_phys_cursor_glyph (w
, glyph_row
, DRAW_CURSOR
);
5200 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, BAR_CURSOR
);
5204 x_draw_bar_cursor (w
, glyph_row
, cursor_width
, HBAR_CURSOR
);
5208 w
->phys_cursor_width
= 0;
5220 #if 0 /* MAC_TODO: no icon support yet. */
5222 x_bitmap_icon (f
, icon
)
5228 if (FRAME_W32_WINDOW (f
) == 0)
5232 hicon
= LoadIcon (hinst
, EMACS_CLASS
);
5233 else if (STRINGP (icon
))
5234 hicon
= LoadImage (NULL
, (LPCTSTR
) SDATA (icon
), IMAGE_ICON
, 0, 0,
5235 LR_DEFAULTSIZE
| LR_LOADFROMFILE
);
5236 else if (SYMBOLP (icon
))
5240 if (EQ (icon
, intern ("application")))
5241 name
= (LPCTSTR
) IDI_APPLICATION
;
5242 else if (EQ (icon
, intern ("hand")))
5243 name
= (LPCTSTR
) IDI_HAND
;
5244 else if (EQ (icon
, intern ("question")))
5245 name
= (LPCTSTR
) IDI_QUESTION
;
5246 else if (EQ (icon
, intern ("exclamation")))
5247 name
= (LPCTSTR
) IDI_EXCLAMATION
;
5248 else if (EQ (icon
, intern ("asterisk")))
5249 name
= (LPCTSTR
) IDI_ASTERISK
;
5250 else if (EQ (icon
, intern ("winlogo")))
5251 name
= (LPCTSTR
) IDI_WINLOGO
;
5255 hicon
= LoadIcon (NULL
, name
);
5263 PostMessage (FRAME_W32_WINDOW (f
), WM_SETICON
, (WPARAM
) ICON_BIG
,
5268 #endif /* MAC_TODO */
5270 /************************************************************************
5272 ************************************************************************/
5274 /* Display Error Handling functions not used on W32. Listing them here
5275 helps diff stay in step when comparing w32term.c with xterm.c.
5277 x_error_catcher (display, error)
5278 x_catch_errors (dpy)
5279 x_catch_errors_unwind (old_val)
5280 x_check_errors (dpy, format)
5281 x_had_errors_p (dpy)
5282 x_clear_errors (dpy)
5283 x_uncatch_errors (dpy, count)
5285 x_connection_signal (signalnum)
5286 x_connection_closed (dpy, error_message)
5287 x_error_quitter (display, error)
5288 x_error_handler (display, error)
5289 x_io_error_quitter (display)
5294 /* Changing the font of the frame. */
5296 /* Give frame F the font named FONTNAME as its default font, and
5297 return the full name of that font. FONTNAME may be a wildcard
5298 pattern; in that case, we choose some font that fits the pattern.
5299 The return value shows which font we chose. */
5302 x_new_font (f
, fontname
)
5304 register char *fontname
;
5306 struct font_info
*fontp
5307 = FS_LOAD_FONT (f
, 0, fontname
, -1);
5312 FRAME_FONT (f
) = (XFontStruct
*) (fontp
->font
);
5313 FRAME_BASELINE_OFFSET (f
) = fontp
->baseline_offset
;
5314 FRAME_FONTSET (f
) = -1;
5316 FRAME_COLUMN_WIDTH (f
) = fontp
->average_width
;
5317 FRAME_SPACE_WIDTH (f
) = fontp
->space_width
;
5318 FRAME_LINE_HEIGHT (f
) = FONT_HEIGHT (FRAME_FONT (f
));
5320 compute_fringe_widths (f
, 1);
5322 /* Compute the scroll bar width in character columns. */
5323 if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) > 0)
5325 int wid
= FRAME_COLUMN_WIDTH (f
);
5326 FRAME_CONFIG_SCROLL_BAR_COLS (f
)
5327 = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f
) + wid
-1) / wid
;
5331 int wid
= FRAME_COLUMN_WIDTH (f
);
5332 FRAME_CONFIG_SCROLL_BAR_COLS (f
) = (14 + wid
- 1) / wid
;
5335 /* Now make the frame display the given font. */
5336 if (FRAME_MAC_WINDOW (f
) != 0)
5338 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->normal_gc
,
5340 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->reverse_gc
,
5342 XSetFont (FRAME_MAC_DISPLAY (f
), f
->output_data
.mac
->cursor_gc
,
5345 /* Don't change the size of a tip frame; there's no point in
5346 doing it because it's done in Fx_show_tip, and it leads to
5347 problems because the tip frame has no widget. */
5348 if (NILP (tip_frame
) || XFRAME (tip_frame
) != f
)
5349 x_set_window_size (f
, 0, FRAME_COLS (f
), FRAME_LINES (f
));
5352 return build_string (fontp
->full_name
);
5355 /* Give frame F the fontset named FONTSETNAME as its default font, and
5356 return the full name of that fontset. FONTSETNAME may be a wildcard
5357 pattern; in that case, we choose some fontset that fits the pattern.
5358 The return value shows which fontset we chose. */
5361 x_new_fontset (f
, fontsetname
)
5365 int fontset
= fs_query_fontset (build_string (fontsetname
), 0);
5371 if (FRAME_FONTSET (f
) == fontset
)
5372 /* This fontset is already set in frame F. There's nothing more
5374 return fontset_name (fontset
);
5376 result
= x_new_font (f
, (SDATA (fontset_ascii (fontset
))));
5378 if (!STRINGP (result
))
5379 /* Can't load ASCII font. */
5382 /* Since x_new_font doesn't update any fontset information, do it now. */
5383 FRAME_FONTSET (f
) = fontset
;
5385 return build_string (fontsetname
);
5389 /***********************************************************************
5390 TODO: W32 Input Methods
5391 ***********************************************************************/
5392 /* Listing missing functions from xterm.c helps diff stay in step.
5394 xim_destroy_callback (xim, client_data, call_data)
5395 xim_open_dpy (dpyinfo, resource_name)
5397 xim_instantiate_callback (display, client_data, call_data)
5398 xim_initialize (dpyinfo, resource_name)
5399 xim_close_dpy (dpyinfo)
5405 mac_handle_origin_change (f
)
5408 x_real_positions (f
, &f
->left_pos
, &f
->top_pos
);
5412 mac_handle_size_change (f
, pixelwidth
, pixelheight
)
5414 int pixelwidth
, pixelheight
;
5418 cols
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, pixelwidth
);
5419 rows
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, pixelheight
);
5421 if (cols
!= FRAME_COLS (f
)
5422 || rows
!= FRAME_LINES (f
)
5423 || pixelwidth
!= FRAME_PIXEL_WIDTH (f
)
5424 || pixelheight
!= FRAME_PIXEL_HEIGHT (f
))
5426 /* We pass 1 for DELAY since we can't run Lisp code inside of
5428 change_frame_size (f
, rows
, cols
, 0, 1, 0);
5429 FRAME_PIXEL_WIDTH (f
) = pixelwidth
;
5430 FRAME_PIXEL_HEIGHT (f
) = pixelheight
;
5431 SET_FRAME_GARBAGED (f
);
5433 /* If cursor was outside the new size, mark it as off. */
5434 mark_window_cursors_off (XWINDOW (f
->root_window
));
5436 /* Clear out any recollection of where the mouse highlighting
5437 was, since it might be in a place that's outside the new
5438 frame size. Actually checking whether it is outside is a
5439 pain in the neck, so don't try--just let the highlighting be
5440 done afresh with new size. */
5441 cancel_mouse_face (f
);
5443 #if TARGET_API_MAC_CARBON
5444 mac_reposition_hourglass (f
);
5450 /* Calculate the absolute position in frame F
5451 from its current recorded position values and gravity. */
5454 x_calc_absolute_position (f
)
5457 int width_diff
= 0, height_diff
= 0;
5458 int flags
= f
->size_hint_flags
;
5461 /* We have nothing to do if the current position
5462 is already for the top-left corner. */
5463 if (! ((flags
& XNegative
) || (flags
& YNegative
)))
5466 /* Find the offsets of the outside upper-left corner of
5467 the inner window, with respect to the outer window. */
5469 mac_get_window_bounds (f
, &inner
, &outer
);
5472 width_diff
= (outer
.right
- outer
.left
) - (inner
.right
- inner
.left
);
5473 height_diff
= (outer
.bottom
- outer
.top
) - (inner
.bottom
- inner
.top
);
5475 /* Treat negative positions as relative to the leftmost bottommost
5476 position that fits on the screen. */
5477 if (flags
& XNegative
)
5478 f
->left_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->width
5480 - FRAME_PIXEL_WIDTH (f
)
5483 if (flags
& YNegative
)
5484 f
->top_pos
= (FRAME_MAC_DISPLAY_INFO (f
)->height
5486 - FRAME_PIXEL_HEIGHT (f
)
5489 /* The left_pos and top_pos
5490 are now relative to the top and left screen edges,
5491 so the flags should correspond. */
5492 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5495 /* CHANGE_GRAVITY is 1 when calling from Fset_frame_position,
5496 to really change the position, and 0 when calling from
5497 x_make_frame_visible (in that case, XOFF and YOFF are the current
5498 position values). It is -1 when calling from x_set_frame_parameters,
5499 which means, do adjust for borders but don't change the gravity. */
5502 x_set_offset (f
, xoff
, yoff
, change_gravity
)
5504 register int xoff
, yoff
;
5507 if (change_gravity
> 0)
5511 f
->size_hint_flags
&= ~ (XNegative
| YNegative
);
5513 f
->size_hint_flags
|= XNegative
;
5515 f
->size_hint_flags
|= YNegative
;
5516 f
->win_gravity
= NorthWestGravity
;
5518 x_calc_absolute_position (f
);
5521 x_wm_set_size_hint (f
, (long) 0, 0);
5523 #if TARGET_API_MAC_CARBON
5524 mac_move_window_structure (FRAME_MAC_WINDOW (f
), f
->left_pos
, f
->top_pos
);
5525 /* If the title bar is completely outside the screen, adjust the
5527 ConstrainWindowToScreen (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
,
5528 kWindowConstrainMoveRegardlessOfFit
5529 | kWindowConstrainAllowPartial
, NULL
, NULL
);
5530 if (!NILP (tip_frame
) && XFRAME (tip_frame
) == f
)
5531 mac_handle_origin_change (f
);
5534 Rect inner
, outer
, screen_rect
, dummy
;
5535 RgnHandle region
= NewRgn ();
5537 mac_get_window_bounds (f
, &inner
, &outer
);
5538 f
->x_pixels_diff
= inner
.left
- outer
.left
;
5539 f
->y_pixels_diff
= inner
.top
- outer
.top
;
5540 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5541 f
->top_pos
+ f
->y_pixels_diff
, false);
5543 /* If the title bar is completely outside the screen, adjust the
5544 position. The variable `outer' holds the title bar rectangle.
5545 The variable `inner' holds slightly smaller one than `outer',
5546 so that the calculation of overlapping may not become too
5548 GetWindowRegion (FRAME_MAC_WINDOW (f
), kWindowTitleBarRgn
, region
);
5549 outer
= (*region
)->rgnBBox
;
5550 DisposeRgn (region
);
5552 InsetRect (&inner
, 8, 8);
5553 screen_rect
= qd
.screenBits
.bounds
;
5554 screen_rect
.top
+= GetMBarHeight ();
5556 if (!SectRect (&inner
, &screen_rect
, &dummy
))
5558 if (inner
.right
<= screen_rect
.left
)
5559 f
->left_pos
= screen_rect
.left
;
5560 else if (inner
.left
>= screen_rect
.right
)
5561 f
->left_pos
= screen_rect
.right
- (outer
.right
- outer
.left
);
5563 if (inner
.bottom
<= screen_rect
.top
)
5564 f
->top_pos
= screen_rect
.top
;
5565 else if (inner
.top
>= screen_rect
.bottom
)
5566 f
->top_pos
= screen_rect
.bottom
- (outer
.bottom
- outer
.top
);
5568 MoveWindow (FRAME_MAC_WINDOW (f
), f
->left_pos
+ f
->x_pixels_diff
,
5569 f
->top_pos
+ f
->y_pixels_diff
, false);
5577 /* Call this to change the size of frame F's x-window.
5578 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5579 for this size change and subsequent size changes.
5580 Otherwise we leave the window gravity unchanged. */
5583 x_set_window_size (f
, change_gravity
, cols
, rows
)
5588 int pixelwidth
, pixelheight
;
5592 check_frame_size (f
, &rows
, &cols
);
5593 f
->scroll_bar_actual_width
5594 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
5596 compute_fringe_widths (f
, 0);
5598 pixelwidth
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, cols
);
5599 pixelheight
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, rows
);
5601 f
->win_gravity
= NorthWestGravity
;
5602 x_wm_set_size_hint (f
, (long) 0, 0);
5604 mac_size_window (FRAME_MAC_WINDOW (f
), pixelwidth
, pixelheight
, 0);
5606 #if TARGET_API_MAC_CARBON
5607 if (!NILP (tip_frame
) && f
== XFRAME (tip_frame
))
5609 mac_handle_size_change (f
, pixelwidth
, pixelheight
);
5611 if (f
->output_data
.mac
->internal_border_width
5612 != FRAME_INTERNAL_BORDER_WIDTH (f
))
5614 mac_clear_window (f
);
5615 f
->output_data
.mac
->internal_border_width
5616 = FRAME_INTERNAL_BORDER_WIDTH (f
);
5619 SET_FRAME_GARBAGED (f
);
5624 /* Mouse warping. */
5626 void x_set_mouse_pixel_position (struct frame
*f
, int pix_x
, int pix_y
);
5629 x_set_mouse_position (f
, x
, y
)
5635 pix_x
= FRAME_COL_TO_PIXEL_X (f
, x
) + FRAME_COLUMN_WIDTH (f
) / 2;
5636 pix_y
= FRAME_LINE_TO_PIXEL_Y (f
, y
) + FRAME_LINE_HEIGHT (f
) / 2;
5638 if (pix_x
< 0) pix_x
= 0;
5639 if (pix_x
> FRAME_PIXEL_WIDTH (f
)) pix_x
= FRAME_PIXEL_WIDTH (f
);
5641 if (pix_y
< 0) pix_y
= 0;
5642 if (pix_y
> FRAME_PIXEL_HEIGHT (f
)) pix_y
= FRAME_PIXEL_HEIGHT (f
);
5644 x_set_mouse_pixel_position (f
, pix_x
, pix_y
);
5648 x_set_mouse_pixel_position (f
, pix_x
, pix_y
)
5654 mac_convert_frame_point_to_global (f
, &pix_x
, &pix_y
);
5655 CGWarpMouseCursorPosition (CGPointMake (pix_x
, pix_y
));
5658 #if 0 /* MAC_TODO: LMSetMouseLocation and CursorDeviceMoveTo are non-Carbon */
5661 XWarpPointer (FRAME_X_DISPLAY (f
), None
, FRAME_X_WINDOW (f
),
5662 0, 0, 0, 0, pix_x
, pix_y
);
5668 /* focus shifting, raising and lowering. */
5671 x_focus_on_frame (f
)
5674 #if 0 /* This proves to be unpleasant. */
5678 /* I don't think that the ICCCM allows programs to do things like this
5679 without the interaction of the window manager. Whatever you end up
5680 doing with this code, do it to x_unfocus_frame too. */
5681 XSetInputFocus (FRAME_X_DISPLAY (f
), FRAME_X_WINDOW (f
),
5682 RevertToPointerRoot
, CurrentTime
);
5692 /* Raise frame F. */
5698 if (f
->async_visible
)
5701 mac_bring_window_to_front (FRAME_MAC_WINDOW (f
));
5706 /* Lower frame F. */
5712 if (f
->async_visible
)
5715 mac_send_window_behind (FRAME_MAC_WINDOW (f
), NULL
);
5721 XTframe_raise_lower (f
, raise_flag
)
5731 /* Change of visibility. */
5734 mac_handle_visibility_change (f
)
5737 Window wp
= FRAME_MAC_WINDOW (f
);
5738 int visible
= 0, iconified
= 0;
5739 struct input_event buf
;
5741 if (mac_is_window_visible (wp
))
5743 if (mac_is_window_collapsed (wp
))
5749 if (!f
->async_visible
&& visible
)
5753 /* wait_reading_process_output will notice this and update
5754 the frame's display structures. If we were made
5755 invisible, we should not set garbaged, because that stops
5756 redrawing on Update events. */
5757 SET_FRAME_GARBAGED (f
);
5760 buf
.kind
= DEICONIFY_EVENT
;
5761 XSETFRAME (buf
.frame_or_window
, f
);
5763 kbd_buffer_store_event (&buf
);
5765 else if (! NILP (Vframe_list
) && ! NILP (XCDR (Vframe_list
)))
5766 /* Force a redisplay sooner or later to update the
5767 frame titles in case this is the second frame. */
5768 record_asynch_buffer_change ();
5770 else if (f
->async_visible
&& !visible
)
5774 buf
.kind
= ICONIFY_EVENT
;
5775 XSETFRAME (buf
.frame_or_window
, f
);
5777 kbd_buffer_store_event (&buf
);
5780 f
->async_visible
= visible
;
5781 f
->async_iconified
= iconified
;
5784 /* This tries to wait until the frame is really visible.
5785 However, if the window manager asks the user where to position
5786 the frame, this will return before the user finishes doing that.
5787 The frame will not actually be visible at that time,
5788 but it will become visible later when the window manager
5789 finishes with it. */
5792 x_make_frame_visible (f
)
5797 if (! FRAME_VISIBLE_P (f
))
5799 /* We test FRAME_GARBAGED_P here to make sure we don't
5800 call x_set_offset a second time
5801 if we get to x_make_frame_visible a second time
5802 before the window gets really visible. */
5803 if (! FRAME_ICONIFIED_P (f
)
5804 && ! f
->output_data
.mac
->asked_for_visible
)
5805 x_set_offset (f
, f
->left_pos
, f
->top_pos
, 0);
5807 f
->output_data
.mac
->asked_for_visible
= 1;
5809 mac_collapse_window (FRAME_MAC_WINDOW (f
), false);
5810 mac_show_window (FRAME_MAC_WINDOW (f
));
5813 XFlush (FRAME_MAC_DISPLAY (f
));
5815 /* Synchronize to ensure Emacs knows the frame is visible
5816 before we do anything else. We do this loop with input not blocked
5817 so that incoming events are handled. */
5822 /* This must come after we set COUNT. */
5825 XSETFRAME (frame
, f
);
5827 /* Wait until the frame is visible. Process X events until a
5828 MapNotify event has been seen, or until we think we won't get a
5829 MapNotify at all.. */
5830 for (count
= input_signal_count
+ 10;
5831 input_signal_count
< count
&& !FRAME_VISIBLE_P (f
);)
5833 /* Force processing of queued events. */
5836 /* Machines that do polling rather than SIGIO have been
5837 observed to go into a busy-wait here. So we'll fake an
5838 alarm signal to let the handler know that there's something
5839 to be read. We used to raise a real alarm, but it seems
5840 that the handler isn't always enabled here. This is
5842 if (input_polling_used ())
5844 /* It could be confusing if a real alarm arrives while
5845 processing the fake one. Turn it off and let the
5846 handler reset it. */
5847 extern void poll_for_input_1
P_ ((void));
5848 int old_poll_suppress_count
= poll_suppress_count
;
5849 poll_suppress_count
= 1;
5850 poll_for_input_1 ();
5851 poll_suppress_count
= old_poll_suppress_count
;
5854 /* See if a MapNotify event has been processed. */
5855 FRAME_SAMPLE_VISIBILITY (f
);
5860 /* Change from mapped state to withdrawn state. */
5862 /* Make the frame visible (mapped and not iconified). */
5865 x_make_frame_invisible (f
)
5868 /* A deactivate event does not occur when the last visible frame is
5869 made invisible. So if we clear the highlight here, it will not
5870 be rehighlighted when it is made visible. */
5872 /* Don't keep the highlight on an invisible frame. */
5873 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5874 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5879 #if !TARGET_API_MAC_CARBON
5880 /* Before unmapping the window, update the WM_SIZE_HINTS property to claim
5881 that the current position of the window is user-specified, rather than
5882 program-specified, so that when the window is mapped again, it will be
5883 placed at the same location, without forcing the user to position it
5884 by hand again (they have already done that once for this window.) */
5885 x_wm_set_size_hint (f
, (long) 0, 1);
5888 mac_hide_window (FRAME_MAC_WINDOW (f
));
5892 #if !TARGET_API_MAC_CARBON
5893 mac_handle_visibility_change (f
);
5897 /* Change window state from mapped to iconified. */
5905 /* A deactivate event does not occur when the last visible frame is
5906 iconified. So if we clear the highlight here, it will not be
5907 rehighlighted when it is deiconified. */
5909 /* Don't keep the highlight on an invisible frame. */
5910 if (FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
== f
)
5911 FRAME_MAC_DISPLAY_INFO (f
)->x_highlight_frame
= 0;
5914 if (f
->async_iconified
)
5919 FRAME_SAMPLE_VISIBILITY (f
);
5921 if (! FRAME_VISIBLE_P (f
))
5922 mac_show_window (FRAME_MAC_WINDOW (f
));
5924 err
= mac_collapse_window (FRAME_MAC_WINDOW (f
), true);
5929 error ("Can't notify window manager of iconification");
5931 #if !TARGET_API_MAC_CARBON
5932 mac_handle_visibility_change (f
);
5937 /* Free X resources of frame F. */
5940 x_free_frame_resources (f
)
5943 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
5944 Window wp
= FRAME_MAC_WINDOW (f
);
5948 /* AppKit version of mac_dispose_frame_window, which is implemented
5949 as -[NSWindow close], will change the focus to the next window
5950 during its call. So, unlike other platforms, we clean up the
5951 focus-related variables before calling mac_dispose_frame_window. */
5952 if (f
== dpyinfo
->x_focus_frame
)
5954 dpyinfo
->x_focus_frame
= 0;
5955 #if USE_MAC_FONT_PANEL
5956 mac_set_font_info_for_selection (NULL
, DEFAULT_FACE_ID
, 0);
5959 if (f
== dpyinfo
->x_focus_event_frame
)
5960 dpyinfo
->x_focus_event_frame
= 0;
5961 if (f
== dpyinfo
->x_highlight_frame
)
5962 dpyinfo
->x_highlight_frame
= 0;
5964 if (f
== dpyinfo
->mouse_face_mouse_frame
)
5966 dpyinfo
->mouse_face_beg_row
5967 = dpyinfo
->mouse_face_beg_col
= -1;
5968 dpyinfo
->mouse_face_end_row
5969 = dpyinfo
->mouse_face_end_col
= -1;
5970 dpyinfo
->mouse_face_window
= Qnil
;
5971 dpyinfo
->mouse_face_deferred_gc
= 0;
5972 dpyinfo
->mouse_face_mouse_frame
= 0;
5975 mac_dispose_frame_window (f
);
5976 if (wp
== tip_window
)
5977 /* Neither WaitNextEvent nor ReceiveNextEvent receives `window
5978 closed' event. So we reset tip_window here. */
5981 free_frame_menubar (f
);
5983 if (FRAME_FACE_CACHE (f
))
5984 free_frame_faces (f
);
5988 if (FRAME_SIZE_HINTS (f
))
5989 xfree (FRAME_SIZE_HINTS (f
));
5991 xfree (f
->output_data
.mac
);
5992 f
->output_data
.mac
= NULL
;
5998 /* Destroy the X window of frame F. */
6001 x_destroy_window (f
)
6004 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
6006 x_free_frame_resources (f
);
6008 dpyinfo
->reference_count
--;
6012 /* Setting window manager hints. */
6014 /* Set the normal size hints for the window manager, for frame F.
6015 FLAGS is the flags word to use--or 0 meaning preserve the flags
6016 that the window now has.
6017 If USER_POSITION is nonzero, we set the USPosition
6018 flag (this is useful when FLAGS is 0). */
6020 x_wm_set_size_hint (f
, flags
, user_position
)
6025 int base_width
, base_height
, width_inc
, height_inc
;
6026 int min_rows
= 0, min_cols
= 0;
6027 XSizeHints
*size_hints
;
6029 base_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, 0);
6030 base_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, 0);
6031 width_inc
= FRAME_COLUMN_WIDTH (f
);
6032 height_inc
= FRAME_LINE_HEIGHT (f
);
6034 check_frame_size (f
, &min_rows
, &min_cols
);
6036 size_hints
= FRAME_SIZE_HINTS (f
);
6037 if (size_hints
== NULL
)
6039 size_hints
= FRAME_SIZE_HINTS (f
) = xmalloc (sizeof (XSizeHints
));
6040 bzero (size_hints
, sizeof (XSizeHints
));
6043 size_hints
->flags
|= PResizeInc
| PMinSize
| PBaseSize
;
6044 size_hints
->width_inc
= width_inc
;
6045 size_hints
->height_inc
= height_inc
;
6046 size_hints
->min_width
= base_width
+ min_cols
* width_inc
;
6047 size_hints
->min_height
= base_height
+ min_rows
* height_inc
;
6048 size_hints
->base_width
= base_width
;
6049 size_hints
->base_height
= base_height
;
6052 size_hints
->flags
= flags
;
6053 else if (user_position
)
6055 size_hints
->flags
&= ~ PPosition
;
6056 size_hints
->flags
|= USPosition
;
6060 #if 0 /* MAC_TODO: hide application instead of iconify? */
6061 /* Used for IconicState or NormalState */
6064 x_wm_set_window_state (f
, state
)
6068 #ifdef USE_X_TOOLKIT
6071 XtSetArg (al
[0], XtNinitialState
, state
);
6072 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6073 #else /* not USE_X_TOOLKIT */
6074 Window window
= FRAME_X_WINDOW (f
);
6076 f
->output_data
.x
->wm_hints
.flags
|= StateHint
;
6077 f
->output_data
.x
->wm_hints
.initial_state
= state
;
6079 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6080 #endif /* not USE_X_TOOLKIT */
6084 x_wm_set_icon_pixmap (f
, pixmap_id
)
6090 #ifndef USE_X_TOOLKIT
6091 Window window
= FRAME_X_WINDOW (f
);
6096 icon_pixmap
= x_bitmap_pixmap (f
, pixmap_id
);
6097 f
->output_data
.x
->wm_hints
.icon_pixmap
= icon_pixmap
;
6101 /* It seems there is no way to turn off use of an icon pixmap.
6102 The following line does it, only if no icon has yet been created,
6103 for some window managers. But with mwm it crashes.
6104 Some people say it should clear the IconPixmapHint bit in this case,
6105 but that doesn't work, and the X consortium said it isn't the
6106 right thing at all. Since there is no way to win,
6107 best to explicitly give up. */
6109 f
->output_data
.x
->wm_hints
.icon_pixmap
= None
;
6115 #ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */
6119 XtSetArg (al
[0], XtNiconPixmap
, icon_pixmap
);
6120 XtSetValues (f
->output_data
.x
->widget
, al
, 1);
6123 #else /* not USE_X_TOOLKIT */
6125 f
->output_data
.x
->wm_hints
.flags
|= IconPixmapHint
;
6126 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6128 #endif /* not USE_X_TOOLKIT */
6131 #endif /* MAC_TODO */
6134 x_wm_set_icon_position (f
, icon_x
, icon_y
)
6138 #if 0 /* MAC_TODO: no icons on Mac */
6139 #ifdef USE_X_TOOLKIT
6140 Window window
= XtWindow (f
->output_data
.x
->widget
);
6142 Window window
= FRAME_X_WINDOW (f
);
6145 f
->output_data
.x
->wm_hints
.flags
|= IconPositionHint
;
6146 f
->output_data
.x
->wm_hints
.icon_x
= icon_x
;
6147 f
->output_data
.x
->wm_hints
.icon_y
= icon_y
;
6149 XSetWMHints (FRAME_X_DISPLAY (f
), window
, &f
->output_data
.x
->wm_hints
);
6150 #endif /* MAC_TODO */
6154 /***********************************************************************
6156 ***********************************************************************/
6158 /* An XLFD pattern is divided into blocks delimited by '*'. This
6159 structure holds information for each block. */
6160 struct xlfdpat_block
6162 /* Length of the pattern string in this block. Non-zero except for
6163 the first and the last blocks. */
6166 /* Pattern string except the last character in this block. The last
6167 character is replaced with NUL in order to use it as a
6169 unsigned char *pattern
;
6171 /* Last character of the pattern string. Must not be '?'. */
6172 unsigned char last_char
;
6174 /* One of the tables for the Boyer-Moore string search. It
6175 specifies the number of positions to proceed for each character
6176 with which the match fails. */
6179 /* The skip value for the last character in the above `skip' is
6180 assigned to `infinity' in order to simplify a loop condition.
6181 The original value is saved here. */
6187 /* Normalized pattern string. "Normalized" means that capital
6188 letters are lowered, blocks are not empty except the first and
6189 the last ones, and trailing '?'s in a block that is not the last
6190 one are moved to the next one. The last character in each block
6191 is replaced with NUL. */
6194 /* Number of characters except '*'s and trailing '?'s in the
6195 normalized pattern string. */
6198 /* Number of trailing '?'s in the normalized pattern string. */
6199 int trailing_anychars
;
6201 /* Number of blocks and information for each block. The latter is
6202 NULL if the pattern is exact (no '*' or '?' in it). */
6204 struct xlfdpat_block
*blocks
;
6208 xlfdpat_destroy (pat
)
6209 struct xlfdpat
*pat
;
6216 xfree (pat
->blocks
);
6223 static struct xlfdpat
*
6224 xlfdpat_create (pattern
)
6225 const char *pattern
;
6227 struct xlfdpat
*pat
;
6228 int nblocks
, i
, skip
;
6229 unsigned char last_char
, *p
, *q
, *anychar_head
;
6230 const unsigned char *ptr
;
6231 struct xlfdpat_block
*blk
;
6233 pat
= xmalloc (sizeof (struct xlfdpat
));
6234 pat
->buf
= xmalloc (strlen (pattern
) + 1);
6236 /* Normalize the pattern string and store it to `pat->buf'. */
6238 anychar_head
= NULL
;
6241 for (ptr
= pattern
; *ptr
; ptr
++)
6243 unsigned char c
= *ptr
;
6246 if (last_char
== '*')
6247 /* ...a** -> ...a* */
6251 if (last_char
== '?')
6253 if (anychar_head
> pat
->buf
&& *(anychar_head
- 1) == '*')
6254 /* ...*??* -> ...*?? */
6257 /* ...a??* -> ...a*?? */
6259 *anychar_head
++ = '*';
6267 if (last_char
!= '?')
6271 /* On Mac OS X 10.3, tolower also converts non-ASCII
6272 characters for some locales. */
6276 *q
++ = last_char
= c
;
6280 pat
->nblocks
= nblocks
;
6281 if (last_char
!= '?')
6282 pat
->trailing_anychars
= 0;
6285 pat
->trailing_anychars
= q
- anychar_head
;
6288 pat
->nchars
= q
- pat
->buf
- (nblocks
- 1);
6290 if (anychar_head
== NULL
&& nblocks
== 1)
6292 /* The pattern is exact. */
6297 pat
->blocks
= xmalloc (sizeof (struct xlfdpat_block
) * nblocks
);
6299 /* Divide the normalized pattern into blocks. */
6301 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
- 1; blk
++)
6306 blk
->len
= p
- blk
->pattern
;
6310 blk
->len
= q
- blk
->pattern
;
6312 /* Setup a table for the Boyer-Moore string search. */
6313 for (blk
= pat
->blocks
; blk
< pat
->blocks
+ nblocks
; blk
++)
6316 blk
->last_char
= blk
->pattern
[blk
->len
- 1];
6317 blk
->pattern
[blk
->len
- 1] = '\0';
6319 for (skip
= 1; skip
< blk
->len
; skip
++)
6320 if (blk
->pattern
[blk
->len
- skip
- 1] == '?')
6323 for (i
= 0; i
< 256; i
++)
6324 blk
->skip
[i
] = skip
;
6326 p
= blk
->pattern
+ (blk
->len
- skip
);
6328 blk
->skip
[*p
++] = skip
;
6330 blk
->last_char_skip
= blk
->skip
[blk
->last_char
];
6337 xlfdpat_exact_p (pat
)
6338 struct xlfdpat
*pat
;
6340 return pat
->blocks
== NULL
;
6343 /* Return the first string in STRING + 0, ..., STRING + START_MAX such
6344 that the pattern in *BLK matches with its prefix. Return NULL
6345 there is no such strings. STRING must be lowered in advance. */
6348 xlfdpat_block_match_1 (blk
, string
, start_max
)
6349 struct xlfdpat_block
*blk
;
6350 const unsigned char *string
;
6353 int start
, infinity
;
6355 const unsigned char *s
;
6357 xassert (blk
->len
> 0);
6358 xassert (start_max
+ blk
->len
<= strlen (string
));
6359 xassert (blk
->last_char
!= '?');
6361 /* See the comments in the function `boyer_moore' (search.c) for the
6362 use of `infinity'. */
6363 infinity
= start_max
+ blk
->len
+ 1;
6364 blk
->skip
[blk
->last_char
] = infinity
;
6369 /* Check the last character of the pattern. */
6370 s
= string
+ blk
->len
- 1;
6373 start
+= blk
->skip
[*(s
+ start
)];
6375 while (start
<= start_max
);
6377 if (start
< infinity
)
6378 /* Couldn't find the last character. */
6381 /* No less than `infinity' means we could find the last
6382 character at `s[start - infinity]'. */
6385 /* Check the remaining characters. We prefer making no-'?'
6386 cases faster because the use of '?' is really rare. */
6391 while (*p
++ == *s
++)
6394 while (*(p
- 1) == '?');
6396 if (*(p
- 1) == '\0')
6398 return string
+ start
;
6401 start
+= blk
->last_char_skip
;
6403 while (start
<= start_max
);
6408 #define xlfdpat_block_match(b, s, m) \
6409 ((b)->len == 1 ? memchr ((s), (b)->last_char, (m) + 1) \
6410 : xlfdpat_block_match_1 (b, s, m))
6412 /* Check if XLFD pattern PAT, which is generated by `xlfdpat_create',
6413 matches with STRING. STRING must be lowered in advance. */
6416 xlfdpat_match (pat
, string
)
6417 struct xlfdpat
*pat
;
6418 const unsigned char *string
;
6420 int str_len
, nblocks
, i
, start_max
;
6421 struct xlfdpat_block
*blk
;
6422 const unsigned char *s
;
6424 xassert (pat
->nblocks
> 0);
6426 if (xlfdpat_exact_p (pat
))
6427 return strcmp (pat
->buf
, string
) == 0;
6429 /* The number of the characters in the string must not be smaller
6430 than that in the pattern. */
6431 str_len
= strlen (string
);
6432 if (str_len
< pat
->nchars
+ pat
->trailing_anychars
)
6435 /* Chop off the trailing '?'s. */
6436 str_len
-= pat
->trailing_anychars
;
6438 /* The last block. When it is non-empty, it must match at the end
6440 nblocks
= pat
->nblocks
;
6441 blk
= pat
->blocks
+ (nblocks
- 1);
6443 /* The last block is also the first one. */
6444 return (str_len
== blk
->len
6445 && (blk
->len
== 0 || xlfdpat_block_match (blk
, string
, 0)));
6446 else if (blk
->len
!= 0)
6447 if (!xlfdpat_block_match (blk
, string
+ (str_len
- blk
->len
), 0))
6450 /* The first block. When it is non-empty, it must match at the
6451 beginning of the string. */
6455 s
= xlfdpat_block_match (blk
, string
, 0);
6458 string
= s
+ blk
->len
;
6461 /* The rest of the blocks. */
6462 start_max
= str_len
- pat
->nchars
;
6463 for (i
= 1, blk
++; i
< nblocks
- 1; i
++, blk
++)
6465 s
= xlfdpat_block_match (blk
, string
, start_max
);
6468 start_max
-= s
- string
;
6469 string
= s
+ blk
->len
;
6476 /***********************************************************************
6478 ***********************************************************************/
6480 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
6483 x_get_font_info (f
, font_idx
)
6487 return (FRAME_MAC_FONT_TABLE (f
) + font_idx
);
6490 /* the global font name table */
6491 static char **font_name_table
= NULL
;
6492 static int font_name_table_size
= 0;
6493 static int font_name_count
= 0;
6495 /* Alist linking font family names to Font Manager font family
6496 references (which can also be used as QuickDraw font IDs). We use
6497 an alist because hash tables are not ready when the terminal frame
6498 for Mac OS Classic is created. */
6499 static Lisp_Object fm_font_family_alist
;
6501 /* Hash table linking font family names to ATSU font IDs. */
6502 static Lisp_Object atsu_font_id_hash
;
6503 /* Alist linking Font Manager style to face attributes. */
6504 static Lisp_Object fm_style_face_attributes_alist
;
6505 extern Lisp_Object QCfamily
, QCweight
, QCslant
, Qnormal
, Qbold
, Qitalic
;
6507 #if USE_MAC_FONT_PANEL
6508 Lisp_Object Qpanel_closed
, Qselection
;
6511 /* Alist linking character set strings to Mac text encoding and Emacs
6513 static Lisp_Object Vmac_charset_info_alist
;
6516 create_text_encoding_info_alist ()
6518 Lisp_Object result
= Qnil
, rest
;
6520 for (rest
= Vmac_charset_info_alist
; CONSP (rest
); rest
= XCDR (rest
))
6522 Lisp_Object charset_info
= XCAR (rest
);
6523 Lisp_Object charset
, coding_system
, text_encoding
;
6524 Lisp_Object existing_info
;
6526 if (!(CONSP (charset_info
)
6527 && (charset
= XCAR (charset_info
),
6529 && CONSP (XCDR (charset_info
))
6530 && (text_encoding
= XCAR (XCDR (charset_info
)),
6531 INTEGERP (text_encoding
))
6532 && CONSP (XCDR (XCDR (charset_info
)))
6533 && (coding_system
= XCAR (XCDR (XCDR (charset_info
))),
6534 SYMBOLP (coding_system
))))
6537 existing_info
= assq_no_quit (text_encoding
, result
);
6538 if (NILP (existing_info
))
6539 result
= Fcons (list3 (text_encoding
, coding_system
, charset
),
6542 if (NILP (Fmember (charset
, XCDR (XCDR (existing_info
)))))
6543 XSETCDR (XCDR (existing_info
),
6544 Fcons (charset
, XCDR (XCDR (existing_info
))));
6552 decode_mac_font_name (name
, size
, coding_system
)
6555 Lisp_Object coding_system
;
6557 struct coding_system coding
;
6560 if (!NILP (coding_system
) && !NILP (Fcoding_system_p (coding_system
)))
6562 for (p
= name
; *p
; p
++)
6563 if (!isascii (*p
) || iscntrl (*p
))
6568 setup_coding_system (coding_system
, &coding
);
6569 coding
.src_multibyte
= 0;
6570 coding
.dst_multibyte
= 1;
6571 coding
.mode
|= CODING_MODE_LAST_BLOCK
;
6572 coding
.composing
= COMPOSITION_DISABLED
;
6573 buf
= (char *) alloca (size
);
6575 decode_coding (&coding
, name
, buf
, strlen (name
), size
- 1);
6576 bcopy (buf
, name
, coding
.produced
);
6577 name
[coding
.produced
] = '\0';
6581 /* If there's just one occurrence of '-' in the family name, it is
6582 replaced with '_'. (More than one occurrence of '-' means a
6583 "FOUNDRY-FAMILY-CHARSET"-style name.) */
6584 p
= strchr (name
, '-');
6585 if (p
&& strchr (p
+ 1, '-') == NULL
)
6588 for (p
= name
; *p
; p
++)
6589 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6590 for some locales. */
6597 mac_to_x_fontname (name
, size
, style
, charset
)
6605 char xf
[256], *result
;
6608 if (sscanf (name
, "%31[^-]-%255[^-]-%31s", foundry
, family
, cs
) == 3)
6612 strcpy(foundry
, "Apple");
6613 strcpy(family
, name
);
6616 sprintf (xf
, "%s-%c-normal--%d-%d-%d-%d-m-%d-%s",
6617 style
& bold
? "bold" : "medium", style
& italic
? 'i' : 'r',
6618 size
, size
* 10, size
? 72 : 0, size
? 72 : 0, size
* 10, charset
);
6620 result
= xmalloc (strlen (foundry
) + strlen (family
) + strlen (xf
) + 3 + 1);
6621 sprintf (result
, "-%s-%s-%s", foundry
, family
, xf
);
6622 for (p
= result
; *p
; p
++)
6623 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6624 for some locales. */
6631 /* Parse fully-specified and instantiated X11 font spec XF, and store
6632 the results to FAMILY, *SIZE, *STYLE, and CHARSET. Return 1 if the
6633 parsing succeeded, and 0 otherwise. For FAMILY and CHARSET, the
6634 caller must allocate at least 256 and 32 bytes respectively. For
6635 ordinary Mac fonts, the value stored to FAMILY should just be their
6636 names, like "monaco", "Taipei", etc. Fonts converted from the GNU
6637 intlfonts collection contain their charset designation in their
6638 names, like "ETL-Fixed-iso8859-1", "ETL-Fixed-koi8-r", etc. Both
6639 types of font names are handled accordingly. */
6641 const int kDefaultFontSize
= 12;
6644 parse_x_font_name (xf
, family
, size
, style
, charset
)
6651 Str31 foundry
, weight
;
6652 int point_size
, avgwidth
;
6655 if (sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]-%*[^-]-%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6656 foundry
, family
, weight
, slant
, size
,
6657 &point_size
, &avgwidth
, charset
) != 8
6658 && sscanf (xf
, "-%31[^-]-%255[^-]-%31[^-]-%1[^-]-%*[^-]--%d-%d-%*[^-]-%*[^-]-%*c-%d-%31s",
6659 foundry
, family
, weight
, slant
, size
,
6660 &point_size
, &avgwidth
, charset
) != 8)
6666 *size
= point_size
/ 10;
6667 else if (avgwidth
> 0)
6668 *size
= avgwidth
/ 10;
6671 *size
= kDefaultFontSize
;
6674 if (strcmp (weight
, "bold") == 0)
6679 if (NILP (Fassoc (build_string (charset
), Vmac_charset_info_alist
)))
6681 int foundry_len
= strlen (foundry
), family_len
= strlen (family
);
6683 if (foundry_len
+ family_len
+ strlen (charset
) + 2 < sizeof (Str255
))
6685 /* Like sprintf (family, "%s-%s-%s", foundry, family, charset),
6686 but take overlap into account. */
6687 memmove (family
+ foundry_len
+ 1, family
, family_len
);
6688 memcpy (family
, foundry
, foundry_len
);
6689 family
[foundry_len
] = '-';
6690 family
[foundry_len
+ 1 + family_len
] = '-';
6691 strcpy (family
+ foundry_len
+ 1 + family_len
+ 1, charset
);
6697 for (p
= family
; *p
; p
++)
6698 /* On Mac OS X 10.3, tolower also converts non-ASCII characters
6699 for some locales. */
6708 add_font_name_table_entry (char *font_name
)
6710 if (font_name_table_size
== 0)
6712 font_name_table_size
= 256;
6713 font_name_table
= (char **)
6714 xmalloc (font_name_table_size
* sizeof (char *));
6716 else if (font_name_count
+ 1 >= font_name_table_size
)
6718 font_name_table_size
*= 2;
6719 font_name_table
= (char **)
6720 xrealloc (font_name_table
,
6721 font_name_table_size
* sizeof (char *));
6724 font_name_table
[font_name_count
++] = font_name
;
6728 add_mac_font_name (name
, size
, style
, charset
)
6732 const char *charset
;
6735 add_font_name_table_entry (mac_to_x_fontname (name
, size
, style
, charset
));
6738 add_font_name_table_entry (mac_to_x_fontname (name
, 0, style
, charset
));
6739 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
, charset
));
6740 add_font_name_table_entry (mac_to_x_fontname (name
, 0, bold
, charset
));
6741 add_font_name_table_entry (mac_to_x_fontname (name
, 0, italic
| bold
,
6748 fm_get_style_from_font (font
)
6752 FMFontStyle style
= normal
;
6755 FMFontFamily font_family
;
6756 #define FONT_HEADER_MAC_STYLE_OFFSET (4*4 + 2*2 + 8*2 + 2*4)
6758 /* FMGetFontFamilyInstanceFromFont returns `normal' as the style of
6759 some font (e.g., Optima) even if it is `bold'. */
6760 err
= FMGetFontTable (font
, 'head', FONT_HEADER_MAC_STYLE_OFFSET
,
6761 sizeof (mac_style
), &mac_style
, &len
);
6763 && len
>= FONT_HEADER_MAC_STYLE_OFFSET
+ sizeof (mac_style
))
6764 style
= EndianU16_BtoN (mac_style
);
6766 FMGetFontFamilyInstanceFromFont (font
, &font_family
, &style
);
6772 atsu_find_font_from_family_name (family
)
6775 struct Lisp_Hash_Table
*h
= XHASH_TABLE (atsu_font_id_hash
);
6778 Lisp_Object rest
, best
;
6779 FMFontStyle min_style
, style
;
6781 i
= hash_lookup (h
, make_unibyte_string (family
, strlen (family
)),
6784 return kATSUInvalidFontID
;
6786 rest
= HASH_VALUE (h
, i
);
6787 if (INTEGERP (rest
) || (CONSP (rest
) && INTEGERP (XCDR (rest
))))
6788 return cons_to_long (rest
);
6790 rest
= Fnreverse (rest
);
6794 && (min_style
= fm_get_style_from_font (cons_to_long (best
))) != normal
)
6797 style
= fm_get_style_from_font (cons_to_long (XCAR (rest
)));
6798 if (style
< min_style
)
6801 if (style
== normal
)
6808 while (!NILP (rest
));
6810 HASH_VALUE (h
, i
) = best
;
6811 return cons_to_long (best
);
6815 fm_style_to_face_attributes (fm_style
)
6816 FMFontStyle fm_style
;
6820 fm_style
&= (bold
| italic
);
6821 tem
= assq_no_quit (make_number (fm_style
),
6822 fm_style_face_attributes_alist
);
6826 tem
= list4 (QCweight
, fm_style
& bold
? Qbold
: Qnormal
,
6827 QCslant
, fm_style
& italic
? Qitalic
: Qnormal
);
6828 fm_style_face_attributes_alist
=
6829 Fcons (Fcons (make_number (fm_style
), tem
),
6830 fm_style_face_attributes_alist
);
6836 atsu_find_font_family_name (font_id
)
6841 Lisp_Object family
= Qnil
;
6843 err
= ATSUFindFontName (font_id
, kFontFamilyName
,
6844 kFontMacintoshPlatform
, kFontNoScript
,
6845 kFontNoLanguage
, 0, NULL
, &len
, NULL
);
6848 family
= make_uninit_string (len
);
6849 err
= ATSUFindFontName (font_id
, kFontFamilyName
,
6850 kFontMacintoshPlatform
, kFontNoScript
,
6851 kFontNoLanguage
, len
, SDATA (family
),
6855 decode_mac_font_name (SDATA (family
), len
+ 1, Qnil
);
6861 mac_atsu_font_face_attributes (font_id
)
6864 Lisp_Object family
, style_attrs
;
6866 family
= atsu_find_font_family_name (font_id
);
6869 style_attrs
= fm_style_to_face_attributes (fm_get_style_from_font (font_id
));
6870 return Fcons (QCfamily
, Fcons (family
, style_attrs
));
6874 /* Sets up the table font_name_table to contain the list of all fonts
6875 in the system the first time the table is used so that the Resource
6876 Manager need not be accessed every time this information is
6880 init_font_name_table ()
6882 #if TARGET_API_MAC_CARBON
6883 FMFontFamilyIterator ffi
;
6884 FMFontFamilyInstanceIterator ffii
;
6886 Lisp_Object text_encoding_info_alist
;
6887 struct gcpro gcpro1
;
6889 text_encoding_info_alist
= create_text_encoding_info_alist ();
6892 #if USE_CG_TEXT_DRAWING
6893 init_cg_text_anti_aliasing_threshold ();
6895 if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode
),
6896 text_encoding_info_alist
)))
6899 struct Lisp_Hash_Table
*h
;
6901 ItemCount nfonts
, i
;
6902 ATSUFontID
*font_ids
= NULL
;
6903 Lisp_Object prev_family
= Qnil
;
6907 make_hash_table (Qequal
, make_number (DEFAULT_HASH_SIZE
),
6908 make_float (DEFAULT_REHASH_SIZE
),
6909 make_float (DEFAULT_REHASH_THRESHOLD
),
6911 h
= XHASH_TABLE (atsu_font_id_hash
);
6913 err
= ATSUFontCount (&nfonts
);
6916 font_ids
= xmalloc (sizeof (ATSUFontID
) * nfonts
);
6917 err
= ATSUGetFontIDs (font_ids
, nfonts
, NULL
);
6920 for (i
= 0; i
< nfonts
; i
++)
6924 family
= atsu_find_font_family_name (font_ids
[i
]);
6925 if (NILP (family
) || SREF (family
, 0) == '.')
6927 if (!NILP (Fequal (prev_family
, family
)))
6928 family
= prev_family
;
6930 j
= hash_lookup (h
, family
, &hash_code
);
6933 add_mac_font_name (SDATA (family
), 0, normal
, "iso10646-1");
6934 j
= hash_put (h
, family
, Fcons (long_to_cons (font_ids
[i
]),
6937 else if (EQ (prev_family
, family
))
6938 HASH_VALUE (h
, j
) = Fcons (long_to_cons (font_ids
[i
]),
6940 prev_family
= family
;
6947 /* Create a dummy instance iterator here to avoid creating and
6948 destroying it in the loop. */
6949 if (FMCreateFontFamilyInstanceIterator (0, &ffii
) != noErr
)
6951 /* Create an iterator to enumerate the font families. */
6952 if (FMCreateFontFamilyIterator (NULL
, NULL
, kFMDefaultOptions
, &ffi
)
6955 FMDisposeFontFamilyInstanceIterator (&ffii
);
6959 GCPRO1 (text_encoding_info_alist
);
6961 while (FMGetNextFontFamily (&ffi
, &ff
) == noErr
)
6967 TextEncoding encoding
;
6968 TextEncodingBase sc
;
6969 Lisp_Object text_encoding_info
, family
;
6971 if (FMGetFontFamilyName (ff
, name
) != noErr
)
6977 if (FMGetFontFamilyTextEncoding (ff
, &encoding
) != noErr
)
6979 sc
= GetTextEncodingBase (encoding
);
6980 text_encoding_info
= assq_no_quit (make_number (sc
),
6981 text_encoding_info_alist
);
6982 if (NILP (text_encoding_info
))
6983 text_encoding_info
= assq_no_quit (make_number (kTextEncodingMacRoman
),
6984 text_encoding_info_alist
);
6985 decode_mac_font_name (name
, sizeof (name
),
6986 XCAR (XCDR (text_encoding_info
)));
6987 family
= build_string (name
);
6988 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
6990 fm_font_family_alist
= Fcons (Fcons (family
, make_number (ff
)),
6991 fm_font_family_alist
);
6993 /* Point the instance iterator at the current font family. */
6994 if (FMResetFontFamilyInstanceIterator (ff
, &ffii
) != noErr
)
6997 while (FMGetNextFontFamilyInstance (&ffii
, &font
, &style
, &size
)
7000 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7002 if (size
> 0 || style
== normal
)
7003 for (; !NILP (rest
); rest
= XCDR (rest
))
7004 add_mac_font_name (name
, size
, style
, SDATA (XCAR (rest
)));
7010 /* Dispose of the iterators. */
7011 FMDisposeFontFamilyIterator (&ffi
);
7012 FMDisposeFontFamilyInstanceIterator (&ffii
);
7013 #else /* !TARGET_API_MAC_CARBON */
7015 SInt16 fontnum
, old_fontnum
;
7016 int num_mac_fonts
= CountResources('FOND');
7018 Handle font_handle
, font_handle_2
;
7019 short id
, scriptcode
;
7022 struct FontAssoc
*fat
;
7023 struct AsscEntry
*assc_entry
;
7024 Lisp_Object text_encoding_info_alist
, text_encoding_info
, family
;
7025 struct gcpro gcpro1
;
7027 GetPort (&port
); /* save the current font number used */
7028 old_fontnum
= port
->txFont
;
7030 text_encoding_info_alist
= create_text_encoding_info_alist ();
7032 GCPRO1 (text_encoding_info_alist
);
7034 for (i
= 1; i
<= num_mac_fonts
; i
++) /* get all available fonts */
7036 font_handle
= GetIndResource ('FOND', i
);
7040 GetResInfo (font_handle
, &id
, &type
, name
);
7041 GetFNum (name
, &fontnum
);
7043 if (fontnum
== 0 || *name
== '.')
7047 scriptcode
= FontToScript (fontnum
);
7048 text_encoding_info
= assq_no_quit (make_number (scriptcode
),
7049 text_encoding_info_alist
);
7050 if (NILP (text_encoding_info
))
7051 text_encoding_info
= assq_no_quit (make_number (smRoman
),
7052 text_encoding_info_alist
);
7053 decode_mac_font_name (name
, sizeof (name
),
7054 XCAR (XCDR (text_encoding_info
)));
7055 family
= build_string (name
);
7056 if (!NILP (Fassoc (family
, fm_font_family_alist
)))
7058 fm_font_family_alist
= Fcons (Fcons (family
, make_number (fontnum
)),
7059 fm_font_family_alist
);
7062 HLock (font_handle
);
7064 if (GetResourceSizeOnDisk (font_handle
)
7065 >= sizeof (struct FamRec
))
7067 fat
= (struct FontAssoc
*) (*font_handle
7068 + sizeof (struct FamRec
));
7070 = (struct AsscEntry
*) (*font_handle
7071 + sizeof (struct FamRec
)
7072 + sizeof (struct FontAssoc
));
7074 for (j
= 0; j
<= fat
->numAssoc
; j
++, assc_entry
++)
7076 Lisp_Object rest
= XCDR (XCDR (text_encoding_info
));
7078 for (; !NILP (rest
); rest
= XCDR (rest
))
7079 add_mac_font_name (name
, assc_entry
->fontSize
,
7080 assc_entry
->fontStyle
,
7081 SDATA (XCAR (rest
)));
7085 HUnlock (font_handle
);
7086 font_handle_2
= GetNextFOND (font_handle
);
7087 ReleaseResource (font_handle
);
7088 font_handle
= font_handle_2
;
7090 while (ResError () == noErr
&& font_handle
);
7095 TextFont (old_fontnum
);
7096 #endif /* !TARGET_API_MAC_CARBON */
7101 mac_clear_font_name_table ()
7105 for (i
= 0; i
< font_name_count
; i
++)
7106 xfree (font_name_table
[i
]);
7107 xfree (font_name_table
);
7108 font_name_table
= NULL
;
7109 font_name_table_size
= font_name_count
= 0;
7110 fm_font_family_alist
= Qnil
;
7114 enum xlfd_scalable_field_index
7116 XLFD_SCL_PIXEL_SIZE
,
7117 XLFD_SCL_POINT_SIZE
,
7122 static const int xlfd_scalable_fields
[] =
7131 mac_do_list_fonts (pattern
, maxnames
)
7132 const char *pattern
;
7136 Lisp_Object font_list
= Qnil
;
7137 struct xlfdpat
*pat
;
7140 int scl_val
[XLFD_SCL_LAST
], *val
;
7144 if (font_name_table
== NULL
) /* Initialize when first used. */
7145 init_font_name_table ();
7147 for (i
= 0; i
< XLFD_SCL_LAST
; i
++)
7150 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
7151 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
7152 fonts are scaled according to the specified size. */
7155 field
= xlfd_scalable_fields
;
7163 if ('0' <= *ptr
&& *ptr
<= '9')
7165 *val
= *ptr
++ - '0';
7166 while ('0' <= *ptr
&& *ptr
<= '9' && *val
< 10000)
7167 *val
= *val
* 10 + *ptr
++ - '0';
7174 ptr
= strchr (ptr
, '-');
7177 while (ptr
&& i
< 14);
7179 if (i
== 14 && ptr
== NULL
)
7181 if (scl_val
[XLFD_SCL_PIXEL_SIZE
] < 0)
7182 scl_val
[XLFD_SCL_PIXEL_SIZE
] =
7183 (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
] / 10
7184 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
] / 10
7186 if (scl_val
[XLFD_SCL_POINT_SIZE
] < 0)
7187 scl_val
[XLFD_SCL_POINT_SIZE
] =
7188 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7189 : (scl_val
[XLFD_SCL_AVGWIDTH
] > 0 ? scl_val
[XLFD_SCL_AVGWIDTH
]
7191 if (scl_val
[XLFD_SCL_AVGWIDTH
] < 0)
7192 scl_val
[XLFD_SCL_AVGWIDTH
] =
7193 (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0 ? scl_val
[XLFD_SCL_PIXEL_SIZE
] * 10
7194 : (scl_val
[XLFD_SCL_POINT_SIZE
] > 0 ? scl_val
[XLFD_SCL_POINT_SIZE
]
7198 scl_val
[XLFD_SCL_PIXEL_SIZE
] = -1;
7200 pat
= xlfdpat_create (pattern
);
7204 exact
= xlfdpat_exact_p (pat
);
7206 for (i
= 0; i
< font_name_count
; i
++)
7208 if (xlfdpat_match (pat
, font_name_table
[i
]))
7210 font_list
= Fcons (build_string (font_name_table
[i
]), font_list
);
7211 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7214 else if (scl_val
[XLFD_SCL_PIXEL_SIZE
] > 0
7215 && (ptr
= strstr (font_name_table
[i
], "-0-0-0-0-m-0-")))
7217 int former_len
= ptr
- font_name_table
[i
];
7219 scaled
= xmalloc (strlen (font_name_table
[i
]) + 20 + 1);
7220 memcpy (scaled
, font_name_table
[i
], former_len
);
7221 sprintf (scaled
+ former_len
,
7222 "-%d-%d-72-72-m-%d-%s",
7223 scl_val
[XLFD_SCL_PIXEL_SIZE
],
7224 scl_val
[XLFD_SCL_POINT_SIZE
],
7225 scl_val
[XLFD_SCL_AVGWIDTH
],
7226 ptr
+ sizeof ("-0-0-0-0-m-0-") - 1);
7228 if (xlfdpat_match (pat
, scaled
))
7230 font_list
= Fcons (build_string (scaled
), font_list
);
7232 if (exact
|| (maxnames
> 0 && ++n_fonts
>= maxnames
))
7240 xlfdpat_destroy (pat
);
7245 /* Return a list of names of available fonts matching PATTERN on frame F.
7247 Frame F null means we have not yet created any frame on Mac, and
7248 consult the first display in x_display_list. MAXNAMES sets a limit
7249 on how many fonts to match. */
7252 x_list_fonts (f
, pattern
, size
, maxnames
)
7254 Lisp_Object pattern
;
7257 Lisp_Object list
= Qnil
, patterns
, tem
, key
;
7258 struct mac_display_info
*dpyinfo
7259 = f
? FRAME_MAC_DISPLAY_INFO (f
) : x_display_list
;
7261 xassert (size
<= 0);
7263 patterns
= Fassoc (pattern
, Valternate_fontname_alist
);
7264 if (NILP (patterns
))
7265 patterns
= Fcons (pattern
, Qnil
);
7267 for (; CONSP (patterns
); patterns
= XCDR (patterns
))
7269 pattern
= XCAR (patterns
);
7271 if (!STRINGP (pattern
))
7274 tem
= XCAR (XCDR (dpyinfo
->name_list_element
));
7275 key
= Fcons (pattern
, make_number (maxnames
));
7277 list
= Fassoc (key
, tem
);
7280 list
= Fcdr_safe (list
);
7281 /* We have a cashed list. Don't have to get the list again. */
7286 list
= mac_do_list_fonts (SDATA (pattern
), maxnames
);
7289 /* MAC_TODO: add code for matching outline fonts here */
7291 /* Now store the result in the cache. */
7292 XSETCAR (XCDR (dpyinfo
->name_list_element
),
7293 Fcons (Fcons (key
, list
),
7294 XCAR (XCDR (dpyinfo
->name_list_element
))));
7297 if (NILP (list
)) continue; /* Try the remaining alternatives. */
7306 /* Check that FONT is valid on frame F. It is if it can be found in F's
7310 x_check_font (f
, font
)
7315 struct x_display_info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
7317 xassert (font
!= NULL
);
7319 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7320 if (dpyinfo
->font_table
[i
].name
7321 && font
== dpyinfo
->font_table
[i
].font
)
7324 xassert (i
< dpyinfo
->n_fonts
);
7327 #endif /* GLYPH_DEBUG != 0 */
7329 /* Set *W to the minimum width, *H to the minimum font height of FONT.
7330 Note: There are (broken) X fonts out there with invalid XFontStruct
7331 min_bounds contents. For example, handa@etl.go.jp reports that
7332 "-adobe-courier-medium-r-normal--*-180-*-*-m-*-iso8859-1" fonts
7333 have font->min_bounds.width == 0. */
7336 x_font_min_bounds (font
, w
, h
)
7337 MacFontStruct
*font
;
7340 *h
= FONT_HEIGHT (font
);
7341 *w
= font
->min_bounds
.width
;
7345 /* Compute the smallest character width and smallest font height over
7346 all fonts available on frame F. Set the members smallest_char_width
7347 and smallest_font_height in F's x_display_info structure to
7348 the values computed. Value is non-zero if smallest_font_height or
7349 smallest_char_width become smaller than they were before. */
7352 x_compute_min_glyph_bounds (f
)
7356 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7357 MacFontStruct
*font
;
7358 int old_width
= dpyinfo
->smallest_char_width
;
7359 int old_height
= dpyinfo
->smallest_font_height
;
7361 dpyinfo
->smallest_font_height
= 100000;
7362 dpyinfo
->smallest_char_width
= 100000;
7364 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7365 if (dpyinfo
->font_table
[i
].name
)
7367 struct font_info
*fontp
= dpyinfo
->font_table
+ i
;
7370 font
= (MacFontStruct
*) fontp
->font
;
7371 xassert (font
!= (MacFontStruct
*) ~0);
7372 x_font_min_bounds (font
, &w
, &h
);
7374 dpyinfo
->smallest_font_height
= min (dpyinfo
->smallest_font_height
, h
);
7375 dpyinfo
->smallest_char_width
= min (dpyinfo
->smallest_char_width
, w
);
7378 xassert (dpyinfo
->smallest_char_width
> 0
7379 && dpyinfo
->smallest_font_height
> 0);
7381 return (dpyinfo
->n_fonts
== 1
7382 || dpyinfo
->smallest_char_width
< old_width
7383 || dpyinfo
->smallest_font_height
< old_height
);
7387 /* Determine whether given string is a fully-specified XLFD: all 14
7388 fields are present, none is '*'. */
7391 is_fully_specified_xlfd (p
)
7400 for (i
= 0; i
< 13; i
++)
7402 q
= strchr (p
+ 1, '-');
7405 if (q
- p
== 2 && *(p
+ 1) == '*')
7410 if (strchr (p
+ 1, '-') != NULL
)
7413 if (*(p
+ 1) == '*' && *(p
+ 2) == '\0')
7420 /* mac_load_query_font creates and returns an internal representation
7421 for a font in a MacFontStruct struct. There is really no concept
7422 corresponding to "loading" a font on the Mac. But we check its
7423 existence and find the font number and all other information for it
7424 and store them in the returned MacFontStruct. */
7426 static MacFontStruct
*
7427 mac_load_query_font (f
, fontname
)
7437 static ATSUFontID font_id
;
7438 ATSUStyle mac_style
= NULL
;
7441 #if TARGET_API_MAC_CARBON
7442 TextEncoding encoding
;
7447 MacFontStruct
*font
;
7448 XCharStruct
*space_bounds
= NULL
, *pcm
;
7450 if (is_fully_specified_xlfd (fontname
))
7454 Lisp_Object matched_fonts
;
7456 matched_fonts
= mac_do_list_fonts (fontname
, 1);
7457 if (NILP (matched_fonts
))
7459 name
= SDATA (XCAR (matched_fonts
));
7462 if (parse_x_font_name (name
, family
, &size
, &fontface
, charset
) == 0)
7466 if (strcmp (charset
, "iso10646-1") == 0) /* XXX */
7469 static const ATSUAttributeTag tags
[] =
7470 {kATSUFontTag
, kATSUSizeTag
,
7471 kATSUQDBoldfaceTag
, kATSUQDItalicTag
};
7472 static const ByteCount sizes
[] =
7473 {sizeof (ATSUFontID
), sizeof (Fixed
),
7474 sizeof (Boolean
), sizeof (Boolean
)};
7475 static Fixed size_fixed
;
7476 static Boolean bold_p
, italic_p
;
7477 static const ATSUAttributeValuePtr values
[] =
7478 {&font_id
, &size_fixed
,
7479 &bold_p
, &italic_p
};
7480 static const ATSUFontFeatureType types
[] =
7481 {kAllTypographicFeaturesType
, kDiacriticsType
};
7482 static const ATSUFontFeatureSelector selectors
[] =
7483 {kAllTypeFeaturesOffSelector
, kDecomposeDiacriticsSelector
};
7486 font_id
= atsu_find_font_from_family_name (family
);
7487 if (font_id
== kATSUInvalidFontID
)
7489 size_fixed
= Long2Fix (size
);
7490 bold_p
= (fontface
& bold
) != 0;
7491 italic_p
= (fontface
& italic
) != 0;
7492 err
= ATSUCreateStyle (&mac_style
);
7495 err
= ATSUSetFontFeatures (mac_style
, sizeof (types
) / sizeof (types
[0]),
7499 err
= ATSUSetAttributes (mac_style
, sizeof (tags
) / sizeof (tags
[0]),
7500 tags
, sizes
, values
);
7503 err
= FMGetFontFamilyInstanceFromFont (font_id
, &fontnum
, &style
);
7506 scriptcode
= kTextEncodingMacUnicode
;
7511 Lisp_Object tmp
= Fassoc (build_string (family
), fm_font_family_alist
);
7515 fontnum
= XINT (XCDR (tmp
));
7516 #if TARGET_API_MAC_CARBON
7517 if (FMGetFontFamilyTextEncoding (fontnum
, &encoding
) != noErr
)
7519 scriptcode
= GetTextEncodingBase (encoding
);
7521 scriptcode
= FontToScript (fontnum
);
7525 font
= (MacFontStruct
*) xmalloc (sizeof (struct MacFontStruct
));
7527 font
->mac_fontnum
= fontnum
;
7528 font
->mac_fontsize
= size
;
7529 font
->mac_fontface
= fontface
;
7530 font
->mac_scriptcode
= scriptcode
;
7532 font
->mac_style
= mac_style
;
7533 #if USE_CG_TEXT_DRAWING
7534 font
->cg_font
= NULL
;
7535 font
->cg_glyphs
= NULL
;
7539 /* Apple Japanese (SJIS) font is listed as both
7540 "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0"
7541 (Roman script) in init_font_name_table (). The latter should be
7542 treated as a one-byte font. */
7543 if (scriptcode
== smJapanese
&& strcmp (charset
, "jisx0201.1976-0") == 0)
7544 font
->mac_scriptcode
= smRoman
;
7546 font
->full_name
= mac_to_x_fontname (family
, size
, fontface
, charset
);
7549 if (font
->mac_style
)
7554 font
->min_byte1
= 0;
7555 font
->max_byte1
= 0xff;
7556 font
->min_char_or_byte2
= 0;
7557 font
->max_char_or_byte2
= 0xff;
7559 font
->bounds
.rows
= xmalloc (sizeof (XCharStruct
*) * 0x100);
7560 bzero (font
->bounds
.rows
, sizeof (XCharStruct
*) * 0x100);
7561 font
->bounds
.rows
[0] = xmalloc (sizeof (XCharStruct
) * 0x100);
7562 pcm_init (font
->bounds
.rows
[0], 0x100);
7564 #if USE_CG_TEXT_DRAWING
7568 ATSFontRef ats_font
;
7570 err
= FMGetFontFromFontFamilyInstance (fontnum
, fontface
,
7572 /* Use CG text drawing if italic/bold is not synthesized. */
7573 if (err
== noErr
&& style
== fontface
)
7575 ats_font
= FMGetATSFontRefFromFont (font_id
);
7576 font
->cg_font
= CGFontCreateWithPlatformFont (&ats_font
);
7582 font
->cg_glyphs
= xmalloc (sizeof (CGGlyph
) * 0x100);
7583 bzero (font
->cg_glyphs
, sizeof (CGGlyph
) * 0x100);
7586 space_bounds
= font
->bounds
.rows
[0] + 0x20;
7587 err
= mac_query_char_extents (font
->mac_style
, 0x20,
7588 &font
->ascent
, &font
->descent
,
7590 #if USE_CG_TEXT_DRAWING
7591 (font
->cg_glyphs
? font
->cg_glyphs
+ 0x20
7598 || space_bounds
->width
<= 0 || FONT_HEIGHT (font
) <= 0)
7600 mac_unload_font (&one_mac_display_info
, font
);
7604 pcm
= font
->bounds
.rows
[0];
7605 for (c
= 0x21; c
<= 0xff; c
++)
7608 /* Soft hyphen is not supported in ATSUI. */
7612 #if USE_CG_TEXT_DRAWING
7613 if (font
->cg_glyphs
)
7623 mac_query_char_extents (font
->mac_style
, c
, NULL
, NULL
,
7624 pcm
? pcm
+ c
: NULL
,
7625 #if USE_CG_TEXT_DRAWING
7626 (font
->cg_glyphs
? font
->cg_glyphs
+ c
7633 #if USE_CG_TEXT_DRAWING
7634 if (font
->cg_glyphs
&& font
->cg_glyphs
[c
] == 0)
7636 /* Don't use CG text drawing if font substitution occurs in
7637 ASCII or Latin-1 characters. */
7638 CGFontRelease (font
->cg_font
);
7639 font
->cg_font
= NULL
;
7640 xfree (font
->cg_glyphs
);
7641 font
->cg_glyphs
= NULL
;
7652 FontInfo the_fontinfo
;
7653 int is_two_byte_font
;
7655 mac_begin_clip (f
, NULL
);
7659 TextFace (fontface
);
7661 GetFontInfo (&the_fontinfo
);
7663 font
->ascent
= the_fontinfo
.ascent
;
7664 font
->descent
= the_fontinfo
.descent
;
7666 is_two_byte_font
= (font
->mac_scriptcode
== smJapanese
7667 || font
->mac_scriptcode
== smTradChinese
7668 || font
->mac_scriptcode
== smSimpChinese
7669 || font
->mac_scriptcode
== smKorean
);
7671 if (is_two_byte_font
)
7675 font
->min_byte1
= 0xa1;
7676 font
->max_byte1
= 0xfe;
7677 font
->min_char_or_byte2
= 0xa1;
7678 font
->max_char_or_byte2
= 0xfe;
7680 /* Use the width of an "ideographic space" of that font
7681 because the_fontinfo.widMax returns the wrong width for
7683 switch (font
->mac_scriptcode
)
7686 font
->min_byte1
= 0x81;
7687 font
->max_byte1
= 0xfc;
7688 font
->min_char_or_byte2
= 0x40;
7689 font
->max_char_or_byte2
= 0xfc;
7690 char_width
= StringWidth("\p\x81\x40");
7693 font
->min_char_or_byte2
= 0x40;
7694 char_width
= StringWidth("\p\xa1\x40");
7697 char_width
= StringWidth("\p\xa1\xa1");
7700 char_width
= StringWidth("\p\xa1\xa1");
7704 font
->bounds
.per_char
= NULL
;
7706 if (fontface
& italic
)
7707 font
->max_bounds
.rbearing
= char_width
+ 1;
7709 font
->max_bounds
.rbearing
= char_width
;
7710 font
->max_bounds
.lbearing
= 0;
7711 font
->max_bounds
.width
= char_width
;
7712 font
->max_bounds
.ascent
= the_fontinfo
.ascent
;
7713 font
->max_bounds
.descent
= the_fontinfo
.descent
;
7715 font
->min_bounds
= font
->max_bounds
;
7721 font
->min_byte1
= font
->max_byte1
= 0;
7722 font
->min_char_or_byte2
= 0x20;
7723 font
->max_char_or_byte2
= 0xff;
7725 font
->bounds
.per_char
=
7726 xmalloc (sizeof (XCharStruct
) * (0xff - 0x20 + 1));
7727 bzero (font
->bounds
.per_char
,
7728 sizeof (XCharStruct
) * (0xff - 0x20 + 1));
7730 space_bounds
= font
->bounds
.per_char
;
7731 err
= mac_query_char_extents (NULL
, 0x20, &font
->ascent
,
7732 &font
->descent
, space_bounds
, NULL
);
7733 if (err
!= noErr
|| space_bounds
->width
<= 0)
7735 mac_unload_font (&one_mac_display_info
, font
);
7739 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0xff; c
++, pcm
++)
7740 mac_query_char_extents (NULL
, c
, NULL
, NULL
, pcm
, NULL
);
7743 mac_end_clip (f
, NULL
);
7750 font
->min_bounds
= font
->max_bounds
= *space_bounds
;
7751 for (c
= 0x21, pcm
= space_bounds
+ 1; c
<= 0x7f; c
++, pcm
++)
7754 font
->min_bounds
.lbearing
= min (font
->min_bounds
.lbearing
,
7756 font
->min_bounds
.rbearing
= min (font
->min_bounds
.rbearing
,
7758 font
->min_bounds
.width
= min (font
->min_bounds
.width
,
7760 font
->min_bounds
.ascent
= min (font
->min_bounds
.ascent
,
7762 font
->min_bounds
.descent
= min (font
->min_bounds
.descent
,
7765 font
->max_bounds
.lbearing
= max (font
->max_bounds
.lbearing
,
7767 font
->max_bounds
.rbearing
= max (font
->max_bounds
.rbearing
,
7769 font
->max_bounds
.width
= max (font
->max_bounds
.width
,
7771 font
->max_bounds
.ascent
= max (font
->max_bounds
.ascent
,
7773 font
->max_bounds
.descent
= max (font
->max_bounds
.descent
,
7778 font
->mac_style
== NULL
&&
7780 font
->max_bounds
.width
== font
->min_bounds
.width
7781 && font
->min_bounds
.lbearing
>= 0
7782 && font
->max_bounds
.rbearing
<= font
->max_bounds
.width
)
7784 /* Fixed width and no overhangs. */
7785 xfree (font
->bounds
.per_char
);
7786 font
->bounds
.per_char
= NULL
;
7790 #if !defined (MAC_OS8) || USE_ATSUI
7791 /* AppKit and WebKit do some adjustment to the heights of Courier,
7792 Helvetica, and Times. This only works on the environments where
7793 srcCopy text transfer mode is never used. */
7795 #ifdef MAC_OS8 /* implies USE_ATSUI */
7798 (strcmp (family
, "courier") == 0 || strcmp (family
, "helvetica") == 0
7799 || strcmp (family
, "times") == 0))
7800 font
->ascent
+= (font
->ascent
+ font
->descent
) * .15 + 0.5;
7808 mac_unload_font (dpyinfo
, font
)
7809 struct mac_display_info
*dpyinfo
;
7812 xfree (font
->full_name
);
7814 if (font
->mac_style
)
7818 for (i
= font
->min_byte1
; i
<= font
->max_byte1
; i
++)
7819 if (font
->bounds
.rows
[i
])
7820 xfree (font
->bounds
.rows
[i
]);
7821 xfree (font
->bounds
.rows
);
7822 ATSUDisposeStyle (font
->mac_style
);
7826 if (font
->bounds
.per_char
)
7827 xfree (font
->bounds
.per_char
);
7828 #if USE_CG_TEXT_DRAWING
7830 CGFontRelease (font
->cg_font
);
7831 if (font
->cg_glyphs
)
7832 xfree (font
->cg_glyphs
);
7838 /* Load font named FONTNAME of the size SIZE for frame F, and return a
7839 pointer to the structure font_info while allocating it dynamically.
7840 If SIZE is 0, load any size of font.
7841 If loading is failed, return NULL. */
7844 x_load_font (f
, fontname
, size
)
7846 register char *fontname
;
7849 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
7850 Lisp_Object font_names
;
7852 /* Get a list of all the fonts that match this name. Once we
7853 have a list of matching fonts, we compare them against the fonts
7854 we already have by comparing names. */
7855 font_names
= x_list_fonts (f
, build_string (fontname
), size
, 1);
7857 if (!NILP (font_names
))
7862 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
7863 for (tail
= font_names
; CONSP (tail
); tail
= XCDR (tail
))
7864 if (dpyinfo
->font_table
[i
].name
7865 && (!strcmp (dpyinfo
->font_table
[i
].name
,
7866 SDATA (XCAR (tail
)))
7867 || !strcmp (dpyinfo
->font_table
[i
].full_name
,
7868 SDATA (XCAR (tail
)))))
7869 return (dpyinfo
->font_table
+ i
);
7874 /* Load the font and add it to the table. */
7876 struct MacFontStruct
*font
;
7877 struct font_info
*fontp
;
7880 fontname
= (char *) SDATA (XCAR (font_names
));
7883 font
= mac_load_query_font (f
, fontname
);
7888 /* Find a free slot in the font table. */
7889 for (i
= 0; i
< dpyinfo
->n_fonts
; ++i
)
7890 if (dpyinfo
->font_table
[i
].name
== NULL
)
7893 /* If no free slot found, maybe enlarge the font table. */
7894 if (i
== dpyinfo
->n_fonts
7895 && dpyinfo
->n_fonts
== dpyinfo
->font_table_size
)
7898 dpyinfo
->font_table_size
= max (16, 2 * dpyinfo
->font_table_size
);
7899 sz
= dpyinfo
->font_table_size
* sizeof *dpyinfo
->font_table
;
7901 = (struct font_info
*) xrealloc (dpyinfo
->font_table
, sz
);
7904 fontp
= dpyinfo
->font_table
+ i
;
7905 if (i
== dpyinfo
->n_fonts
)
7908 /* Now fill in the slots of *FONTP. */
7910 bzero (fontp
, sizeof (*fontp
));
7912 fontp
->font_idx
= i
;
7913 fontp
->name
= (char *) xmalloc (strlen (fontname
) + 1);
7914 bcopy (fontname
, fontp
->name
, strlen (fontname
) + 1);
7916 if (font
->min_bounds
.width
== font
->max_bounds
.width
)
7918 /* Fixed width font. */
7919 fontp
->average_width
= fontp
->space_width
= font
->min_bounds
.width
;
7926 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
7927 pcm
= mac_per_char_metric (font
, &char2b
, 0);
7929 fontp
->space_width
= pcm
->width
;
7931 fontp
->space_width
= FONT_WIDTH (font
);
7935 int width
= pcm
->width
;
7936 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
7937 if ((pcm
= mac_per_char_metric (font
, &char2b
, 0)) != NULL
)
7938 width
+= pcm
->width
;
7939 fontp
->average_width
= width
/ 95;
7942 fontp
->average_width
= FONT_WIDTH (font
);
7945 fontp
->full_name
= (char *) xmalloc (strlen (font
->full_name
) + 1);
7946 bcopy (font
->full_name
, fontp
->full_name
, strlen (font
->full_name
) + 1);
7948 fontp
->size
= font
->max_bounds
.width
;
7949 fontp
->height
= FONT_HEIGHT (font
);
7951 /* For some font, ascent and descent in max_bounds field is
7952 larger than the above value. */
7953 int max_height
= font
->max_bounds
.ascent
+ font
->max_bounds
.descent
;
7954 if (max_height
> fontp
->height
)
7955 fontp
->height
= max_height
;
7958 /* The slot `encoding' specifies how to map a character
7959 code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
7960 the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
7961 (0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
7962 2:0xA020..0xFF7F). For the moment, we don't know which charset
7963 uses this font. So, we set information in fontp->encoding[1]
7964 which is never used by any charset. If mapping can't be
7965 decided, set FONT_ENCODING_NOT_DECIDED. */
7966 if (font
->mac_scriptcode
== smJapanese
)
7967 fontp
->encoding
[1] = 4;
7971 = (font
->max_byte1
== 0
7973 ? (font
->min_char_or_byte2
< 0x80
7974 ? (font
->max_char_or_byte2
< 0x80
7975 ? 0 /* 0x20..0x7F */
7976 : FONT_ENCODING_NOT_DECIDED
) /* 0x20..0xFF */
7977 : 1) /* 0xA0..0xFF */
7979 : (font
->min_byte1
< 0x80
7980 ? (font
->max_byte1
< 0x80
7981 ? (font
->min_char_or_byte2
< 0x80
7982 ? (font
->max_char_or_byte2
< 0x80
7983 ? 0 /* 0x2020..0x7F7F */
7984 : FONT_ENCODING_NOT_DECIDED
) /* 0x2020..0x7FFF */
7985 : 3) /* 0x20A0..0x7FFF */
7986 : FONT_ENCODING_NOT_DECIDED
) /* 0x20??..0xA0?? */
7987 : (font
->min_char_or_byte2
< 0x80
7988 ? (font
->max_char_or_byte2
< 0x80
7989 ? 2 /* 0xA020..0xFF7F */
7990 : FONT_ENCODING_NOT_DECIDED
) /* 0xA020..0xFFFF */
7991 : 1))); /* 0xA0A0..0xFFFF */
7994 #if 0 /* MAC_TODO: fill these out with more reasonably values */
7995 fontp
->baseline_offset
7996 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
7997 ? (long) value
: 0);
7998 fontp
->relative_compose
7999 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
8000 ? (long) value
: 0);
8001 fontp
->default_ascent
8002 = (XGetFontProperty (font
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
8003 ? (long) value
: 0);
8005 fontp
->baseline_offset
= 0;
8006 fontp
->relative_compose
= 0;
8007 fontp
->default_ascent
= 0;
8010 /* Set global flag fonts_changed_p to non-zero if the font loaded
8011 has a character with a smaller width than any other character
8012 before, or if the font loaded has a smaller height than any
8013 other font loaded before. If this happens, it will make a
8014 glyph matrix reallocation necessary. */
8015 fonts_changed_p
|= x_compute_min_glyph_bounds (f
);
8022 /* Return a pointer to struct font_info of a font named FONTNAME for
8023 frame F. If no such font is loaded, return NULL. */
8026 x_query_font (f
, fontname
)
8028 register char *fontname
;
8030 struct mac_display_info
*dpyinfo
= FRAME_MAC_DISPLAY_INFO (f
);
8033 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
8034 if (dpyinfo
->font_table
[i
].name
8035 && (!xstricmp (dpyinfo
->font_table
[i
].name
, fontname
)
8036 || !xstricmp (dpyinfo
->font_table
[i
].full_name
, fontname
)))
8037 return (dpyinfo
->font_table
+ i
);
8042 /* Find a CCL program for a font specified by FONTP, and set the member
8043 `encoder' of the structure. */
8046 x_find_ccl_program (fontp
)
8047 struct font_info
*fontp
;
8049 Lisp_Object list
, elt
;
8051 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
8055 && STRINGP (XCAR (elt
))
8056 && (fast_c_string_match_ignore_case (XCAR (elt
), fontp
->name
)
8062 struct ccl_program
*ccl
8063 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
8065 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
8068 fontp
->font_encoder
= ccl
;
8073 /* The Mac Event loop code */
8075 #if !TARGET_API_MAC_CARBON
8077 #include <Quickdraw.h>
8078 #include <Balloons.h>
8079 #include <Devices.h>
8081 #include <Gestalt.h>
8083 #include <Processes.h>
8085 #include <ToolUtils.h>
8086 #include <TextUtils.h>
8087 #include <Dialogs.h>
8090 #include <Resources.h>
8095 #endif /* ! TARGET_API_MAC_CARBON */
8097 /* Contains the string "reverse", which is a constant for mouse button emu.*/
8098 Lisp_Object Qreverse
;
8101 /* Modifier associated with the control key, or nil to ignore. */
8102 Lisp_Object Vmac_control_modifier
;
8104 /* Modifier associated with the option key, or nil to ignore. */
8105 Lisp_Object Vmac_option_modifier
;
8107 /* Modifier associated with the command key, or nil to ignore. */
8108 Lisp_Object Vmac_command_modifier
;
8110 /* Modifier associated with the function key, or nil to ignore. */
8111 Lisp_Object Vmac_function_modifier
;
8113 /* True if the option and command modifiers should be used to emulate
8114 a three button mouse */
8115 Lisp_Object Vmac_emulate_three_button_mouse
;
8117 #if TARGET_API_MAC_CARBON
8118 /* Non-zero if the mouse wheel button (i.e. button 4) should map to
8119 mouse-2, instead of mouse-3. */
8120 int mac_wheel_button_is_mouse_2
;
8122 /* If non-zero, the Mac "Command" key is passed on to the Mac Toolbox
8123 for processing before Emacs sees it. */
8124 int mac_pass_command_to_system
;
8126 /* If non-zero, the Mac "Control" key is passed on to the Mac Toolbox
8127 for processing before Emacs sees it. */
8128 int mac_pass_control_to_system
;
8131 /* Whether or not the screen configuration has changed. */
8132 int mac_screen_config_changed
= 0;
8135 #if TARGET_API_MAC_CARBON
8136 Lisp_Object Qhi_command
;
8138 Lisp_Object Qtoolbar_switch_mode
;
8141 Lisp_Object Qtext_input
;
8142 Lisp_Object Qupdate_active_input_area
, Qunicode_for_key_event
;
8143 Lisp_Object Vmac_ts_active_input_overlay
;
8144 Lisp_Object Vmac_ts_script_language_on_focus
;
8145 Lisp_Object saved_ts_script_language_on_focus
;
8146 static ScriptLanguageRecord saved_ts_language
;
8147 static Component saved_ts_component
;
8150 Lisp_Object Qservice
, Qpaste
, Qperform
;
8152 #endif /* TARGET_API_MAC_CARBON */
8153 extern Lisp_Object Qundefined
;
8154 extern int XTread_socket
P_ ((int, int, struct input_event
*));
8155 extern void init_apple_event_handler
P_ ((void));
8156 extern void mac_find_apple_event_spec
P_ ((AEEventClass
, AEEventID
,
8157 Lisp_Object
*, Lisp_Object
*,
8159 extern OSErr init_coercion_handler
P_ ((void));
8161 /* Table for translating Mac keycode to X keysym values. Contributed
8163 Mapping for special keys is now identical to that in Apple X11
8164 except `clear' (-> <clear>) on the KeyPad, `enter' (-> <kp-enter>)
8165 on the right of the Cmd key on laptops, and fn + `enter' (->
8167 const unsigned char keycode_to_xkeysym_table
[] = {
8168 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8169 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8170 /*0x20*/ 0, 0, 0, 0, 0x0d /*return*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8172 /*0x30*/ 0x09 /*tab*/, 0 /*0x0020 space*/, 0, 0x08 /*backspace*/,
8173 /*0x34*/ 0x8d /*enter on laptops*/, 0x1b /*escape*/, 0, 0,
8174 /*0x38*/ 0, 0, 0, 0,
8175 /*0x3C*/ 0, 0, 0, 0,
8177 /*0x40*/ 0, 0xae /*kp-decimal*/, 0, 0xaa /*kp-multiply*/,
8178 /*0x44*/ 0, 0xab /*kp-add*/, 0, 0x0b /*clear*/,
8179 /*0x48*/ 0, 0, 0, 0xaf /*kp-divide*/,
8180 /*0x4C*/ 0x8d /*kp-enter*/, 0, 0xad /*kp-subtract*/, 0,
8182 /*0x50*/ 0, 0xbd /*kp-equal*/, 0xb0 /*kp-0*/, 0xb1 /*kp-1*/,
8183 /*0x54*/ 0xb2 /*kp-2*/, 0xb3 /*kp-3*/, 0xb4 /*kp-4*/, 0xb5 /*kp-5*/,
8184 /*0x58*/ 0xb6 /*kp-6*/, 0xb7 /*kp-7*/, 0, 0xb8 /*kp-8*/,
8185 /*0x5C*/ 0xb9 /*kp-9*/, 0, 0, 0,
8187 /*0x60*/ 0xc2 /*f5*/, 0xc3 /*f6*/, 0xc4 /*f7*/, 0xc0 /*f3*/,
8188 /*0x64*/ 0xc5 /*f8*/, 0xc6 /*f9*/, 0, 0xc8 /*f11*/,
8189 /*0x68*/ 0, 0xca /*f13*/, 0xcd /*f16*/, 0xcb /*f14*/,
8190 /*0x6C*/ 0, 0xc7 /*f10*/, 0x0a /*fn+enter on laptops*/, 0xc9 /*f12*/,
8192 /*0x70*/ 0, 0xcc /*f15*/, 0x6a /*help*/, 0x50 /*home*/,
8193 /*0x74*/ 0x55 /*pgup*/, 0xff /*delete*/, 0xc1 /*f4*/, 0x57 /*end*/,
8194 /*0x78*/ 0xbf /*f2*/, 0x56 /*pgdown*/, 0xbe /*f1*/, 0x51 /*left*/,
8195 /*0x7C*/ 0x53 /*right*/, 0x54 /*down*/, 0x52 /*up*/, 0
8199 /* Table for translating Mac keycode with the laptop `fn' key to that
8200 without it. Destination symbols in comments are keys on US
8201 keyboard, and they may not be the same on other types of keyboards.
8202 If the destination is identical to the source, it doesn't map `fn'
8203 key to a modifier. */
8204 static const unsigned char fn_keycode_to_keycode_table
[] = {
8205 /*0x00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8206 /*0x10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8207 /*0x20*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8209 /*0x30*/ 0, 0, 0, 0,
8210 /*0x34*/ 0, 0, 0, 0,
8211 /*0x38*/ 0, 0, 0, 0,
8212 /*0x3C*/ 0, 0, 0, 0,
8214 /*0x40*/ 0, 0x2f /*kp-decimal -> '.'*/, 0, 0x23 /*kp-multiply -> 'p'*/,
8215 /*0x44*/ 0, 0x2c /*kp-add -> '/'*/, 0, 0x16 /*clear -> '6'*/,
8216 /*0x48*/ 0, 0, 0, 0x1d /*kp-/ -> '0'*/,
8217 /*0x4C*/ 0x24 /*kp-enter -> return*/, 0, 0x29 /*kp-subtract -> ';'*/, 0,
8219 /*0x50*/ 0, 0x1b /*kp-equal -> '-'*/, 0x2e /*kp-0 -> 'm'*/, 0x26 /*kp-1 -> 'j'*/,
8220 /*0x54*/ 0x28 /*kp-2 -> 'k'*/, 0x25 /*kp-3 -> 'l'*/, 0x20 /*kp-4 -> 'u'*/, 0x22 /*kp-5 ->'i'*/,
8221 /*0x58*/ 0x1f /*kp-6 -> 'o'*/, 0x1a /*kp-7 -> '7'*/, 0, 0x1c /*kp-8 -> '8'*/,
8222 /*0x5C*/ 0x19 /*kp-9 -> '9'*/, 0, 0, 0,
8224 /*0x60*/ 0x60 /*f5 = f5*/, 0x61 /*f6 = f6*/, 0x62 /*f7 = f7*/, 0x63 /*f3 = f3*/,
8225 /*0x64*/ 0x64 /*f8 = f8*/, 0x65 /*f9 = f9*/, 0, 0x67 /*f11 = f11*/,
8226 /*0x68*/ 0, 0x69 /*f13 = f13*/, 0x6a /*f16 = f16*/, 0x6b /*f14 = f14*/,
8227 /*0x6C*/ 0, 0x6d /*f10 = f10*/, 0, 0x6f /*f12 = f12*/,
8229 /*0x70*/ 0, 0x71 /*f15 = f15*/, 0x72 /*help = help*/, 0x7b /*home -> left*/,
8230 /*0x74*/ 0x7e /*pgup -> up*/, 0x33 /*delete -> backspace*/, 0x76 /*f4 = f4*/, 0x7c /*end -> right*/,
8231 /*0x78*/ 0x78 /*f2 = f2*/, 0x7d /*pgdown -> down*/, 0x7a /*f1 = f1*/, 0x7b /*left = left*/,
8232 /*0x7C*/ 0x7c /*right = right*/, 0x7d /*down = down*/, 0x7e /*up = up*/, 0
8234 #endif /* MAC_OSX */
8237 #if TARGET_API_MAC_CARBON
8238 mac_to_emacs_modifiers (UInt32 mods
, UInt32 unmapped_mods
)
8240 mac_to_emacs_modifiers (EventModifiers mods
, EventModifiers unmapped_mods
)
8243 unsigned int result
= 0;
8244 if ((mods
| unmapped_mods
) & shiftKey
)
8245 result
|= shift_modifier
;
8247 /* Deactivated to simplify configuration:
8248 if Vmac_option_modifier is non-NIL, we fully process the Option
8249 key. Otherwise, we only process it if an additional Ctrl or Command
8250 is pressed. That way the system may convert the character to a
8252 if ((mods & optionKey) &&
8253 (( !NILP(Vmac_option_modifier) ||
8254 ((mods & cmdKey) || (mods & controlKey))))) */
8256 if (!NILP (Vmac_option_modifier
) && (mods
& optionKey
)) {
8257 Lisp_Object val
= Fget(Vmac_option_modifier
, Qmodifier_value
);
8259 result
|= XUINT(val
);
8261 if (!NILP (Vmac_command_modifier
) && (mods
& cmdKey
)) {
8262 Lisp_Object val
= Fget(Vmac_command_modifier
, Qmodifier_value
);
8264 result
|= XUINT(val
);
8266 if (!NILP (Vmac_control_modifier
) && (mods
& controlKey
)) {
8267 Lisp_Object val
= Fget(Vmac_control_modifier
, Qmodifier_value
);
8269 result
|= XUINT(val
);
8273 if (!NILP (Vmac_function_modifier
) && (mods
& kEventKeyModifierFnMask
)) {
8274 Lisp_Object val
= Fget(Vmac_function_modifier
, Qmodifier_value
);
8276 result
|= XUINT(val
);
8284 mac_mapped_modifiers (modifiers
, key_code
)
8285 UInt32 modifiers
, key_code
;
8287 UInt32 mapped_modifiers_all
=
8288 (NILP (Vmac_control_modifier
) ? 0 : controlKey
)
8289 | (NILP (Vmac_option_modifier
) ? 0 : optionKey
)
8290 | (NILP (Vmac_command_modifier
) ? 0 : cmdKey
);
8293 mapped_modifiers_all
|=
8294 (NILP (Vmac_function_modifier
) ? 0 : kEventKeyModifierFnMask
);
8296 /* The meaning of kEventKeyModifierFnMask has changed in Mac OS X
8297 10.5, and it now behaves much like Cocoa's NSFunctionKeyMask. It
8298 no longer means laptop's `fn' key is down for the following keys:
8299 F1, F2, and so on, Help, Forward Delete, Home, End, Page Up, Page
8300 Down, the arrow keys, and Clear. We ignore the corresponding bit
8301 if that key can be entered without the `fn' key on laptops. */
8302 if (modifiers
& kEventKeyModifierFnMask
8304 && fn_keycode_to_keycode_table
[key_code
] == key_code
)
8305 modifiers
&= ~kEventKeyModifierFnMask
;
8308 return mapped_modifiers_all
& modifiers
;
8312 mac_get_emulated_btn ( UInt32 modifiers
)
8315 if (!NILP (Vmac_emulate_three_button_mouse
)) {
8316 int cmdIs3
= !EQ (Vmac_emulate_three_button_mouse
, Qreverse
);
8317 if (modifiers
& cmdKey
)
8318 result
= cmdIs3
? 2 : 1;
8319 else if (modifiers
& optionKey
)
8320 result
= cmdIs3
? 1 : 2;
8327 mac_restore_keyboard_input_source ()
8329 OSStatus err
= noErr
;
8330 ScriptLanguageRecord slrec
, *slptr
= NULL
;
8332 if (EQ (Vmac_ts_script_language_on_focus
, Qt
)
8333 && EQ (saved_ts_script_language_on_focus
, Qt
))
8334 slptr
= &saved_ts_language
;
8335 else if (CONSP (Vmac_ts_script_language_on_focus
)
8336 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
8337 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
))
8338 && CONSP (saved_ts_script_language_on_focus
)
8339 && EQ (XCAR (saved_ts_script_language_on_focus
),
8340 XCAR (Vmac_ts_script_language_on_focus
))
8341 && EQ (XCDR (saved_ts_script_language_on_focus
),
8342 XCDR (Vmac_ts_script_language_on_focus
)))
8344 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
8345 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
8351 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
8352 err
= SetDefaultInputMethodOfClass (saved_ts_component
, slptr
,
8353 kKeyboardInputMethodClass
);
8355 err
= SetDefaultInputMethod (saved_ts_component
, slptr
);
8358 err
= SetTextServiceLanguage (slptr
);
8360 /* Seems to be needed on Mac OS X 10.2. */
8362 KeyScript (slptr
->fScript
| smKeyForceKeyScriptMask
);
8369 mac_save_keyboard_input_source ()
8372 ScriptLanguageRecord slrec
, *slptr
= NULL
;
8374 saved_ts_script_language_on_focus
= Vmac_ts_script_language_on_focus
;
8376 if (EQ (Vmac_ts_script_language_on_focus
, Qt
))
8378 err
= GetTextServiceLanguage (&saved_ts_language
);
8380 slptr
= &saved_ts_language
;
8382 else if (CONSP (Vmac_ts_script_language_on_focus
)
8383 && INTEGERP (XCAR (Vmac_ts_script_language_on_focus
))
8384 && INTEGERP (XCDR (Vmac_ts_script_language_on_focus
)))
8386 slrec
.fScript
= XINT (XCAR (Vmac_ts_script_language_on_focus
));
8387 slrec
.fLanguage
= XINT (XCDR (Vmac_ts_script_language_on_focus
));
8393 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
8394 GetDefaultInputMethodOfClass (&saved_ts_component
, slptr
,
8395 kKeyboardInputMethodClass
);
8397 GetDefaultInputMethod (&saved_ts_component
, slptr
);
8403 #if TARGET_API_MAC_CARBON
8404 /***** Code to handle C-g testing *****/
8405 extern int quit_char
;
8406 extern int make_ctrl_char
P_ ((int));
8409 mac_quit_char_key_p (modifiers
, key_code
)
8410 UInt32 modifiers
, key_code
;
8412 UInt32 char_code
, mapped_modifiers
;
8413 unsigned long some_state
= 0;
8414 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8415 int c
, emacs_modifiers
;
8417 /* Mask off modifier keys that are mapped to some Emacs modifiers. */
8418 mapped_modifiers
= mac_mapped_modifiers (modifiers
, key_code
);
8419 key_code
|= (modifiers
& ~mapped_modifiers
);
8420 char_code
= KeyTranslate (kchr_ptr
, key_code
, &some_state
);
8421 if (char_code
& ~0xff)
8424 emacs_modifiers
= mac_to_emacs_modifiers (mapped_modifiers
, modifiers
);
8425 if (emacs_modifiers
& ctrl_modifier
)
8426 c
= make_ctrl_char (char_code
);
8428 c
|= (emacs_modifiers
8429 & (meta_modifier
| alt_modifier
8430 | hyper_modifier
| super_modifier
));
8432 return c
== quit_char
;
8437 mac_set_unicode_keystroke_event (code
, buf
)
8439 struct input_event
*buf
;
8441 int charset_id
, c1
, c2
;
8445 buf
->kind
= ASCII_KEYSTROKE_EVENT
;
8448 else if (code
< 0x100)
8451 charset_id
= CHARSET_8_BIT_CONTROL
;
8453 charset_id
= charset_latin_iso8859_1
;
8454 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
8455 buf
->code
= MAKE_CHAR (charset_id
, code
, 0);
8460 charset_id
= charset_mule_unicode_0100_24ff
,
8462 else if (code
< 0x33FF)
8463 charset_id
= charset_mule_unicode_2500_33ff
,
8465 else if (code
>= 0xE000)
8466 charset_id
= charset_mule_unicode_e000_ffff
,
8468 c1
= (code
/ 96) + 32, c2
= (code
% 96) + 32;
8469 buf
->kind
= MULTIBYTE_CHAR_KEYSTROKE_EVENT
;
8470 buf
->code
= MAKE_CHAR (charset_id
, c1
, c2
);
8475 do_keystroke (action
, char_code
, key_code
, modifiers
, timestamp
, buf
)
8477 unsigned char char_code
;
8478 UInt32 key_code
, modifiers
;
8479 unsigned long timestamp
;
8480 struct input_event
*buf
;
8482 static SInt16 last_key_script
= -1;
8483 SInt16 current_key_script
= GetScriptManagerVariable (smKeyScript
);
8484 UInt32 mapped_modifiers
= mac_mapped_modifiers (modifiers
, key_code
);
8487 if (mapped_modifiers
& kEventKeyModifierFnMask
8489 && fn_keycode_to_keycode_table
[key_code
])
8490 key_code
= fn_keycode_to_keycode_table
[key_code
];
8493 if (key_code
<= 0x7f && keycode_to_xkeysym_table
[key_code
])
8495 buf
->kind
= NON_ASCII_KEYSTROKE_EVENT
;
8496 buf
->code
= 0xff00 | keycode_to_xkeysym_table
[key_code
];
8498 else if (mapped_modifiers
)
8500 /* translate the keycode back to determine the original key */
8502 UCKeyboardLayout
*uchr_ptr
= NULL
;
8503 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020
8505 KeyboardLayoutRef layout
;
8507 err
= KLGetCurrentKeyboardLayout (&layout
);
8509 err
= KLGetKeyboardLayoutProperty (layout
, kKLuchrData
,
8510 (const void **) &uchr_ptr
);
8512 static SInt16 last_key_layout_id
= 0;
8513 static Handle uchr_handle
= (Handle
)-1;
8514 SInt16 current_key_layout_id
=
8515 GetScriptVariable (current_key_script
, smScriptKeys
);
8517 if (uchr_handle
== (Handle
)-1
8518 || last_key_layout_id
!= current_key_layout_id
)
8520 uchr_handle
= GetResource ('uchr', current_key_layout_id
);
8521 last_key_layout_id
= current_key_layout_id
;
8524 uchr_ptr
= (UCKeyboardLayout
*)*uchr_handle
;
8530 UInt16 key_action
= action
- keyDown
;
8531 UInt32 modifier_key_state
= (modifiers
& ~mapped_modifiers
) >> 8;
8532 UInt32 keyboard_type
= LMGetKbdType ();
8533 SInt32 dead_key_state
= 0;
8535 UniCharCount actual_length
;
8537 status
= UCKeyTranslate (uchr_ptr
, key_code
, key_action
,
8538 modifier_key_state
, keyboard_type
,
8539 kUCKeyTranslateNoDeadKeysMask
,
8541 1, &actual_length
, &code
);
8542 if (status
== noErr
&& actual_length
== 1)
8543 mac_set_unicode_keystroke_event (code
, buf
);
8545 #endif /* MAC_OSX */
8547 if (buf
->kind
== NO_EVENT
)
8549 /* This code comes from Keyboard Resource, Appendix C of IM
8550 - Text. This is necessary since shift is ignored in KCHR
8551 table translation when option or command is pressed. It
8552 also does not translate correctly control-shift chars
8553 like C-% so mask off shift here also. */
8554 /* Mask off modifier keys that are mapped to some Emacs
8556 int new_modifiers
= modifiers
& ~mapped_modifiers
;
8557 /* set high byte of keycode to modifier high byte*/
8558 int new_key_code
= key_code
| new_modifiers
;
8559 Ptr kchr_ptr
= (Ptr
) GetScriptManagerVariable (smKCHRCache
);
8560 unsigned long some_state
= 0;
8561 UInt32 new_char_code
;
8563 new_char_code
= KeyTranslate (kchr_ptr
, new_key_code
, &some_state
);
8564 if (new_char_code
== 0)
8565 /* Seems like a dead key. Append up-stroke. */
8566 new_char_code
= KeyTranslate (kchr_ptr
, new_key_code
| 0x80,
8570 buf
->kind
= ASCII_KEYSTROKE_EVENT
;
8571 buf
->code
= new_char_code
& 0xff;
8576 if (buf
->kind
== NO_EVENT
)
8578 buf
->kind
= ASCII_KEYSTROKE_EVENT
;
8579 buf
->code
= char_code
;
8582 buf
->modifiers
= mac_to_emacs_modifiers (mapped_modifiers
, modifiers
);
8583 buf
->modifiers
|= (extra_keyboard_modifiers
8584 & (meta_modifier
| alt_modifier
8585 | hyper_modifier
| super_modifier
));
8587 #if TARGET_API_MAC_CARBON
8588 if (buf
->kind
== ASCII_KEYSTROKE_EVENT
8589 && buf
->code
>= 0x80 && buf
->modifiers
)
8592 TextEncoding encoding
= kTextEncodingMacRoman
;
8593 TextToUnicodeInfo ttu_info
;
8595 UpgradeScriptInfoToTextEncoding (current_key_script
,
8596 kTextLanguageDontCare
,
8597 kTextRegionDontCare
,
8599 err
= CreateTextToUnicodeInfoByEncoding (encoding
, &ttu_info
);
8604 ByteCount unicode_len
;
8607 pstr
[1] = buf
->code
;
8608 err
= ConvertFromPStringToUnicode (ttu_info
, pstr
,
8610 &unicode_len
, &code
);
8611 if (err
== noErr
&& unicode_len
== sizeof (UniChar
))
8612 mac_set_unicode_keystroke_event (code
, buf
);
8613 DisposeTextToUnicodeInfo (&ttu_info
);
8618 if (buf
->kind
== ASCII_KEYSTROKE_EVENT
8619 && buf
->code
>= 0x80
8620 && last_key_script
!= current_key_script
)
8622 struct input_event event
;
8625 event
.kind
= LANGUAGE_CHANGE_EVENT
;
8627 event
.code
= current_key_script
;
8628 event
.timestamp
= timestamp
;
8629 kbd_buffer_store_event (&event
);
8630 last_key_script
= current_key_script
;
8635 mac_store_apple_event (class, id
, desc
)
8636 Lisp_Object
class, id
;
8639 struct input_event buf
;
8643 buf
.kind
= MAC_APPLE_EVENT
;
8646 XSETFRAME (buf
.frame_or_window
,
8647 mac_focus_frame (&one_mac_display_info
));
8648 /* Now that Lisp object allocations are protected by BLOCK_INPUT, it
8649 is safe to use them during read_socket_hook. */
8650 buf
.arg
= mac_aedesc_to_lisp (desc
);
8651 kbd_buffer_store_event (&buf
);
8654 #if TARGET_API_MAC_CARBON
8656 mac_store_event_ref_as_apple_event (class, id
, class_key
, id_key
,
8657 event
, num_params
, names
, types
)
8660 Lisp_Object class_key
, id_key
;
8663 const EventParamName
*names
;
8664 const EventParamType
*types
;
8666 OSStatus err
= eventNotHandledErr
;
8667 Lisp_Object binding
;
8669 mac_find_apple_event_spec (class, id
, &class_key
, &id_key
, &binding
);
8670 if (!NILP (binding
) && !EQ (binding
, Qundefined
))
8672 if (INTEGERP (binding
))
8673 err
= XINT (binding
);
8676 AppleEvent apple_event
;
8677 err
= create_apple_event_from_event_ref (event
, num_params
,
8682 mac_store_apple_event (class_key
, id_key
, &apple_event
);
8683 AEDisposeDesc (&apple_event
);
8684 mac_wakeup_from_rne ();
8691 #endif /* TARGET_API_MAC_CARBON */
8694 mac_handle_dm_notification (event
)
8697 mac_screen_config_changed
= 1;
8700 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
8702 mac_handle_cg_display_reconfig (display
, flags
, user_info
)
8703 CGDirectDisplayID display
;
8704 CGDisplayChangeSummaryFlags flags
;
8707 mac_screen_config_changed
= 1;
8712 init_dm_notification_handler ()
8716 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
8717 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
8718 if (CGDisplayRegisterReconfigurationCallback
!= NULL
)
8721 CGDisplayRegisterReconfigurationCallback (mac_handle_cg_display_reconfig
,
8724 #if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
8725 else /* CGDisplayRegisterReconfigurationCallback == NULL */
8727 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 */
8728 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030 || MAC_OS_X_VERSION_MIN_REQUIRED == 1020
8730 static DMNotificationUPP handle_dm_notificationUPP
= NULL
;
8731 ProcessSerialNumber psn
;
8733 if (handle_dm_notificationUPP
== NULL
)
8734 handle_dm_notificationUPP
=
8735 NewDMNotificationUPP (mac_handle_dm_notification
);
8737 err
= GetCurrentProcess (&psn
);
8739 err
= DMRegisterNotifyProc (handle_dm_notificationUPP
, &psn
);
8747 mac_get_screen_info (dpyinfo
)
8748 struct mac_display_info
*dpyinfo
;
8751 /* HasDepth returns true if it is possible to have a 32 bit display,
8752 but this may not be what is actually used. Mac OSX can do better. */
8753 dpyinfo
->color_p
= CGDisplaySamplesPerPixel (kCGDirectMainDisplay
) > 1;
8754 dpyinfo
->n_planes
= CGDisplayBitsPerPixel (kCGDirectMainDisplay
);
8757 CGDisplayCount ndisps
;
8758 CGDirectDisplayID
*displays
;
8760 err
= CGGetActiveDisplayList (0, NULL
, &ndisps
);
8763 displays
= alloca (sizeof (CGDirectDisplayID
) * ndisps
);
8764 err
= CGGetActiveDisplayList (ndisps
, displays
, &ndisps
);
8768 CGRect bounds
= CGRectZero
;
8770 while (ndisps
-- > 0)
8771 bounds
= CGRectUnion (bounds
, CGDisplayBounds (displays
[ndisps
]));
8772 dpyinfo
->height
= CGRectGetHeight (bounds
);
8773 dpyinfo
->width
= CGRectGetWidth (bounds
);
8777 dpyinfo
->height
= CGDisplayPixelsHigh (kCGDirectMainDisplay
);
8778 dpyinfo
->width
= CGDisplayPixelsWide (kCGDirectMainDisplay
);
8781 #else /* !MAC_OSX */
8783 GDHandle gdh
= GetMainDevice ();
8784 Rect rect
= (**gdh
).gdRect
;
8786 dpyinfo
->color_p
= TestDeviceAttribute (gdh
, gdDevType
);
8787 for (dpyinfo
->n_planes
= 32; dpyinfo
->n_planes
> 0; dpyinfo
->n_planes
>>= 1)
8788 if (HasDepth (gdh
, dpyinfo
->n_planes
, gdDevType
, dpyinfo
->color_p
))
8791 for (gdh
= DMGetFirstScreenDevice (dmOnlyActiveDisplays
); gdh
;
8792 gdh
= DMGetNextScreenDevice (gdh
, dmOnlyActiveDisplays
))
8793 UnionRect (&rect
, &(**gdh
).gdRect
, &rect
);
8795 dpyinfo
->height
= rect
.bottom
- rect
.top
;
8796 dpyinfo
->width
= rect
.right
- rect
.left
;
8798 #endif /* !MAC_OSX */
8802 /***********************************************************************
8803 Initialization (Mac OS Classic)
8804 ***********************************************************************/
8807 extern void init_emacs_passwd_dir ();
8808 extern int emacs_main (int, char **, char **);
8810 extern void initialize_applescript();
8811 extern void terminate_applescript();
8816 Handle menubar_handle
;
8819 menubar_handle
= GetNewMBar (128);
8820 if(menubar_handle
== NULL
)
8822 SetMenuBar (menubar_handle
);
8825 #if !TARGET_API_MAC_CARBON
8826 menu
= GetMenuRef (M_APPLE
);
8828 AppendResMenu (menu
, 'DRVR');
8835 do_init_managers (void)
8837 #if !TARGET_API_MAC_CARBON
8838 InitGraf (&qd
.thePort
);
8840 FlushEvents (everyEvent
, 0);
8845 #endif /* !TARGET_API_MAC_CARBON */
8848 #if !TARGET_API_MAC_CARBON
8849 /* set up some extra stack space for use by emacs */
8850 SetApplLimit ((Ptr
) ((long) GetApplLimit () - EXTRA_STACK_ALLOC
));
8852 /* MaxApplZone must be called for AppleScript to execute more
8853 complicated scripts */
8856 #endif /* !TARGET_API_MAC_CARBON */
8860 do_check_ram_size (void)
8862 SInt32 physical_ram_size
, logical_ram_size
;
8864 if (Gestalt (gestaltPhysicalRAMSize
, &physical_ram_size
) != noErr
8865 || Gestalt (gestaltLogicalRAMSize
, &logical_ram_size
) != noErr
8866 || physical_ram_size
> (1 << VALBITS
)
8867 || logical_ram_size
> (1 << VALBITS
))
8869 StopAlert (RAM_TOO_LARGE_ALERT_ID
, NULL
);
8876 profiler_exit_proc ()
8878 ProfilerDump ("\pEmacs.prof");
8883 /* These few functions implement Emacs as a normal Mac application
8884 (almost): set up the heap and the Toolbox, handle necessary system
8885 events plus a few simple menu events. They also set up Emacs's
8886 access to functions defined in the rest of this file. Emacs uses
8887 function hooks to perform all its terminal I/O. A complete list of
8888 these functions appear in termhooks.h. For what they do, read the
8889 comments there and see also w32term.c and xterm.c. What's
8890 noticeably missing here is the event loop, which is normally
8891 present in most Mac application. After performing the necessary
8892 Mac initializations, main passes off control to emacs_main
8893 (corresponding to main in emacs.c). Emacs_main calls XTread_socket
8894 (defined further below) to read input. This is where
8895 WaitNextEvent/ReceiveNextEvent is called to process Mac events. */
8901 #if __profile__ /* is the profiler on? */
8902 if (ProfilerInit(collectDetailed
, bestTimeBase
, 5000, 200))
8907 /* set creator and type for files created by MSL */
8908 _fcreator
= MAC_EMACS_CREATOR_CODE
;
8912 do_init_managers ();
8917 do_check_ram_size ();
8920 init_emacs_passwd_dir ();
8924 init_coercion_handler ();
8926 initialize_applescript ();
8928 init_apple_event_handler ();
8930 init_dm_notification_handler ();
8936 /* set up argv array from STR# resource */
8937 get_string_list (&argv
, ARGV_STRING_LIST_ID
);
8941 /* free up AppleScript resources on exit */
8942 atexit (terminate_applescript
);
8944 #if __profile__ /* is the profiler on? */
8945 atexit (profiler_exit_proc
);
8948 /* 3rd param "envp" never used in emacs_main */
8949 (void) emacs_main (argc
, argv
, 0);
8952 /* Never reached - real exit in Fkill_emacs */
8956 /* Need to override CodeWarrior's input function so no conversion is
8957 done on newlines Otherwise compiled functions in .elc files will be
8958 read incorrectly. Defined in ...:MSL C:MSL
8959 Common:Source:buffer_io.c. */
8962 __convert_to_newlines (unsigned char * p
, size_t * n
)
8968 __convert_from_newlines (unsigned char * p
, size_t * n
)
8975 make_mac_terminal_frame (struct frame
*f
)
8980 XSETFRAME (frame
, f
);
8982 f
->output_method
= output_mac
;
8983 f
->output_data
.mac
= (struct mac_output
*)
8984 xmalloc (sizeof (struct mac_output
));
8985 bzero (f
->output_data
.mac
, sizeof (struct mac_output
));
8987 XSETFRAME (FRAME_KBOARD (f
)->Vdefault_minibuffer_frame
, f
);
8989 FRAME_COLS (f
) = 96;
8990 FRAME_LINES (f
) = 4;
8992 FRAME_CAN_HAVE_SCROLL_BARS (f
) = 1;
8993 FRAME_VERTICAL_SCROLL_BAR_TYPE (f
) = vertical_scroll_bar_right
;
8995 FRAME_DESIRED_CURSOR (f
) = FILLED_BOX_CURSOR
;
8997 f
->output_data
.mac
->cursor_pixel
= 0;
8998 f
->output_data
.mac
->border_pixel
= 0x00ff00;
8999 f
->output_data
.mac
->mouse_pixel
= 0xff00ff;
9000 f
->output_data
.mac
->cursor_foreground_pixel
= 0x0000ff;
9002 f
->output_data
.mac
->text_cursor
= kThemeIBeamCursor
;
9003 f
->output_data
.mac
->nontext_cursor
= kThemeArrowCursor
;
9004 f
->output_data
.mac
->modeline_cursor
= kThemeArrowCursor
;
9005 f
->output_data
.mac
->hand_cursor
= kThemePointingHandCursor
;
9006 f
->output_data
.mac
->hourglass_cursor
= kThemeWatchCursor
;
9007 f
->output_data
.mac
->horizontal_drag_cursor
= kThemeResizeLeftRightCursor
;
9009 FRAME_FONTSET (f
) = -1;
9010 f
->output_data
.mac
->explicit_parent
= 0;
9013 f
->border_width
= 0;
9015 f
->internal_border_width
= 0;
9020 f
->new_text_cols
= 0;
9021 f
->new_text_lines
= 0;
9023 SetRect (&r
, f
->left_pos
, f
->top_pos
,
9024 f
->left_pos
+ FRAME_PIXEL_WIDTH (f
),
9025 f
->top_pos
+ FRAME_PIXEL_HEIGHT (f
));
9029 if (!(FRAME_MAC_WINDOW (f
) =
9030 NewCWindow (NULL
, &r
, "\p", true, dBoxProc
,
9031 (WindowRef
) -1, 1, (long) f
->output_data
.mac
)))
9033 /* so that update events can find this mac_output struct */
9034 f
->output_data
.mac
->mFP
= f
; /* point back to emacs frame */
9040 /* Need to be initialized for unshow_buffer in window.c. */
9041 selected_window
= f
->selected_window
;
9043 Fmodify_frame_parameters (frame
,
9044 Fcons (Fcons (Qfont
,
9045 build_string ("-*-monaco-medium-r-*--*-90-*-*-*-*-mac-roman")), Qnil
));
9046 Fmodify_frame_parameters (frame
,
9047 Fcons (Fcons (Qforeground_color
,
9048 build_string ("black")), Qnil
));
9049 Fmodify_frame_parameters (frame
,
9050 Fcons (Fcons (Qbackground_color
,
9051 build_string ("white")), Qnil
));
9053 #endif /* MAC_OS8 */
9056 /***********************************************************************
9058 ***********************************************************************/
9060 static int mac_initialized
= 0;
9063 mac_make_rdb (xrm_option
)
9064 const char *xrm_option
;
9066 XrmDatabase database
;
9068 database
= xrm_get_preference_database (NULL
);
9070 xrm_merge_string_database (database
, xrm_option
);
9075 struct mac_display_info
*
9076 mac_term_init (display_name
, xrm_option
, resource_name
)
9077 Lisp_Object display_name
;
9079 char *resource_name
;
9081 struct mac_display_info
*dpyinfo
;
9085 if (!mac_initialized
)
9088 mac_initialized
= 1;
9092 error ("Sorry, this version can only handle one display");
9094 dpyinfo
= &one_mac_display_info
;
9095 bzero (dpyinfo
, sizeof (*dpyinfo
));
9098 dpyinfo
->mac_id_name
9099 = (char *) xmalloc (SCHARS (Vinvocation_name
)
9100 + SCHARS (Vsystem_name
)
9102 sprintf (dpyinfo
->mac_id_name
, "%s@%s",
9103 SDATA (Vinvocation_name
), SDATA (Vsystem_name
));
9105 dpyinfo
->mac_id_name
= (char *) xmalloc (strlen ("Mac Display") + 1);
9106 strcpy (dpyinfo
->mac_id_name
, "Mac Display");
9109 dpyinfo
->reference_count
= 0;
9110 dpyinfo
->resx
= 72.0;
9111 dpyinfo
->resy
= 72.0;
9113 mac_get_screen_info (dpyinfo
);
9115 dpyinfo
->grabbed
= 0;
9116 dpyinfo
->root_window
= NULL
;
9117 dpyinfo
->image_cache
= make_image_cache ();
9119 dpyinfo
->mouse_face_beg_row
= dpyinfo
->mouse_face_beg_col
= -1;
9120 dpyinfo
->mouse_face_end_row
= dpyinfo
->mouse_face_end_col
= -1;
9121 dpyinfo
->mouse_face_face_id
= DEFAULT_FACE_ID
;
9122 dpyinfo
->mouse_face_window
= Qnil
;
9123 dpyinfo
->mouse_face_overlay
= Qnil
;
9124 dpyinfo
->mouse_face_hidden
= 0;
9126 dpyinfo
->xrdb
= mac_make_rdb (xrm_option
);
9128 /* Put this display on the chain. */
9129 dpyinfo
->next
= x_display_list
;
9130 x_display_list
= dpyinfo
;
9132 /* Put it on x_display_name_list. */
9133 x_display_name_list
= Fcons (Fcons (display_name
,
9134 Fcons (Qnil
, dpyinfo
->xrdb
)),
9135 x_display_name_list
);
9136 dpyinfo
->name_list_element
= XCAR (x_display_name_list
);
9143 /* Get rid of display DPYINFO, assuming all frames are already gone. */
9146 x_delete_display (dpyinfo
)
9147 struct mac_display_info
*dpyinfo
;
9151 /* Discard this display from x_display_name_list and x_display_list.
9152 We can't use Fdelq because that can quit. */
9153 if (! NILP (x_display_name_list
)
9154 && EQ (XCAR (x_display_name_list
), dpyinfo
->name_list_element
))
9155 x_display_name_list
= XCDR (x_display_name_list
);
9160 tail
= x_display_name_list
;
9161 while (CONSP (tail
) && CONSP (XCDR (tail
)))
9163 if (EQ (XCAR (XCDR (tail
)), dpyinfo
->name_list_element
))
9165 XSETCDR (tail
, XCDR (XCDR (tail
)));
9172 if (x_display_list
== dpyinfo
)
9173 x_display_list
= dpyinfo
->next
;
9176 struct x_display_info
*tail
;
9178 for (tail
= x_display_list
; tail
; tail
= tail
->next
)
9179 if (tail
->next
== dpyinfo
)
9180 tail
->next
= tail
->next
->next
;
9183 /* Free the font names in the font table. */
9184 for (i
= 0; i
< dpyinfo
->n_fonts
; i
++)
9185 if (dpyinfo
->font_table
[i
].name
)
9187 if (dpyinfo
->font_table
[i
].name
!= dpyinfo
->font_table
[i
].full_name
)
9188 xfree (dpyinfo
->font_table
[i
].full_name
);
9189 xfree (dpyinfo
->font_table
[i
].name
);
9192 if (dpyinfo
->font_table
)
9194 if (dpyinfo
->font_table
->font_encoder
)
9195 xfree (dpyinfo
->font_table
->font_encoder
);
9196 xfree (dpyinfo
->font_table
);
9198 if (dpyinfo
->mac_id_name
)
9199 xfree (dpyinfo
->mac_id_name
);
9201 if (x_display_list
== 0)
9203 mac_clear_font_name_table ();
9204 bzero (dpyinfo
, sizeof (*dpyinfo
));
9209 /* Set up use of X before we make the first connection. */
9211 extern frame_parm_handler mac_frame_parm_handlers
[];
9213 static struct redisplay_interface x_redisplay_interface
=
9215 mac_frame_parm_handlers
,
9219 x_clear_end_of_line
,
9221 x_after_update_window_line
,
9222 x_update_window_begin
,
9223 x_update_window_end
,
9227 mac_flush_display_optional
,
9229 0, /* flush_display_optional */
9231 x_clear_window_mouse_face
,
9232 x_get_glyph_overhangs
,
9233 x_fix_overlapping_area
,
9234 x_draw_fringe_bitmap
,
9236 mac_define_fringe_bitmap
,
9237 mac_destroy_fringe_bitmap
,
9239 0, /* define_fringe_bitmap */
9240 0, /* destroy_fringe_bitmap */
9242 mac_per_char_metric
,
9244 mac_compute_glyph_string_overhangs
,
9245 x_draw_glyph_string
,
9246 mac_define_frame_cursor
,
9247 mac_clear_frame_area
,
9248 mac_draw_window_cursor
,
9249 mac_draw_vertical_window_border
,
9250 mac_shift_glyphs_for_insert
9256 rif
= &x_redisplay_interface
;
9258 clear_frame_hook
= x_clear_frame
;
9259 ins_del_lines_hook
= x_ins_del_lines
;
9260 delete_glyphs_hook
= x_delete_glyphs
;
9261 ring_bell_hook
= XTring_bell
;
9262 reset_terminal_modes_hook
= XTreset_terminal_modes
;
9263 set_terminal_modes_hook
= XTset_terminal_modes
;
9264 update_begin_hook
= x_update_begin
;
9265 update_end_hook
= x_update_end
;
9266 set_terminal_window_hook
= XTset_terminal_window
;
9267 read_socket_hook
= XTread_socket
;
9268 frame_up_to_date_hook
= XTframe_up_to_date
;
9269 mouse_position_hook
= XTmouse_position
;
9270 frame_rehighlight_hook
= XTframe_rehighlight
;
9271 frame_raise_lower_hook
= XTframe_raise_lower
;
9273 set_vertical_scroll_bar_hook
= XTset_vertical_scroll_bar
;
9274 condemn_scroll_bars_hook
= XTcondemn_scroll_bars
;
9275 redeem_scroll_bar_hook
= XTredeem_scroll_bar
;
9276 judge_scroll_bars_hook
= XTjudge_scroll_bars
;
9278 scroll_region_ok
= 1; /* we'll scroll partial frames */
9279 char_ins_del_ok
= 1;
9280 line_ins_del_ok
= 1; /* we'll just blt 'em */
9281 fast_clear_end_of_line
= 1; /* X does this well */
9282 memory_below_frame
= 0; /* we don't remember what scrolls
9286 last_tool_bar_item
= -1;
9288 /* Try to use interrupt input; if we can't, then start polling. */
9289 Fset_input_mode (Qt
, Qnil
, Qt
, Qnil
);
9293 #if TARGET_API_MAC_CARBON
9295 init_coercion_handler ();
9297 init_dm_notification_handler ();
9300 install_application_handler ();
9302 mac_toolbox_initialize ();
9305 if (!inhibit_window_system
)
9307 static const ProcessSerialNumber psn
= {0, kCurrentProcess
};
9309 SetFrontProcess (&psn
);
9328 staticpro (&x_error_message_string
);
9329 x_error_message_string
= Qnil
;
9332 Qcontrol
= intern ("control"); staticpro (&Qcontrol
);
9333 Qmeta
= intern ("meta"); staticpro (&Qmeta
);
9334 Qalt
= intern ("alt"); staticpro (&Qalt
);
9335 Qhyper
= intern ("hyper"); staticpro (&Qhyper
);
9336 Qsuper
= intern ("super"); staticpro (&Qsuper
);
9337 Qmodifier_value
= intern ("modifier-value");
9338 staticpro (&Qmodifier_value
);
9340 Fput (Qcontrol
, Qmodifier_value
, make_number (ctrl_modifier
));
9341 Fput (Qmeta
, Qmodifier_value
, make_number (meta_modifier
));
9342 Fput (Qalt
, Qmodifier_value
, make_number (alt_modifier
));
9343 Fput (Qhyper
, Qmodifier_value
, make_number (hyper_modifier
));
9344 Fput (Qsuper
, Qmodifier_value
, make_number (super_modifier
));
9346 #if TARGET_API_MAC_CARBON
9347 Qhi_command
= intern ("hi-command"); staticpro (&Qhi_command
);
9349 Qtoolbar_switch_mode
= intern ("toolbar-switch-mode");
9350 staticpro (&Qtoolbar_switch_mode
);
9351 #if USE_MAC_FONT_PANEL
9352 Qpanel_closed
= intern ("panel-closed"); staticpro (&Qpanel_closed
);
9353 Qselection
= intern ("selection"); staticpro (&Qselection
);
9356 Qservice
= intern ("service"); staticpro (&Qservice
);
9357 Qpaste
= intern ("paste"); staticpro (&Qpaste
);
9358 Qperform
= intern ("perform"); staticpro (&Qperform
);
9361 Qtext_input
= intern ("text-input"); staticpro (&Qtext_input
);
9362 Qupdate_active_input_area
= intern ("update-active-input-area");
9363 staticpro (&Qupdate_active_input_area
);
9364 Qunicode_for_key_event
= intern ("unicode-for-key-event");
9365 staticpro (&Qunicode_for_key_event
);
9370 Fprovide (intern ("mac-carbon"), Qnil
);
9373 staticpro (&Qreverse
);
9374 Qreverse
= intern ("reverse");
9376 staticpro (&x_display_name_list
);
9377 x_display_name_list
= Qnil
;
9379 staticpro (&last_mouse_scroll_bar
);
9380 last_mouse_scroll_bar
= Qnil
;
9382 staticpro (&fm_font_family_alist
);
9383 fm_font_family_alist
= Qnil
;
9386 staticpro (&atsu_font_id_hash
);
9387 atsu_font_id_hash
= Qnil
;
9389 staticpro (&fm_style_face_attributes_alist
);
9390 fm_style_face_attributes_alist
= Qnil
;
9394 staticpro (&saved_ts_script_language_on_focus
);
9395 saved_ts_script_language_on_focus
= Qnil
;
9398 /* We don't yet support this, but defining this here avoids whining
9399 from cus-start.el and other places, like "M-x set-variable". */
9400 DEFVAR_BOOL ("x-use-underline-position-properties",
9401 &x_use_underline_position_properties
,
9402 doc
: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
9403 A value of nil means ignore them. If you encounter fonts with bogus
9404 UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
9405 to 4.1, set this to nil.
9407 NOTE: Not supported on Mac yet. */);
9408 x_use_underline_position_properties
= 0;
9410 DEFVAR_BOOL ("x-underline-at-descent-line",
9411 &x_underline_at_descent_line
,
9412 doc
: /* *Non-nil means to draw the underline at the same place as the descent line.
9413 A value of nil means to draw the underline according to the value of the
9414 variable `x-use-underline-position-properties', which is usually at the
9415 baseline level. The default value is nil. */);
9416 x_underline_at_descent_line
= 0;
9418 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars
,
9419 doc
: /* If not nil, Emacs uses toolkit scroll bars. */);
9420 #ifdef USE_TOOLKIT_SCROLL_BARS
9421 Vx_toolkit_scroll_bars
= Qt
;
9423 Vx_toolkit_scroll_bars
= Qnil
;
9426 staticpro (&last_mouse_motion_frame
);
9427 last_mouse_motion_frame
= Qnil
;
9429 /* Variables to configure modifier key assignment. */
9431 DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier
,
9432 doc
: /* *Modifier key assumed when the Mac control key is pressed.
9433 The value can be `control', `meta', `alt', `hyper', or `super' for the
9434 respective modifier. The default is `control'. */);
9435 Vmac_control_modifier
= Qcontrol
;
9437 DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier
,
9438 doc
: /* *Modifier key assumed when the Mac alt/option key is pressed.
9439 The value can be `control', `meta', `alt', `hyper', or `super' for the
9440 respective modifier. If the value is nil then the key will act as the
9441 normal Mac control modifier, and the option key can be used to compose
9442 characters depending on the chosen Mac keyboard setting. */);
9443 Vmac_option_modifier
= Qnil
;
9445 DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier
,
9446 doc
: /* *Modifier key assumed when the Mac command key is pressed.
9447 The value can be `control', `meta', `alt', `hyper', or `super' for the
9448 respective modifier. The default is `meta'. */);
9449 Vmac_command_modifier
= Qmeta
;
9451 DEFVAR_LISP ("mac-function-modifier", &Vmac_function_modifier
,
9452 doc
: /* *Modifier key assumed when the Mac function key is pressed.
9453 The value can be `control', `meta', `alt', `hyper', or `super' for the
9454 respective modifier. Note that remapping the function key may lead to
9455 unexpected results for some keys on non-US/GB keyboards. */);
9456 Vmac_function_modifier
= Qnil
;
9458 DEFVAR_LISP ("mac-emulate-three-button-mouse",
9459 &Vmac_emulate_three_button_mouse
,
9460 doc
: /* *Specify a way of three button mouse emulation.
9461 The value can be nil, t, or the symbol `reverse'.
9462 A value of nil means that no emulation should be done and the modifiers
9463 should be placed on the mouse-1 event.
9464 t means that when the option-key is held down while pressing the mouse
9465 button, the click will register as mouse-2 and while the command-key
9466 is held down, the click will register as mouse-3.
9467 The symbol `reverse' means that the option-key will register for
9468 mouse-3 and the command-key will register for mouse-2. */);
9469 Vmac_emulate_three_button_mouse
= Qnil
;
9471 #if TARGET_API_MAC_CARBON
9472 DEFVAR_BOOL ("mac-wheel-button-is-mouse-2", &mac_wheel_button_is_mouse_2
,
9473 doc
: /* *Non-nil if the wheel button is mouse-2 and the right click mouse-3.
9474 Otherwise, the right click will be treated as mouse-2 and the wheel
9475 button will be mouse-3. */);
9476 mac_wheel_button_is_mouse_2
= 1;
9478 DEFVAR_BOOL ("mac-pass-command-to-system", &mac_pass_command_to_system
,
9479 doc
: /* *Non-nil if command key presses are passed on to the Mac Toolbox. */);
9480 mac_pass_command_to_system
= 1;
9482 DEFVAR_BOOL ("mac-pass-control-to-system", &mac_pass_control_to_system
,
9483 doc
: /* *Non-nil if control key presses are passed on to the Mac Toolbox. */);
9484 mac_pass_control_to_system
= 1;
9488 DEFVAR_BOOL ("mac-allow-anti-aliasing", &mac_use_core_graphics
,
9489 doc
: /* *If non-nil, allow anti-aliasing.
9490 The text will be rendered using Core Graphics text rendering which
9491 may anti-alias the text. */);
9493 mac_use_core_graphics
= 1;
9495 mac_use_core_graphics
= 0;
9498 /* Register an entry for `mac-roman' so that it can be used when
9499 creating the terminal frame on Mac OS 9 before loading
9500 term/mac-win.elc. */
9501 DEFVAR_LISP ("mac-charset-info-alist", &Vmac_charset_info_alist
,
9502 doc
: /* Alist of Emacs character sets vs text encodings and coding systems.
9503 Each entry should be of the form:
9505 (CHARSET-NAME TEXT-ENCODING CODING-SYSTEM)
9507 where CHARSET-NAME is a string used in font names to identify the
9508 charset, TEXT-ENCODING is a TextEncodingBase value in Mac, and
9509 CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */);
9510 Vmac_charset_info_alist
=
9511 Fcons (list3 (build_string ("mac-roman"),
9512 make_number (smRoman
), Qnil
), Qnil
);
9515 DEFVAR_LISP ("mac-ts-active-input-overlay", &Vmac_ts_active_input_overlay
,
9516 doc
: /* Overlay used to display Mac TSM active input area. */);
9517 Vmac_ts_active_input_overlay
= Qnil
;
9519 DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus
,
9520 doc
: /* *How to change Mac TSM script/language when a frame gets focus.
9521 If the value is t, the input script and language are restored to those
9522 used in the last focus frame. If the value is a pair of integers, the
9523 input script and language codes, which are defined in the Script
9524 Manager, are set to its car and cdr parts, respectively. Otherwise,
9525 Emacs doesn't set them and thus follows the system default behavior. */);
9526 Vmac_ts_script_language_on_focus
= Qnil
;
9530 /* arch-tag: f2259165-4454-4c04-a029-a133c8af7b5b
9531 (do not change this comment) */