diff options
| author | YAMAMOTO Mitsuharu | 2005-10-01 11:11:32 +0000 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2005-10-01 11:11:32 +0000 |
| commit | c3bd8190a26087ee8e6095b7b1f1a11ff5120125 (patch) | |
| tree | 0b8737a6b0753f8fa98d1baab5ece7bc0c8b75a2 /src | |
| parent | 04904a238eda88318e50c3d9b121ff492fb0cb72 (diff) | |
| download | emacs-c3bd8190a26087ee8e6095b7b1f1a11ff5120125.tar.gz emacs-c3bd8190a26087ee8e6095b7b1f1a11ff5120125.zip | |
(mac_draw_string_common, x_per_char_metric)
(mac_compute_glyph_string_overhangs, init_font_name_table)
(XLoadQueryFont, mac_unload_font) [USE_ATSUI]: Add ATSUI support.
(atsu_get_text_layout_with_text_ptr) [USE_ATSUI]: New function.
(x_draw_glyph_string_background)
(x_draw_glyph_string_foreground) [MAC_OS8 && USE_ATSUI]: Don't use
XDrawImageString. Always draw background and foreground separately.
(x_draw_glyph_string_foreground) [USE_ATSUI]: Don't use 8-bit
functions for one-byte chars when using ATSUI-compatible fonts.
(atsu_font_id_hash) [USE_ATSUI]: New variable.
(syms_of_macterm) [USE_ATSUI]: Initialize and staticpro it.
(XLoadQueryFont): Set min_byte1, max_byte1, min_char_or_byte2, and
max_char_or_byte2 more in detail.
(quit_char_comp, mac_check_for_quit_char) [MAC_OSX]: Remove functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/macterm.c | 657 |
1 files changed, 526 insertions, 131 deletions
diff --git a/src/macterm.c b/src/macterm.c index d1b5514f47d..6b37b190b1a 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -658,6 +658,62 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height) | |||
| 658 | #endif | 658 | #endif |
| 659 | 659 | ||
| 660 | 660 | ||
| 661 | #if USE_ATSUI | ||
| 662 | static OSStatus | ||
| 663 | atsu_get_text_layout_with_text_ptr (text, text_length, style, text_layout) | ||
| 664 | ConstUniCharArrayPtr text; | ||
| 665 | UniCharCount text_length; | ||
| 666 | ATSUStyle style; | ||
| 667 | ATSUTextLayout *text_layout; | ||
| 668 | { | ||
| 669 | OSStatus err; | ||
| 670 | static ATSUTextLayout saved_text_layout = NULL; /* not reentrant */ | ||
| 671 | |||
| 672 | if (saved_text_layout == NULL) | ||
| 673 | { | ||
| 674 | UniCharCount lengths[] = {kATSUToTextEnd}; | ||
| 675 | ATSUAttributeTag tags[] = {kATSULineLayoutOptionsTag}; | ||
| 676 | ByteCount sizes[] = {sizeof (ATSLineLayoutOptions)}; | ||
| 677 | static ATSLineLayoutOptions line_layout = | ||
| 678 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | ||
| 679 | kATSLineDisableAllLayoutOperations | kATSLineUseDeviceMetrics | ||
| 680 | #else | ||
| 681 | kATSLineIsDisplayOnly | ||
| 682 | #endif | ||
| 683 | ; | ||
| 684 | ATSUAttributeValuePtr values[] = {&line_layout}; | ||
| 685 | |||
| 686 | err = ATSUCreateTextLayoutWithTextPtr (text, | ||
| 687 | kATSUFromTextBeginning, | ||
| 688 | kATSUToTextEnd, | ||
| 689 | text_length, | ||
| 690 | 1, lengths, &style, | ||
| 691 | &saved_text_layout); | ||
| 692 | if (err == noErr) | ||
| 693 | err = ATSUSetLayoutControls (saved_text_layout, | ||
| 694 | sizeof (tags) / sizeof (tags[0]), | ||
| 695 | tags, sizes, values); | ||
| 696 | /* XXX: Should we do this? */ | ||
| 697 | if (err == noErr) | ||
| 698 | err = ATSUSetTransientFontMatching (saved_text_layout, true); | ||
| 699 | } | ||
| 700 | else | ||
| 701 | { | ||
| 702 | err = ATSUSetRunStyle (saved_text_layout, style, | ||
| 703 | kATSUFromTextBeginning, kATSUToTextEnd); | ||
| 704 | if (err == noErr) | ||
| 705 | err = ATSUSetTextPointerLocation (saved_text_layout, text, | ||
| 706 | kATSUFromTextBeginning, | ||
| 707 | kATSUToTextEnd, | ||
| 708 | text_length); | ||
| 709 | } | ||
| 710 | |||
| 711 | if (err == noErr) | ||
| 712 | *text_layout = saved_text_layout; | ||
| 713 | return err; | ||
| 714 | } | ||
| 715 | #endif | ||
| 716 | |||
| 661 | static void | 717 | static void |
| 662 | mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | 718 | mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, |
| 663 | bytes_per_char) | 719 | bytes_per_char) |
| @@ -682,6 +738,89 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 682 | if (mode != srcOr) | 738 | if (mode != srcOr) |
| 683 | RGBBackColor (GC_BACK_COLOR (gc)); | 739 | RGBBackColor (GC_BACK_COLOR (gc)); |
| 684 | 740 | ||
| 741 | #if USE_ATSUI | ||
| 742 | if (GC_FONT (gc)->mac_style) | ||
| 743 | { | ||
| 744 | OSErr err; | ||
| 745 | ATSUTextLayout text_layout; | ||
| 746 | |||
| 747 | xassert (bytes_per_char == 2); | ||
| 748 | |||
| 749 | #ifndef WORDS_BIG_ENDIAN | ||
| 750 | { | ||
| 751 | int i; | ||
| 752 | Unichar *text = (Unichar *)buf; | ||
| 753 | |||
| 754 | for (i = 0; i < nchars; i++) | ||
| 755 | text[i] = buf[2*i] << 8 | buf[2*i+1]; | ||
| 756 | } | ||
| 757 | #endif | ||
| 758 | err = atsu_get_text_layout_with_text_ptr ((ConstUniCharArrayPtr)buf, | ||
| 759 | nchars, | ||
| 760 | GC_FONT (gc)->mac_style, | ||
| 761 | &text_layout); | ||
| 762 | if (err == noErr) | ||
| 763 | { | ||
| 764 | #ifdef MAC_OSX | ||
| 765 | if (NILP (Vmac_use_core_graphics)) | ||
| 766 | { | ||
| 767 | #endif | ||
| 768 | MoveTo (x, y); | ||
| 769 | ATSUDrawText (text_layout, | ||
| 770 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 771 | kATSUUseGrafPortPenLoc, kATSUUseGrafPortPenLoc); | ||
| 772 | #ifdef MAC_OSX | ||
| 773 | } | ||
| 774 | else | ||
| 775 | { | ||
| 776 | CGrafPtr port; | ||
| 777 | CGContextRef context; | ||
| 778 | Rect rect; | ||
| 779 | RgnHandle region = NewRgn (); | ||
| 780 | float port_height; | ||
| 781 | ATSUAttributeTag tags[] = {kATSUCGContextTag}; | ||
| 782 | ByteCount sizes[] = {sizeof (CGContextRef)}; | ||
| 783 | ATSUAttributeValuePtr values[] = {&context}; | ||
| 784 | |||
| 785 | GetPort (&port); | ||
| 786 | QDBeginCGContext (port, &context); | ||
| 787 | GetPortBounds (port, &rect); | ||
| 788 | port_height = rect.bottom - rect.top; | ||
| 789 | GetClip (region); | ||
| 790 | GetRegionBounds (region, &rect); | ||
| 791 | /* XXX: This is not correct if the clip region is not a | ||
| 792 | simple rectangle. */ | ||
| 793 | CGContextClipToRect (context, | ||
| 794 | CGRectMake (rect.left, | ||
| 795 | port_height - rect.bottom, | ||
| 796 | rect.right - rect.left, | ||
| 797 | rect.bottom - rect.top)); | ||
| 798 | DisposeRgn (region); | ||
| 799 | CGContextSetRGBFillColor | ||
| 800 | (context, | ||
| 801 | RED_FROM_ULONG (gc->xgcv.foreground) / 255.0, | ||
| 802 | GREEN_FROM_ULONG (gc->xgcv.foreground) / 255.0, | ||
| 803 | BLUE_FROM_ULONG (gc->xgcv.foreground) / 255.0, | ||
| 804 | 1.0); | ||
| 805 | err = ATSUSetLayoutControls (text_layout, | ||
| 806 | sizeof (tags) / sizeof (tags[0]), | ||
| 807 | tags, sizes, values); | ||
| 808 | if (err == noErr) | ||
| 809 | ATSUDrawText (text_layout, | ||
| 810 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 811 | Long2Fix (x), Long2Fix (port_height - y)); | ||
| 812 | ATSUClearLayoutControls (text_layout, | ||
| 813 | sizeof (tags) / sizeof (tags[0]), | ||
| 814 | tags); | ||
| 815 | CGContextSynchronize (context); | ||
| 816 | QDEndCGContext (port, &context); | ||
| 817 | } | ||
| 818 | #endif | ||
| 819 | } | ||
| 820 | } | ||
| 821 | else | ||
| 822 | { | ||
| 823 | #endif | ||
| 685 | TextFont (GC_FONT (gc)->mac_fontnum); | 824 | TextFont (GC_FONT (gc)->mac_fontnum); |
| 686 | TextSize (GC_FONT (gc)->mac_fontsize); | 825 | TextSize (GC_FONT (gc)->mac_fontsize); |
| 687 | TextFace (GC_FONT (gc)->mac_fontface); | 826 | TextFace (GC_FONT (gc)->mac_fontface); |
| @@ -689,6 +828,9 @@ mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | |||
| 689 | 828 | ||
| 690 | MoveTo (x, y); | 829 | MoveTo (x, y); |
| 691 | DrawText (buf, 0, nchars * bytes_per_char); | 830 | DrawText (buf, 0, nchars * bytes_per_char); |
| 831 | #if USE_ATSUI | ||
| 832 | } | ||
| 833 | #endif | ||
| 692 | 834 | ||
| 693 | if (mode != srcOr) | 835 | if (mode != srcOr) |
| 694 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); | 836 | RGBBackColor (GC_BACK_COLOR (MAC_WINDOW_NORMAL_GC (w))); |
| @@ -1549,6 +1691,61 @@ x_per_char_metric (font, char2b) | |||
| 1549 | 1691 | ||
| 1550 | xassert (font && char2b); | 1692 | xassert (font && char2b); |
| 1551 | 1693 | ||
| 1694 | #if USE_ATSUI | ||
| 1695 | if (font->mac_style) | ||
| 1696 | { | ||
| 1697 | if (char2b->byte1 >= font->min_byte1 | ||
| 1698 | && char2b->byte1 <= font->max_byte1 | ||
| 1699 | && char2b->byte2 >= font->min_char_or_byte2 | ||
| 1700 | && char2b->byte2 <= font->max_char_or_byte2) | ||
| 1701 | { | ||
| 1702 | pcm = (font->per_char | ||
| 1703 | + ((font->max_char_or_byte2 - font->min_char_or_byte2 + 1) | ||
| 1704 | * (char2b->byte1 - font->min_byte1)) | ||
| 1705 | + (char2b->byte2 - font->min_char_or_byte2)); | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | if (pcm && !pcm->valid_p) | ||
| 1709 | { | ||
| 1710 | OSErr err; | ||
| 1711 | ATSUTextLayout text_layout; | ||
| 1712 | UniChar c; | ||
| 1713 | int char_width; | ||
| 1714 | ATSTrapezoid glyph_bounds; | ||
| 1715 | Rect char_bounds; | ||
| 1716 | |||
| 1717 | c = (char2b->byte1 << 8) + char2b->byte2; | ||
| 1718 | BLOCK_INPUT; | ||
| 1719 | err = atsu_get_text_layout_with_text_ptr (&c, 1, | ||
| 1720 | font->mac_style, | ||
| 1721 | &text_layout); | ||
| 1722 | if (err == noErr) | ||
| 1723 | err = ATSUMeasureTextImage (text_layout, | ||
| 1724 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 1725 | 0, 0, &char_bounds); | ||
| 1726 | |||
| 1727 | if (err == noErr) | ||
| 1728 | err = ATSUGetGlyphBounds (text_layout, 0, 0, | ||
| 1729 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 1730 | kATSUseFractionalOrigins, 1, | ||
| 1731 | &glyph_bounds, NULL); | ||
| 1732 | UNBLOCK_INPUT; | ||
| 1733 | if (err != noErr) | ||
| 1734 | pcm = NULL; | ||
| 1735 | else | ||
| 1736 | { | ||
| 1737 | xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x | ||
| 1738 | == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); | ||
| 1739 | |||
| 1740 | char_width = Fix2Long (glyph_bounds.upperRight.x | ||
| 1741 | - glyph_bounds.upperLeft.x); | ||
| 1742 | STORE_XCHARSTRUCT (*pcm, char_width, char_bounds); | ||
| 1743 | } | ||
| 1744 | } | ||
| 1745 | } | ||
| 1746 | else | ||
| 1747 | { | ||
| 1748 | #endif | ||
| 1552 | if (font->per_char != NULL) | 1749 | if (font->per_char != NULL) |
| 1553 | { | 1750 | { |
| 1554 | if (font->min_byte1 == 0 && font->max_byte1 == 0) | 1751 | if (font->min_byte1 == 0 && font->max_byte1 == 0) |
| @@ -1600,6 +1797,9 @@ x_per_char_metric (font, char2b) | |||
| 1600 | && char2b->byte2 <= font->max_char_or_byte2) | 1797 | && char2b->byte2 <= font->max_char_or_byte2) |
| 1601 | pcm = &font->max_bounds; | 1798 | pcm = &font->max_bounds; |
| 1602 | } | 1799 | } |
| 1800 | #if USE_ATSUI | ||
| 1801 | } | ||
| 1802 | #endif | ||
| 1603 | 1803 | ||
| 1604 | return ((pcm == NULL | 1804 | return ((pcm == NULL |
| 1605 | || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) | 1805 | || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) |
| @@ -1925,6 +2125,35 @@ mac_compute_glyph_string_overhangs (s) | |||
| 1925 | Rect r; | 2125 | Rect r; |
| 1926 | MacFontStruct *font = s->font; | 2126 | MacFontStruct *font = s->font; |
| 1927 | 2127 | ||
| 2128 | #if USE_ATSUI | ||
| 2129 | if (font->mac_style) | ||
| 2130 | { | ||
| 2131 | OSErr err; | ||
| 2132 | ATSUTextLayout text_layout; | ||
| 2133 | UniChar *buf; | ||
| 2134 | int i; | ||
| 2135 | |||
| 2136 | SetRect (&r, 0, 0, 0, 0); | ||
| 2137 | buf = xmalloc (sizeof (UniChar) * s->nchars); | ||
| 2138 | if (buf) | ||
| 2139 | { | ||
| 2140 | for (i = 0; i < s->nchars; i++) | ||
| 2141 | buf[i] = (s->char2b[i].byte1 << 8) + s->char2b[i].byte2; | ||
| 2142 | |||
| 2143 | err = atsu_get_text_layout_with_text_ptr (buf, s->nchars, | ||
| 2144 | font->mac_style, | ||
| 2145 | &text_layout); | ||
| 2146 | if (err == noErr) | ||
| 2147 | err = ATSUMeasureTextImage (text_layout, | ||
| 2148 | kATSUFromTextBeginning, | ||
| 2149 | kATSUToTextEnd, | ||
| 2150 | 0, 0, &r); | ||
| 2151 | xfree (buf); | ||
| 2152 | } | ||
| 2153 | } | ||
| 2154 | else | ||
| 2155 | { | ||
| 2156 | #endif | ||
| 1928 | TextFont (font->mac_fontnum); | 2157 | TextFont (font->mac_fontnum); |
| 1929 | TextSize (font->mac_fontsize); | 2158 | TextSize (font->mac_fontsize); |
| 1930 | TextFace (font->mac_fontface); | 2159 | TextFace (font->mac_fontface); |
| @@ -1946,6 +2175,9 @@ mac_compute_glyph_string_overhangs (s) | |||
| 1946 | xfree (buf); | 2175 | xfree (buf); |
| 1947 | } | 2176 | } |
| 1948 | } | 2177 | } |
| 2178 | #if USE_ATSUI | ||
| 2179 | } | ||
| 2180 | #endif | ||
| 1949 | 2181 | ||
| 1950 | s->right_overhang = r.right > s->width ? r.right - s->width : 0; | 2182 | s->right_overhang = r.right > s->width ? r.right - s->width : 0; |
| 1951 | s->left_overhang = r.left < 0 ? -r.left : 0; | 2183 | s->left_overhang = r.left < 0 ? -r.left : 0; |
| @@ -2003,7 +2235,7 @@ x_draw_glyph_string_background (s, force_p) | |||
| 2003 | } | 2235 | } |
| 2004 | else | 2236 | else |
| 2005 | #endif | 2237 | #endif |
| 2006 | #ifdef MAC_OS8 | 2238 | #if defined (MAC_OS8) && !USE_ATSUI |
| 2007 | if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width | 2239 | if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width |
| 2008 | || s->font_not_found_p | 2240 | || s->font_not_found_p |
| 2009 | || s->extends_to_end_of_line_p | 2241 | || s->extends_to_end_of_line_p |
| @@ -2057,11 +2289,15 @@ x_draw_glyph_string_foreground (s) | |||
| 2057 | boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff; | 2289 | boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff; |
| 2058 | 2290 | ||
| 2059 | /* If we can use 8-bit functions, condense S->char2b. */ | 2291 | /* If we can use 8-bit functions, condense S->char2b. */ |
| 2060 | if (!s->two_byte_p) | 2292 | if (!s->two_byte_p |
| 2293 | #if USE_ATSUI | ||
| 2294 | && GC_FONT (s->gc)->mac_style == NULL | ||
| 2295 | #endif | ||
| 2296 | ) | ||
| 2061 | for (i = 0; i < s->nchars; ++i) | 2297 | for (i = 0; i < s->nchars; ++i) |
| 2062 | char1b[i] = s->char2b[i].byte2; | 2298 | char1b[i] = s->char2b[i].byte2; |
| 2063 | 2299 | ||
| 2064 | #ifdef MAC_OS8 | 2300 | #if defined (MAC_OS8) && !USE_ATSUI |
| 2065 | /* Draw text with XDrawString if background has already been | 2301 | /* Draw text with XDrawString if background has already been |
| 2066 | filled. Otherwise, use XDrawImageString. (Note that | 2302 | filled. Otherwise, use XDrawImageString. (Note that |
| 2067 | XDrawImageString is usually faster than XDrawString.) Always | 2303 | XDrawImageString is usually faster than XDrawString.) Always |
| @@ -2072,14 +2308,18 @@ x_draw_glyph_string_foreground (s) | |||
| 2072 | #endif | 2308 | #endif |
| 2073 | { | 2309 | { |
| 2074 | /* Draw characters with 16-bit or 8-bit functions. */ | 2310 | /* Draw characters with 16-bit or 8-bit functions. */ |
| 2075 | if (s->two_byte_p) | 2311 | if (s->two_byte_p |
| 2312 | #if USE_ATSUI | ||
| 2313 | || GC_FONT (s->gc)->mac_style | ||
| 2314 | #endif | ||
| 2315 | ) | ||
| 2076 | XDrawString16 (s->display, s->window, s->gc, x, | 2316 | XDrawString16 (s->display, s->window, s->gc, x, |
| 2077 | s->ybase - boff, s->char2b, s->nchars); | 2317 | s->ybase - boff, s->char2b, s->nchars); |
| 2078 | else | 2318 | else |
| 2079 | XDrawString (s->display, s->window, s->gc, x, | 2319 | XDrawString (s->display, s->window, s->gc, x, |
| 2080 | s->ybase - boff, char1b, s->nchars); | 2320 | s->ybase - boff, char1b, s->nchars); |
| 2081 | } | 2321 | } |
| 2082 | #ifdef MAC_OS8 | 2322 | #if defined (MAC_OS8) && !USE_ATSUI |
| 2083 | else | 2323 | else |
| 2084 | { | 2324 | { |
| 2085 | if (s->two_byte_p) | 2325 | if (s->two_byte_p) |
| @@ -6431,6 +6671,10 @@ static char **font_name_table = NULL; | |||
| 6431 | static int font_name_table_size = 0; | 6671 | static int font_name_table_size = 0; |
| 6432 | static int font_name_count = 0; | 6672 | static int font_name_count = 0; |
| 6433 | 6673 | ||
| 6674 | #if USE_ATSUI | ||
| 6675 | static Lisp_Object atsu_font_id_hash; | ||
| 6676 | #endif | ||
| 6677 | |||
| 6434 | /* Alist linking character set strings to Mac text encoding and Emacs | 6678 | /* Alist linking character set strings to Mac text encoding and Emacs |
| 6435 | coding system. */ | 6679 | coding system. */ |
| 6436 | static Lisp_Object Vmac_charset_info_alist; | 6680 | static Lisp_Object Vmac_charset_info_alist; |
| @@ -6630,6 +6874,74 @@ init_font_name_table () | |||
| 6630 | Lisp_Object text_encoding_info_alist; | 6874 | Lisp_Object text_encoding_info_alist; |
| 6631 | struct gcpro gcpro1; | 6875 | struct gcpro gcpro1; |
| 6632 | 6876 | ||
| 6877 | text_encoding_info_alist = create_text_encoding_info_alist (); | ||
| 6878 | |||
| 6879 | #if USE_ATSUI | ||
| 6880 | if (!NILP (assq_no_quit (make_number (kTextEncodingMacUnicode), | ||
| 6881 | text_encoding_info_alist))) | ||
| 6882 | { | ||
| 6883 | OSErr err; | ||
| 6884 | ItemCount nfonts, i; | ||
| 6885 | ATSUFontID *font_ids = NULL; | ||
| 6886 | Ptr name, prev_name = NULL; | ||
| 6887 | ByteCount name_len; | ||
| 6888 | |||
| 6889 | atsu_font_id_hash = | ||
| 6890 | make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), | ||
| 6891 | make_float (DEFAULT_REHASH_SIZE), | ||
| 6892 | make_float (DEFAULT_REHASH_THRESHOLD), | ||
| 6893 | Qnil, Qnil, Qnil);; | ||
| 6894 | err = ATSUFontCount (&nfonts); | ||
| 6895 | if (err == noErr) | ||
| 6896 | font_ids = xmalloc (sizeof (ATSUFontID) * nfonts); | ||
| 6897 | if (font_ids) | ||
| 6898 | err = ATSUGetFontIDs (font_ids, nfonts, NULL); | ||
| 6899 | if (err == noErr) | ||
| 6900 | for (i = 0; i < nfonts; i++) | ||
| 6901 | { | ||
| 6902 | err = ATSUFindFontName (font_ids[i], kFontFamilyName, | ||
| 6903 | kFontMacintoshPlatform, kFontNoScript, | ||
| 6904 | kFontNoLanguage, 0, NULL, &name_len, NULL); | ||
| 6905 | if (err != noErr) | ||
| 6906 | continue; | ||
| 6907 | name = xmalloc (name_len + 1); | ||
| 6908 | if (name == NULL) | ||
| 6909 | continue; | ||
| 6910 | name[name_len] = '\0'; | ||
| 6911 | err = ATSUFindFontName (font_ids[i], kFontFamilyName, | ||
| 6912 | kFontMacintoshPlatform, kFontNoScript, | ||
| 6913 | kFontNoLanguage, name_len, name, | ||
| 6914 | NULL, NULL); | ||
| 6915 | if (err == noErr | ||
| 6916 | && *name != '.' | ||
| 6917 | && (prev_name == NULL | ||
| 6918 | || strcmp (name, prev_name) != 0)) | ||
| 6919 | { | ||
| 6920 | static char *cs = "iso10646-1"; | ||
| 6921 | |||
| 6922 | add_font_name_table_entry (mac_to_x_fontname (name, 0, | ||
| 6923 | normal, cs)); | ||
| 6924 | add_font_name_table_entry (mac_to_x_fontname (name, 0, | ||
| 6925 | italic, cs)); | ||
| 6926 | add_font_name_table_entry (mac_to_x_fontname (name, 0, | ||
| 6927 | bold, cs)); | ||
| 6928 | add_font_name_table_entry (mac_to_x_fontname (name, 0, | ||
| 6929 | italic | bold, cs)); | ||
| 6930 | Fputhash (Fdowncase (make_unibyte_string (name, name_len)), | ||
| 6931 | long_to_cons (font_ids[i]), atsu_font_id_hash); | ||
| 6932 | xfree (prev_name); | ||
| 6933 | prev_name = name; | ||
| 6934 | } | ||
| 6935 | else | ||
| 6936 | xfree (name); | ||
| 6937 | } | ||
| 6938 | if (prev_name) | ||
| 6939 | xfree (prev_name); | ||
| 6940 | if (font_ids) | ||
| 6941 | xfree (font_ids); | ||
| 6942 | } | ||
| 6943 | #endif | ||
| 6944 | |||
| 6633 | /* Create a dummy instance iterator here to avoid creating and | 6945 | /* Create a dummy instance iterator here to avoid creating and |
| 6634 | destroying it in the loop. */ | 6946 | destroying it in the loop. */ |
| 6635 | if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr) | 6947 | if (FMCreateFontFamilyInstanceIterator (0, &ffii) != noErr) |
| @@ -6642,8 +6954,6 @@ init_font_name_table () | |||
| 6642 | return; | 6954 | return; |
| 6643 | } | 6955 | } |
| 6644 | 6956 | ||
| 6645 | text_encoding_info_alist = create_text_encoding_info_alist (); | ||
| 6646 | |||
| 6647 | GCPRO1 (text_encoding_info_alist); | 6957 | GCPRO1 (text_encoding_info_alist); |
| 6648 | 6958 | ||
| 6649 | while (FMGetNextFontFamily (&ffi, &ff) == noErr) | 6959 | while (FMGetNextFontFamily (&ffi, &ff) == noErr) |
| @@ -7140,6 +7450,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7140 | Str255 mfontname, mfontname_decoded; | 7450 | Str255 mfontname, mfontname_decoded; |
| 7141 | Str31 charset; | 7451 | Str31 charset; |
| 7142 | SInt16 fontnum; | 7452 | SInt16 fontnum; |
| 7453 | #if USE_ATSUI | ||
| 7454 | ATSUStyle mac_style = NULL; | ||
| 7455 | #endif | ||
| 7143 | Style fontface; | 7456 | Style fontface; |
| 7144 | #if TARGET_API_MAC_CARBON | 7457 | #if TARGET_API_MAC_CARBON |
| 7145 | TextEncoding encoding; | 7458 | TextEncoding encoding; |
| @@ -7191,6 +7504,48 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7191 | 7504 | ||
| 7192 | x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded, | 7505 | x_font_name_to_mac_font_name (name, mfontname, mfontname_decoded, |
| 7193 | &fontface, charset); | 7506 | &fontface, charset); |
| 7507 | #if USE_ATSUI | ||
| 7508 | if (strcmp (charset, "iso10646-1") == 0) /* XXX */ | ||
| 7509 | { | ||
| 7510 | OSErr err; | ||
| 7511 | ATSUAttributeTag tags[] = {kATSUFontTag, kATSUSizeTag, | ||
| 7512 | kATSUQDBoldfaceTag, kATSUQDItalicTag}; | ||
| 7513 | ByteCount sizes[] = {sizeof (ATSUFontID), sizeof (Fixed), | ||
| 7514 | sizeof (Boolean), sizeof (Boolean)}; | ||
| 7515 | static ATSUFontID font_id; | ||
| 7516 | static Fixed size_fixed; | ||
| 7517 | static Boolean bold_p, italic_p; | ||
| 7518 | ATSUAttributeValuePtr values[] = {&font_id, &size_fixed, | ||
| 7519 | &bold_p, &italic_p}; | ||
| 7520 | ATSUFontFeatureType types[] = {kAllTypographicFeaturesType}; | ||
| 7521 | ATSUFontFeatureSelector selectors[] = {kAllTypeFeaturesOffSelector}; | ||
| 7522 | Lisp_Object font_id_cons; | ||
| 7523 | |||
| 7524 | font_id_cons = Fgethash (Fdowncase | ||
| 7525 | (make_unibyte_string (mfontname, | ||
| 7526 | strlen (mfontname))), | ||
| 7527 | atsu_font_id_hash, Qnil); | ||
| 7528 | if (NILP (font_id_cons)) | ||
| 7529 | return NULL; | ||
| 7530 | font_id = cons_to_long (font_id_cons); | ||
| 7531 | size_fixed = Long2Fix (size); | ||
| 7532 | bold_p = (fontface & bold) != 0; | ||
| 7533 | italic_p = (fontface & italic) != 0; | ||
| 7534 | err = ATSUCreateStyle (&mac_style); | ||
| 7535 | if (err != noErr) | ||
| 7536 | return NULL; | ||
| 7537 | err = ATSUSetFontFeatures (mac_style, sizeof (types) / sizeof (types[0]), | ||
| 7538 | types, selectors); | ||
| 7539 | if (err != noErr) | ||
| 7540 | return NULL; | ||
| 7541 | err = ATSUSetAttributes (mac_style, sizeof (tags) / sizeof (tags[0]), | ||
| 7542 | tags, sizes, values); | ||
| 7543 | fontnum = -1; | ||
| 7544 | scriptcode = kTextEncodingMacUnicode; | ||
| 7545 | } | ||
| 7546 | else | ||
| 7547 | { | ||
| 7548 | #endif | ||
| 7194 | c2pstr (mfontname); | 7549 | c2pstr (mfontname); |
| 7195 | #if TARGET_API_MAC_CARBON | 7550 | #if TARGET_API_MAC_CARBON |
| 7196 | fontnum = FMGetFontFamilyFromName (mfontname); | 7551 | fontnum = FMGetFontFamilyFromName (mfontname); |
| @@ -7204,6 +7559,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7204 | return NULL; | 7559 | return NULL; |
| 7205 | scriptcode = FontToScript (fontnum); | 7560 | scriptcode = FontToScript (fontnum); |
| 7206 | #endif | 7561 | #endif |
| 7562 | #if USE_ATSUI | ||
| 7563 | } | ||
| 7564 | #endif | ||
| 7207 | 7565 | ||
| 7208 | font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); | 7566 | font = (MacFontStruct *) xmalloc (sizeof (struct MacFontStruct)); |
| 7209 | 7567 | ||
| @@ -7211,6 +7569,9 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7211 | font->mac_fontsize = size; | 7569 | font->mac_fontsize = size; |
| 7212 | font->mac_fontface = fontface; | 7570 | font->mac_fontface = fontface; |
| 7213 | font->mac_scriptcode = scriptcode; | 7571 | font->mac_scriptcode = scriptcode; |
| 7572 | #if USE_ATSUI | ||
| 7573 | font->mac_style = mac_style; | ||
| 7574 | #endif | ||
| 7214 | 7575 | ||
| 7215 | /* Apple Japanese (SJIS) font is listed as both | 7576 | /* Apple Japanese (SJIS) font is listed as both |
| 7216 | "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0" | 7577 | "*-jisx0208.1983-sjis" (Japanese script) and "*-jisx0201.1976-0" |
| @@ -7221,6 +7582,91 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7221 | 7582 | ||
| 7222 | font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset); | 7583 | font->full_name = mac_to_x_fontname (mfontname_decoded, size, fontface, charset); |
| 7223 | 7584 | ||
| 7585 | #if USE_ATSUI | ||
| 7586 | if (font->mac_style) | ||
| 7587 | { | ||
| 7588 | OSErr err; | ||
| 7589 | ATSUTextLayout text_layout; | ||
| 7590 | UniChar c = 0x20; | ||
| 7591 | Rect char_bounds, min_bounds, max_bounds; | ||
| 7592 | int min_width, max_width; | ||
| 7593 | ATSTrapezoid glyph_bounds; | ||
| 7594 | |||
| 7595 | font->per_char = xmalloc (sizeof (XCharStruct) * 0x10000); | ||
| 7596 | if (font->per_char == NULL) | ||
| 7597 | { | ||
| 7598 | mac_unload_font (&one_mac_display_info, font); | ||
| 7599 | return NULL; | ||
| 7600 | } | ||
| 7601 | bzero (font->per_char, sizeof (XCharStruct) * 0x10000); | ||
| 7602 | |||
| 7603 | err = atsu_get_text_layout_with_text_ptr (&c, 1, | ||
| 7604 | font->mac_style, | ||
| 7605 | &text_layout); | ||
| 7606 | if (err != noErr) | ||
| 7607 | { | ||
| 7608 | mac_unload_font (&one_mac_display_info, font); | ||
| 7609 | return NULL; | ||
| 7610 | } | ||
| 7611 | |||
| 7612 | for (c = 0x20; c <= 0x7e; c++) | ||
| 7613 | { | ||
| 7614 | err = ATSUClearLayoutCache (text_layout, kATSUFromTextBeginning); | ||
| 7615 | if (err == noErr) | ||
| 7616 | err = ATSUMeasureTextImage (text_layout, | ||
| 7617 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 7618 | 0, 0, &char_bounds); | ||
| 7619 | if (err == noErr) | ||
| 7620 | err = ATSUGetGlyphBounds (text_layout, 0, 0, | ||
| 7621 | kATSUFromTextBeginning, kATSUToTextEnd, | ||
| 7622 | kATSUseFractionalOrigins, 1, | ||
| 7623 | &glyph_bounds, NULL); | ||
| 7624 | if (err == noErr) | ||
| 7625 | { | ||
| 7626 | xassert (glyph_bounds.lowerRight.x - glyph_bounds.lowerLeft.x | ||
| 7627 | == glyph_bounds.upperRight.x - glyph_bounds.upperLeft.x); | ||
| 7628 | |||
| 7629 | char_width = Fix2Long (glyph_bounds.upperRight.x | ||
| 7630 | - glyph_bounds.upperLeft.x); | ||
| 7631 | STORE_XCHARSTRUCT (font->per_char[c], | ||
| 7632 | char_width, char_bounds); | ||
| 7633 | if (c == 0x20) | ||
| 7634 | { | ||
| 7635 | min_width = max_width = char_width; | ||
| 7636 | min_bounds = max_bounds = char_bounds; | ||
| 7637 | font->ascent = -Fix2Long (glyph_bounds.upperLeft.y); | ||
| 7638 | font->descent = Fix2Long (glyph_bounds.lowerLeft.y); | ||
| 7639 | } | ||
| 7640 | else | ||
| 7641 | { | ||
| 7642 | if (char_width > 0) | ||
| 7643 | { | ||
| 7644 | min_width = min (min_width, char_width); | ||
| 7645 | max_width = max (max_width, char_width); | ||
| 7646 | } | ||
| 7647 | if (!EmptyRect (&char_bounds)) | ||
| 7648 | { | ||
| 7649 | SetRect (&min_bounds, | ||
| 7650 | max (min_bounds.left, char_bounds.left), | ||
| 7651 | max (min_bounds.top, char_bounds.top), | ||
| 7652 | min (min_bounds.right, char_bounds.right), | ||
| 7653 | min (min_bounds.bottom, char_bounds.bottom)); | ||
| 7654 | UnionRect (&max_bounds, &char_bounds, &max_bounds); | ||
| 7655 | } | ||
| 7656 | } | ||
| 7657 | } | ||
| 7658 | } | ||
| 7659 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); | ||
| 7660 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); | ||
| 7661 | |||
| 7662 | font->min_byte1 = 0; | ||
| 7663 | font->max_byte1 = 0xff; | ||
| 7664 | font->min_char_or_byte2 = 0; | ||
| 7665 | font->max_char_or_byte2 = 0xff; | ||
| 7666 | } | ||
| 7667 | else | ||
| 7668 | { | ||
| 7669 | #endif | ||
| 7224 | is_two_byte_font = font->mac_scriptcode == smJapanese || | 7670 | is_two_byte_font = font->mac_scriptcode == smJapanese || |
| 7225 | font->mac_scriptcode == smTradChinese || | 7671 | font->mac_scriptcode == smTradChinese || |
| 7226 | font->mac_scriptcode == smSimpChinese || | 7672 | font->mac_scriptcode == smSimpChinese || |
| @@ -7235,24 +7681,26 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7235 | font->ascent = the_fontinfo.ascent; | 7681 | font->ascent = the_fontinfo.ascent; |
| 7236 | font->descent = the_fontinfo.descent; | 7682 | font->descent = the_fontinfo.descent; |
| 7237 | 7683 | ||
| 7238 | font->min_byte1 = 0; | ||
| 7239 | if (is_two_byte_font) | ||
| 7240 | font->max_byte1 = 1; | ||
| 7241 | else | ||
| 7242 | font->max_byte1 = 0; | ||
| 7243 | font->min_char_or_byte2 = 0x20; | ||
| 7244 | font->max_char_or_byte2 = 0xff; | ||
| 7245 | |||
| 7246 | if (is_two_byte_font) | 7684 | if (is_two_byte_font) |
| 7247 | { | 7685 | { |
| 7686 | font->min_byte1 = 0xa1; | ||
| 7687 | font->max_byte1 = 0xfe; | ||
| 7688 | font->min_char_or_byte2 = 0xa1; | ||
| 7689 | font->max_char_or_byte2 = 0xfe; | ||
| 7690 | |||
| 7248 | /* Use the width of an "ideographic space" of that font because | 7691 | /* Use the width of an "ideographic space" of that font because |
| 7249 | the_fontinfo.widMax returns the wrong width for some fonts. */ | 7692 | the_fontinfo.widMax returns the wrong width for some fonts. */ |
| 7250 | switch (font->mac_scriptcode) | 7693 | switch (font->mac_scriptcode) |
| 7251 | { | 7694 | { |
| 7252 | case smJapanese: | 7695 | case smJapanese: |
| 7696 | font->min_byte1 = 0x81; | ||
| 7697 | font->max_byte1 = 0xfc; | ||
| 7698 | font->min_char_or_byte2 = 0x40; | ||
| 7699 | font->max_char_or_byte2 = 0xfc; | ||
| 7253 | char_width = StringWidth("\p\x81\x40"); | 7700 | char_width = StringWidth("\p\x81\x40"); |
| 7254 | break; | 7701 | break; |
| 7255 | case smTradChinese: | 7702 | case smTradChinese: |
| 7703 | font->min_char_or_byte2 = 0x40; | ||
| 7256 | char_width = StringWidth("\p\xa1\x40"); | 7704 | char_width = StringWidth("\p\xa1\x40"); |
| 7257 | break; | 7705 | break; |
| 7258 | case smSimpChinese: | 7706 | case smSimpChinese: |
| @@ -7264,9 +7712,15 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7264 | } | 7712 | } |
| 7265 | } | 7713 | } |
| 7266 | else | 7714 | else |
| 7267 | /* Do this instead of use the_fontinfo.widMax, which incorrectly | 7715 | { |
| 7268 | returns 15 for 12-point Monaco! */ | 7716 | font->min_byte1 = font->max_byte1 = 0; |
| 7269 | char_width = CharWidth ('m'); | 7717 | font->min_char_or_byte2 = 0x20; |
| 7718 | font->max_char_or_byte2 = 0xff; | ||
| 7719 | |||
| 7720 | /* Do this instead of use the_fontinfo.widMax, which incorrectly | ||
| 7721 | returns 15 for 12-point Monaco! */ | ||
| 7722 | char_width = CharWidth ('m'); | ||
| 7723 | } | ||
| 7270 | 7724 | ||
| 7271 | if (is_two_byte_font) | 7725 | if (is_two_byte_font) |
| 7272 | { | 7726 | { |
| @@ -7285,55 +7739,56 @@ XLoadQueryFont (Display *dpy, char *fontname) | |||
| 7285 | } | 7739 | } |
| 7286 | else | 7740 | else |
| 7287 | { | 7741 | { |
| 7288 | font->per_char = (XCharStruct *) | 7742 | int c, min_width, max_width; |
| 7289 | xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); | 7743 | Rect char_bounds, min_bounds, max_bounds; |
| 7290 | { | 7744 | char ch; |
| 7291 | int c, min_width, max_width; | 7745 | |
| 7292 | Rect char_bounds, min_bounds, max_bounds; | 7746 | font->per_char = xmalloc (sizeof (XCharStruct) * (0xff - 0x20 + 1)); |
| 7293 | char ch; | 7747 | |
| 7294 | 7748 | min_width = max_width = char_width; | |
| 7295 | min_width = max_width = char_width; | 7749 | SetRect (&min_bounds, -32767, -32767, 32767, 32767); |
| 7296 | SetRect (&min_bounds, -32767, -32767, 32767, 32767); | 7750 | SetRect (&max_bounds, 0, 0, 0, 0); |
| 7297 | SetRect (&max_bounds, 0, 0, 0, 0); | 7751 | for (c = 0x20; c <= 0xff; c++) |
| 7298 | for (c = 0x20; c <= 0xff; c++) | 7752 | { |
| 7299 | { | 7753 | ch = c; |
| 7300 | ch = c; | 7754 | char_width = CharWidth (ch); |
| 7301 | char_width = CharWidth (ch); | 7755 | QDTextBounds (1, &ch, &char_bounds); |
| 7302 | QDTextBounds (1, &ch, &char_bounds); | 7756 | STORE_XCHARSTRUCT (font->per_char[c - 0x20], |
| 7303 | STORE_XCHARSTRUCT (font->per_char[c - 0x20], | 7757 | char_width, char_bounds); |
| 7304 | char_width, char_bounds); | 7758 | /* Some Japanese fonts (in SJIS encoding) return 0 as the |
| 7305 | /* Some Japanese fonts (in SJIS encoding) return 0 as the | 7759 | character width of 0x7f. */ |
| 7306 | character width of 0x7f. */ | 7760 | if (char_width > 0) |
| 7307 | if (char_width > 0) | 7761 | { |
| 7308 | { | 7762 | min_width = min (min_width, char_width); |
| 7309 | min_width = min (min_width, char_width); | 7763 | max_width = max (max_width, char_width); |
| 7310 | max_width = max (max_width, char_width); | 7764 | } |
| 7311 | } | 7765 | if (!EmptyRect (&char_bounds)) |
| 7312 | if (!EmptyRect (&char_bounds)) | 7766 | { |
| 7313 | { | 7767 | SetRect (&min_bounds, |
| 7314 | SetRect (&min_bounds, | 7768 | max (min_bounds.left, char_bounds.left), |
| 7315 | max (min_bounds.left, char_bounds.left), | 7769 | max (min_bounds.top, char_bounds.top), |
| 7316 | max (min_bounds.top, char_bounds.top), | 7770 | min (min_bounds.right, char_bounds.right), |
| 7317 | min (min_bounds.right, char_bounds.right), | 7771 | min (min_bounds.bottom, char_bounds.bottom)); |
| 7318 | min (min_bounds.bottom, char_bounds.bottom)); | 7772 | UnionRect (&max_bounds, &char_bounds, &max_bounds); |
| 7319 | UnionRect (&max_bounds, &char_bounds, &max_bounds); | 7773 | } |
| 7320 | } | 7774 | } |
| 7321 | } | 7775 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); |
| 7322 | STORE_XCHARSTRUCT (font->min_bounds, min_width, min_bounds); | 7776 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); |
| 7323 | STORE_XCHARSTRUCT (font->max_bounds, max_width, max_bounds); | 7777 | if (min_width == max_width |
| 7324 | if (min_width == max_width | 7778 | && max_bounds.left >= 0 && max_bounds.right <= max_width) |
| 7325 | && max_bounds.left >= 0 && max_bounds.right <= max_width) | 7779 | { |
| 7326 | { | 7780 | /* Fixed width and no overhangs. */ |
| 7327 | /* Fixed width and no overhangs. */ | 7781 | xfree (font->per_char); |
| 7328 | xfree (font->per_char); | 7782 | font->per_char = NULL; |
| 7329 | font->per_char = NULL; | 7783 | } |
| 7330 | } | ||
| 7331 | } | ||
| 7332 | } | 7784 | } |
| 7333 | 7785 | ||
| 7334 | TextFont (old_fontnum); /* restore previous font number, size and face */ | 7786 | TextFont (old_fontnum); /* restore previous font number, size and face */ |
| 7335 | TextSize (old_fontsize); | 7787 | TextSize (old_fontsize); |
| 7336 | TextFace (old_fontface); | 7788 | TextFace (old_fontface); |
| 7789 | #if USE_ATSUI | ||
| 7790 | } | ||
| 7791 | #endif | ||
| 7337 | 7792 | ||
| 7338 | return font; | 7793 | return font; |
| 7339 | } | 7794 | } |
| @@ -7347,6 +7802,10 @@ mac_unload_font (dpyinfo, font) | |||
| 7347 | xfree (font->full_name); | 7802 | xfree (font->full_name); |
| 7348 | if (font->per_char) | 7803 | if (font->per_char) |
| 7349 | xfree (font->per_char); | 7804 | xfree (font->per_char); |
| 7805 | #if USE_ATSUI | ||
| 7806 | if (font->mac_style) | ||
| 7807 | ATSUDisposeStyle (font->mac_style); | ||
| 7808 | #endif | ||
| 7350 | xfree (font); | 7809 | xfree (font); |
| 7351 | } | 7810 | } |
| 7352 | 7811 | ||
| @@ -10189,75 +10648,6 @@ init_quit_char_handler () | |||
| 10189 | 10648 | ||
| 10190 | mac_determine_quit_char_modifiers(); | 10649 | mac_determine_quit_char_modifiers(); |
| 10191 | } | 10650 | } |
| 10192 | |||
| 10193 | static Boolean | ||
| 10194 | quit_char_comp (EventRef inEvent, void *inCompData) | ||
| 10195 | { | ||
| 10196 | if (GetEventClass(inEvent) != kEventClassKeyboard) | ||
| 10197 | return false; | ||
| 10198 | if (GetEventKind(inEvent) != kEventRawKeyDown) | ||
| 10199 | return false; | ||
| 10200 | { | ||
| 10201 | UInt32 keyCode; | ||
| 10202 | UInt32 keyModifiers; | ||
| 10203 | GetEventParameter(inEvent, kEventParamKeyCode, | ||
| 10204 | typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode); | ||
| 10205 | if (keyCode != mac_quit_char_keycode) | ||
| 10206 | return false; | ||
| 10207 | GetEventParameter(inEvent, kEventParamKeyModifiers, | ||
| 10208 | typeUInt32, NULL, sizeof(UInt32), NULL, &keyModifiers); | ||
| 10209 | if (keyModifiers != mac_quit_char_modifiers) | ||
| 10210 | return false; | ||
| 10211 | } | ||
| 10212 | return true; | ||
| 10213 | } | ||
| 10214 | |||
| 10215 | void | ||
| 10216 | mac_check_for_quit_char () | ||
| 10217 | { | ||
| 10218 | EventRef event; | ||
| 10219 | static EMACS_TIME last_check_time = { 0, 0 }; | ||
| 10220 | static EMACS_TIME one_second = { 1, 0 }; | ||
| 10221 | EMACS_TIME now, t; | ||
| 10222 | |||
| 10223 | /* If windows are not initialized, return immediately (keep it bouncin'). */ | ||
| 10224 | if (!mac_quit_char_modifiers) | ||
| 10225 | return; | ||
| 10226 | |||
| 10227 | /* Don't check if last check is less than a second ago. */ | ||
| 10228 | EMACS_GET_TIME (now); | ||
| 10229 | EMACS_SUB_TIME (t, now, last_check_time); | ||
| 10230 | if (EMACS_TIME_LT (t, one_second)) | ||
| 10231 | return; | ||
| 10232 | last_check_time = now; | ||
| 10233 | |||
| 10234 | /* Redetermine modifiers because they are based on lisp variables */ | ||
| 10235 | mac_determine_quit_char_modifiers (); | ||
| 10236 | |||
| 10237 | /* Fill the queue with events */ | ||
| 10238 | BLOCK_INPUT; | ||
| 10239 | ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &event); | ||
| 10240 | event = FindSpecificEventInQueue (GetMainEventQueue (), quit_char_comp, | ||
| 10241 | NULL); | ||
| 10242 | UNBLOCK_INPUT; | ||
| 10243 | if (event) | ||
| 10244 | { | ||
| 10245 | struct input_event e; | ||
| 10246 | |||
| 10247 | /* Use an input_event to emulate what the interrupt handler does. */ | ||
| 10248 | EVENT_INIT (e); | ||
| 10249 | e.kind = ASCII_KEYSTROKE_EVENT; | ||
| 10250 | e.code = quit_char; | ||
| 10251 | e.arg = Qnil; | ||
| 10252 | e.modifiers = NULL; | ||
| 10253 | e.timestamp = EventTimeToTicks (GetEventTime (event)) * (1000/60); | ||
| 10254 | XSETFRAME (e.frame_or_window, mac_focus_frame (&one_mac_display_info)); | ||
| 10255 | /* Remove event from queue to prevent looping. */ | ||
| 10256 | RemoveEventFromQueue (GetMainEventQueue (), event); | ||
| 10257 | ReleaseEvent (event); | ||
| 10258 | kbd_buffer_store_event (&e); | ||
| 10259 | } | ||
| 10260 | } | ||
| 10261 | #endif /* MAC_OSX */ | 10651 | #endif /* MAC_OSX */ |
| 10262 | 10652 | ||
| 10263 | static void | 10653 | static void |
| @@ -10435,6 +10825,11 @@ syms_of_macterm () | |||
| 10435 | Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); | 10825 | Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); |
| 10436 | staticpro (&Qmac_ready_for_drag_n_drop); | 10826 | staticpro (&Qmac_ready_for_drag_n_drop); |
| 10437 | 10827 | ||
| 10828 | #if USE_ATSUI | ||
| 10829 | staticpro (&atsu_font_id_hash); | ||
| 10830 | atsu_font_id_hash = Qnil; | ||
| 10831 | #endif | ||
| 10832 | |||
| 10438 | DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, | 10833 | DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, |
| 10439 | doc: /* If not nil, Emacs uses toolkit scroll bars. */); | 10834 | doc: /* If not nil, Emacs uses toolkit scroll bars. */); |
| 10440 | #ifdef USE_TOOLKIT_SCROLL_BARS | 10835 | #ifdef USE_TOOLKIT_SCROLL_BARS |