aboutsummaryrefslogtreecommitdiffstats
path: root/src/macterm.c
diff options
context:
space:
mode:
authorSteven Tamm2004-02-26 17:46:48 +0000
committerSteven Tamm2004-02-26 17:46:48 +0000
commite35644615b2a506daa457cbc5613ba8d16a46be6 (patch)
treec9a8a5555b8bffd7808612c10958a1cd96a7a75f /src/macterm.c
parentaf617d0febe392e1d55978df89a73f6c2fca74d4 (diff)
downloademacs-e35644615b2a506daa457cbc5613ba8d16a46be6.tar.gz
emacs-e35644615b2a506daa457cbc5613ba8d16a46be6.zip
Inserting Yamomotosan's changes for MacOSX image support, better support
of Asian fonts, and some long awaited header cleanup and centralization.
Diffstat (limited to 'src/macterm.c')
-rw-r--r--src/macterm.c1050
1 files changed, 757 insertions, 293 deletions
diff --git a/src/macterm.c b/src/macterm.c
index f6e5414c299..a22a1cfafe8 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -35,29 +35,6 @@ Boston, MA 02111-1307, USA. */
35#endif 35#endif
36 36
37#ifdef MAC_OSX 37#ifdef MAC_OSX
38#undef mktime
39#undef DEBUG
40#undef free
41#undef malloc
42#undef realloc
43/* Macros max and min defined in lisp.h conflict with those in
44 precompiled header Carbon.h. */
45#undef max
46#undef min
47#undef init_process
48#include <Carbon/Carbon.h>
49#undef free
50#define free unexec_free
51#undef malloc
52#define malloc unexec_malloc
53#undef realloc
54#define realloc unexec_realloc
55#undef min
56#define min(a, b) ((a) < (b) ? (a) : (b))
57#undef max
58#define max(a, b) ((a) > (b) ? (a) : (b))
59#undef init_process
60#define init_process emacs_init_process
61/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to 38/* USE_CARBON_EVENTS determines if the Carbon Event Manager is used to
62 obtain events from the event queue. If set to 0, WaitNextEvent is 39 obtain events from the event queue. If set to 0, WaitNextEvent is
63 used instead. */ 40 used instead. */
@@ -303,7 +280,9 @@ static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
303static void XTframe_rehighlight P_ ((struct frame *)); 280static void XTframe_rehighlight P_ ((struct frame *));
304static void x_frame_rehighlight P_ ((struct x_display_info *)); 281static void x_frame_rehighlight P_ ((struct x_display_info *));
305static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); 282static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
306static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); 283static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
284 enum text_cursor_kinds));
285
307static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); 286static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC));
308static void x_flush P_ ((struct frame *f)); 287static void x_flush P_ ((struct frame *f));
309static void x_update_begin P_ ((struct frame *)); 288static void x_update_begin P_ ((struct frame *));
@@ -327,15 +306,12 @@ extern void set_frame_menubar (FRAME_PTR, int, int);
327 306
328/* X display function emulation */ 307/* X display function emulation */
329 308
330static void 309void
331XFreePixmap (display, pixmap) 310XFreePixmap (display, pixmap)
332 Display *display; 311 Display *display; /* not used */
333 Pixmap pixmap; 312 Pixmap pixmap;
334{ 313{
335 PixMap *p = (PixMap *) pixmap; 314 DisposeGWorld (pixmap);
336
337 xfree (p->baseAddr);
338 xfree (p);
339} 315}
340 316
341 317
@@ -347,9 +323,9 @@ mac_set_forecolor (unsigned long color)
347{ 323{
348 RGBColor fg_color; 324 RGBColor fg_color;
349 325
350 fg_color.red = RED_FROM_ULONG (color) * 256; 326 fg_color.red = RED16_FROM_ULONG (color);
351 fg_color.green = GREEN_FROM_ULONG (color) * 256; 327 fg_color.green = GREEN16_FROM_ULONG (color);
352 fg_color.blue = BLUE_FROM_ULONG (color) * 256; 328 fg_color.blue = BLUE16_FROM_ULONG (color);
353 329
354 RGBForeColor (&fg_color); 330 RGBForeColor (&fg_color);
355} 331}
@@ -363,9 +339,9 @@ mac_set_backcolor (unsigned long color)
363{ 339{
364 RGBColor bg_color; 340 RGBColor bg_color;
365 341
366 bg_color.red = RED_FROM_ULONG (color) * 256; 342 bg_color.red = RED16_FROM_ULONG (color);
367 bg_color.green = GREEN_FROM_ULONG (color) * 256; 343 bg_color.green = GREEN16_FROM_ULONG (color);
368 bg_color.blue = BLUE_FROM_ULONG (color) * 256; 344 bg_color.blue = BLUE16_FROM_ULONG (color);
369 345
370 RGBBackColor (&bg_color); 346 RGBBackColor (&bg_color);
371} 347}
@@ -401,6 +377,23 @@ XDrawLine (display, w, gc, x1, y1, x2, y2)
401 LineTo (x2, y2); 377 LineTo (x2, y2);
402} 378}
403 379
380void
381mac_draw_line_to_pixmap (display, p, gc, x1, y1, x2, y2)
382 Display *display;
383 Pixmap p;
384 GC gc;
385 int x1, y1, x2, y2;
386{
387 SetGWorld (p, NULL);
388
389 mac_set_colors (gc);
390
391 LockPixels (GetGWorldPixMap (p));
392 MoveTo (x1, y1);
393 LineTo (x2, y2);
394 UnlockPixels (GetGWorldPixMap (p));
395}
396
404/* Mac version of XClearArea. */ 397/* Mac version of XClearArea. */
405 398
406void 399void
@@ -479,7 +472,7 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
479 Rect r; 472 Rect r;
480 473
481 bitmap.rowBytes = sizeof(unsigned short); 474 bitmap.rowBytes = sizeof(unsigned short);
482 bitmap.baseAddr = bits; 475 bitmap.baseAddr = (char *)bits;
483 SetRect (&(bitmap.bounds), 0, 0, width, height); 476 SetRect (&(bitmap.bounds), 0, 0, width, height);
484 477
485#if TARGET_API_MAC_CARBON 478#if TARGET_API_MAC_CARBON
@@ -489,18 +482,13 @@ mac_draw_bitmap (display, w, gc, x, y, width, height, bits, overlay_p)
489#endif 482#endif
490 483
491 mac_set_colors (gc); 484 mac_set_colors (gc);
492 SetRect (&r, x, y, x + bitmap.bounds.right, y + bitmap.bounds.bottom); 485 SetRect (&r, x, y, x + width, y + height);
493 486
494#if TARGET_API_MAC_CARBON 487#if TARGET_API_MAC_CARBON
495 { 488 LockPortBits (GetWindowPort (w));
496 PixMapHandle pmh; 489 CopyBits (&bitmap, GetPortBitMapForCopyBits (GetWindowPort (w)),
497 490 &(bitmap.bounds), &r, overlay_p ? srcOr : srcCopy, 0);
498 LockPortBits (GetWindowPort (w)); 491 UnlockPortBits (GetWindowPort (w));
499 pmh = GetPortPixMap (GetWindowPort (w));
500 CopyBits (&bitmap, (BitMap *) *pmh, &(bitmap.bounds), &r,
501 overlay_p ? srcOr : srcCopy, 0);
502 UnlockPortBits (GetWindowPort (w));
503 }
504#else /* not TARGET_API_MAC_CARBON */ 492#else /* not TARGET_API_MAC_CARBON */
505 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r, 493 CopyBits (&bitmap, &(w->portBits), &(bitmap.bounds), &r,
506 overlay_p ? srcOr : srcCopy, 0); 494 overlay_p ? srcOr : srcCopy, 0);
@@ -546,6 +534,23 @@ mac_reset_clipping (display, w)
546} 534}
547 535
548 536
537/* XBM bits seem to be backward within bytes compared with how
538 Mac does things. */
539static unsigned char
540reflect_byte (orig)
541 unsigned char orig;
542{
543 int i;
544 unsigned char reflected = 0x00;
545 for (i = 0; i < 8; i++)
546 {
547 if (orig & (0x01 << i))
548 reflected |= 0x80 >> i;
549 }
550 return reflected;
551}
552
553
549/* Mac replacement for XCreateBitmapFromBitmapData. */ 554/* Mac replacement for XCreateBitmapFromBitmapData. */
550 555
551static void 556static void
@@ -554,18 +559,19 @@ mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h)
554 char *bits; 559 char *bits;
555 int w, h; 560 int w, h;
556{ 561{
557 int bytes_per_row, i, j; 562 int i, j, w1;
563 char *p;
558 564
559 bitmap->rowBytes = (w + 15) / 16 * 2; /* must be on word boundary */ 565 w1 = (w + 7) / 8; /* nb of 8bits elt in X bitmap */
566 bitmap->rowBytes = ((w + 15) / 16) * 2; /* nb of 16bits elt in Mac bitmap */
560 bitmap->baseAddr = xmalloc (bitmap->rowBytes * h); 567 bitmap->baseAddr = xmalloc (bitmap->rowBytes * h);
561 if (!bitmap->baseAddr)
562 abort ();
563
564 bzero (bitmap->baseAddr, bitmap->rowBytes * h); 568 bzero (bitmap->baseAddr, bitmap->rowBytes * h);
565 for (i = 0; i < h; i++) 569 for (i = 0; i < h; i++)
566 for (j = 0; j < w; j++) 570 {
567 if (BitTst (bits, i * w + j)) 571 p = bitmap->baseAddr + i * bitmap->rowBytes;
568 BitSet (bitmap->baseAddr, i * bitmap->rowBytes * 8 + j); 572 for (j = 0; j < w1; j++)
573 *p++ = reflect_byte (*bits++);
574 }
569 575
570 SetRect (&(bitmap->bounds), 0, 0, w, h); 576 SetRect (&(bitmap->bounds), 0, 0, w, h);
571} 577}
@@ -578,6 +584,67 @@ mac_free_bitmap (bitmap)
578 xfree (bitmap->baseAddr); 584 xfree (bitmap->baseAddr);
579} 585}
580 586
587
588Pixmap
589XCreatePixmap (display, w, width, height, depth)
590 Display *display; /* not used */
591 WindowPtr w;
592 unsigned int width, height;
593 unsigned int depth; /* not used */
594{
595 Pixmap pixmap;
596 Rect r;
597 QDErr err;
598
599#if TARGET_API_MAC_CARBON
600 SetPort (GetWindowPort (w));
601#else
602 SetPort (w);
603#endif
604
605 SetRect (&r, 0, 0, width, height);
606 err = NewGWorld (&pixmap, depth, &r, NULL, NULL, 0);
607 if (err != noErr)
608 return NULL;
609 return pixmap;
610}
611
612
613Pixmap
614XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
615 Display *display; /* not used */
616 WindowPtr w;
617 char *data;
618 unsigned int width, height;
619 unsigned long fg, bg;
620 unsigned int depth; /* not used */
621{
622 Pixmap pixmap;
623 BitMap bitmap;
624
625 pixmap = XCreatePixmap (display, w, width, height, depth);
626 if (pixmap == NULL)
627 return NULL;
628
629 SetGWorld (pixmap, NULL);
630 mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height);
631 mac_set_forecolor (fg);
632 mac_set_backcolor (bg);
633 LockPixels (GetGWorldPixMap (pixmap));
634#if TARGET_API_MAC_CARBON
635 CopyBits (&bitmap, GetPortBitMapForCopyBits (pixmap),
636 &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
637#else /* not TARGET_API_MAC_CARBON */
638 CopyBits (&bitmap, &(((GrafPtr)pixmap)->portBits),
639 &bitmap.bounds, &bitmap.bounds, srcCopy, 0);
640#endif /* not TARGET_API_MAC_CARBON */
641 UnlockPixels (GetGWorldPixMap (pixmap));
642 mac_free_bitmap (&bitmap);
643
644 return pixmap;
645}
646
647
581/* Mac replacement for XFillRectangle. */ 648/* Mac replacement for XFillRectangle. */
582 649
583static void 650static void
@@ -603,6 +670,26 @@ XFillRectangle (display, w, gc, x, y, width, height)
603} 670}
604 671
605 672
673static void
674mac_fill_rectangle_to_pixmap (display, p, gc, x, y, width, height)
675 Display *display;
676 Pixmap p;
677 GC gc;
678 int x, y;
679 unsigned int width, height;
680{
681 Rect r;
682
683 SetGWorld (p, NULL);
684 mac_set_colors (gc);
685 SetRect (&r, x, y, x + width, y + height);
686
687 LockPixels (GetGWorldPixMap (p));
688 PaintRect (&r); /* using foreground color of gc */
689 UnlockPixels (GetGWorldPixMap (p));
690}
691
692
606/* Mac replacement for XDrawRectangle: dest is a window. */ 693/* Mac replacement for XDrawRectangle: dest is a window. */
607 694
608static void 695static void
@@ -638,20 +725,15 @@ mac_draw_rectangle_to_pixmap (display, p, gc, x, y, width, height)
638 int x, y; 725 int x, y;
639 unsigned int width, height; 726 unsigned int width, height;
640{ 727{
641#if 0 /* MAC_TODO: draw a rectangle in a PixMap */
642 Rect r; 728 Rect r;
643 729
644#if TARGET_API_MAC_CARBON 730 SetGWorld (p, NULL);
645 SetPort (GetWindowPort (w));
646#else
647 SetPort (w);
648#endif
649
650 mac_set_colors (gc); 731 mac_set_colors (gc);
651 SetRect (&r, x, y, x + width, y + height); 732 SetRect (&r, x, y, x + width + 1, y + height + 1);
652 733
734 LockPixels (GetGWorldPixMap (p));
653 FrameRect (&r); /* using foreground color of gc */ 735 FrameRect (&r); /* using foreground color of gc */
654#endif /* 0 */ 736 UnlockPixels (GetGWorldPixMap (p));
655} 737}
656 738
657 739
@@ -766,23 +848,66 @@ mac_copy_area (display, src, dest, gc, src_x, src_y, width, height, dest_x,
766 SetPort (dest); 848 SetPort (dest);
767#endif 849#endif
768 850
769 mac_set_colors (gc);
770
771 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); 851 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
772 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 852 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
773 853
854 ForeColor (blackColor);
855 BackColor (whiteColor);
856
857 LockPixels (GetGWorldPixMap (src));
774#if TARGET_API_MAC_CARBON 858#if TARGET_API_MAC_CARBON
775 { 859 LockPortBits (GetWindowPort (dest));
776 PixMapHandle pmh; 860 CopyBits (GetPortBitMapForCopyBits (src),
861 GetPortBitMapForCopyBits (GetWindowPort (dest)),
862 &src_r, &dest_r, srcCopy, 0);
863 UnlockPortBits (GetWindowPort (dest));
864#else /* not TARGET_API_MAC_CARBON */
865 CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits),
866 &src_r, &dest_r, srcCopy, 0);
867#endif /* not TARGET_API_MAC_CARBON */
868 UnlockPixels (GetGWorldPixMap (src));
869}
777 870
778 LockPortBits (GetWindowPort (dest)); 871
779 pmh = GetPortPixMap (GetWindowPort (dest)); 872static void
780 CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); 873mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y,
781 UnlockPortBits (GetWindowPort (dest)); 874 width, height, dest_x, dest_y)
782 } 875 Display *display;
876 Pixmap src, mask;
877 WindowPtr dest;
878 GC gc;
879 int src_x, src_y;
880 unsigned int width, height;
881 int dest_x, dest_y;
882{
883 Rect src_r, dest_r;
884
885#if TARGET_API_MAC_CARBON
886 SetPort (GetWindowPort (dest));
887#else
888 SetPort (dest);
889#endif
890
891 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
892 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
893
894 ForeColor (blackColor);
895 BackColor (whiteColor);
896
897 LockPixels (GetGWorldPixMap (src));
898 LockPixels (GetGWorldPixMap (mask));
899#if TARGET_API_MAC_CARBON
900 LockPortBits (GetWindowPort (dest));
901 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
902 GetPortBitMapForCopyBits (GetWindowPort (dest)),
903 &src_r, &src_r, &dest_r);
904 UnlockPortBits (GetWindowPort (dest));
783#else /* not TARGET_API_MAC_CARBON */ 905#else /* not TARGET_API_MAC_CARBON */
784 CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0); 906 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
907 &(dest->portBits), &src_r, &src_r, &dest_r);
785#endif /* not TARGET_API_MAC_CARBON */ 908#endif /* not TARGET_API_MAC_CARBON */
909 UnlockPixels (GetGWorldPixMap (mask));
910 UnlockPixels (GetGWorldPixMap (src));
786} 911}
787 912
788 913
@@ -817,7 +942,6 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
817{ 942{
818#if TARGET_API_MAC_CARBON 943#if TARGET_API_MAC_CARBON
819 Rect gw_r, src_r, dest_r; 944 Rect gw_r, src_r, dest_r;
820 PixMapHandle pmh;
821 945
822 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); 946 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
823 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); 947 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
@@ -828,8 +952,10 @@ mac_scroll_area (display, w, gc, src_x, src_y, width, height, dest_x, dest_y)
828 BackColor (whiteColor); 952 BackColor (whiteColor);
829 953
830 LockPortBits (GetWindowPort (w)); 954 LockPortBits (GetWindowPort (w));
831 pmh = GetPortPixMap (GetWindowPort (w)); 955 {
832 CopyBits ((BitMap *) *pmh, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); 956 const BitMap *bitmap = GetPortBitMapForCopyBits (GetWindowPort (w));
957 CopyBits (bitmap, bitmap, &src_r, &dest_r, srcCopy, 0);
958 }
833 UnlockPortBits (GetWindowPort (w)); 959 UnlockPortBits (GetWindowPort (w));
834 960
835 mac_set_colors (gc); 961 mac_set_colors (gc);
@@ -872,25 +998,67 @@ static void
872mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height, 998mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height,
873 dest_x, dest_y) 999 dest_x, dest_y)
874 Display *display; 1000 Display *display;
875 Pixmap src; 1001 Pixmap src, dest;
876 Pixmap dest;
877 GC gc; 1002 GC gc;
878 int src_x, src_y; 1003 int src_x, src_y;
879 unsigned int width, height; 1004 unsigned int width, height;
880 int dest_x, dest_y; 1005 int dest_x, dest_y;
881{ 1006{
882 Rect src_r, dest_r; 1007 Rect src_r, dest_r;
883 int src_right = ((PixMap *) src)->bounds.right;
884 int src_bottom = ((PixMap *) src)->bounds.bottom;
885 int w = src_right - src_x;
886 int h = src_bottom - src_y;
887 1008
888 mac_set_colors (gc); 1009 SetGWorld (dest, NULL);
1010 ForeColor (blackColor);
1011 BackColor (whiteColor);
1012
1013 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
1014 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
1015
1016 LockPixels (GetGWorldPixMap (src));
1017 LockPixels (GetGWorldPixMap (dest));
1018#if TARGET_API_MAC_CARBON
1019 CopyBits (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (dest),
1020 &src_r, &dest_r, srcCopy, 0);
1021#else /* not TARGET_API_MAC_CARBON */
1022 CopyBits (&(((GrafPtr)src)->portBits), &(((GrafPtr)dest)->portBits),
1023 &src_r, &dest_r, srcCopy, 0);
1024#endif /* not TARGET_API_MAC_CARBON */
1025 UnlockPixels (GetGWorldPixMap (dest));
1026 UnlockPixels (GetGWorldPixMap (src));
1027}
1028
1029
1030static void
1031mac_copy_area_with_mask_to_pixmap (display, src, mask, dest, gc, src_x, src_y,
1032 width, height, dest_x, dest_y)
1033 Display *display;
1034 Pixmap src, mask, dest;
1035 GC gc;
1036 int src_x, src_y;
1037 unsigned int width, height;
1038 int dest_x, dest_y;
1039{
1040 Rect src_r, dest_r;
1041
1042 SetGWorld (dest, NULL);
1043 ForeColor (blackColor);
1044 BackColor (whiteColor);
889 1045
890 SetRect (&src_r, src_x, src_y, src_right, src_bottom); 1046 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height);
891 SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h); 1047 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height);
892 1048
893 CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0); 1049 LockPixels (GetGWorldPixMap (src));
1050 LockPixels (GetGWorldPixMap (mask));
1051 LockPixels (GetGWorldPixMap (dest));
1052#if TARGET_API_MAC_CARBON
1053 CopyMask (GetPortBitMapForCopyBits (src), GetPortBitMapForCopyBits (mask),
1054 GetPortBitMapForCopyBits (dest), &src_r, &src_r, &dest_r);
1055#else /* not TARGET_API_MAC_CARBON */
1056 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits),
1057 &(((GrafPtr)dest)->portBits), &src_r, &src_r, &dest_r);
1058#endif /* not TARGET_API_MAC_CARBON */
1059 UnlockPixels (GetGWorldPixMap (dest));
1060 UnlockPixels (GetGWorldPixMap (mask));
1061 UnlockPixels (GetGWorldPixMap (src));
894} 1062}
895 1063
896 1064
@@ -947,7 +1115,7 @@ XGetGCValues (void* ignore, XGCValues *gc,
947 1115
948/* Mac replacement for XSetForeground. */ 1116/* Mac replacement for XSetForeground. */
949 1117
950static void 1118void
951XSetForeground (display, gc, color) 1119XSetForeground (display, gc, color)
952 Display *display; 1120 Display *display;
953 GC gc; 1121 GC gc;
@@ -2139,6 +2307,21 @@ x_copy_dpy_color (dpy, cmap, pixel)
2139 2307
2140#endif /* MAC_TODO */ 2308#endif /* MAC_TODO */
2141 2309
2310
2311/* Brightness beyond which a color won't have its highlight brightness
2312 boosted.
2313
2314 Nominally, highlight colors for `3d' faces are calculated by
2315 brightening an object's color by a constant scale factor, but this
2316 doesn't yield good results for dark colors, so for colors who's
2317 brightness is less than this value (on a scale of 0-255) have to
2318 use an additional additive factor.
2319
2320 The value here is set so that the default menu-bar/mode-line color
2321 (grey75) will not have its highlights changed at all. */
2322#define HIGHLIGHT_COLOR_DARK_BOOST_LIMIT 187
2323
2324
2142/* Allocate a color which is lighter or darker than *COLOR by FACTOR 2325/* Allocate a color which is lighter or darker than *COLOR by FACTOR
2143 or DELTA. Try a color with RGB values multiplied by FACTOR first. 2326 or DELTA. Try a color with RGB values multiplied by FACTOR first.
2144 If this produces the same color as COLOR, try a color where all RGB 2327 If this produces the same color as COLOR, try a color where all RGB
@@ -2154,12 +2337,42 @@ mac_alloc_lighter_color (f, color, factor, delta)
2154 int delta; 2337 int delta;
2155{ 2338{
2156 unsigned long new; 2339 unsigned long new;
2340 long bright;
2341
2342 /* On Mac, RGB values are 0-255, not 0-65535, so scale delta. */
2343 delta /= 256;
2157 2344
2158 /* Change RGB values by specified FACTOR. Avoid overflow! */ 2345 /* Change RGB values by specified FACTOR. Avoid overflow! */
2159 xassert (factor >= 0); 2346 xassert (factor >= 0);
2160 new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))), 2347 new = RGB_TO_ULONG (min (0xff, (int) (factor * RED_FROM_ULONG (*color))),
2161 min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))), 2348 min (0xff, (int) (factor * GREEN_FROM_ULONG (*color))),
2162 min (0xff, (int) (factor * BLUE_FROM_ULONG (*color)))); 2349 min (0xff, (int) (factor * BLUE_FROM_ULONG (*color))));
2350
2351 /* Calculate brightness of COLOR. */
2352 bright = (2 * RED_FROM_ULONG (*color) + 3 * GREEN_FROM_ULONG (*color)
2353 + BLUE_FROM_ULONG (*color)) / 6;
2354
2355 /* We only boost colors that are darker than
2356 HIGHLIGHT_COLOR_DARK_BOOST_LIMIT. */
2357 if (bright < HIGHLIGHT_COLOR_DARK_BOOST_LIMIT)
2358 /* Make an additive adjustment to NEW, because it's dark enough so
2359 that scaling by FACTOR alone isn't enough. */
2360 {
2361 /* How far below the limit this color is (0 - 1, 1 being darker). */
2362 double dimness = 1 - (double)bright / HIGHLIGHT_COLOR_DARK_BOOST_LIMIT;
2363 /* The additive adjustment. */
2364 int min_delta = delta * dimness * factor / 2;
2365
2366 if (factor < 1)
2367 new = RGB_TO_ULONG (max (0, min (0xff, (int) (RED_FROM_ULONG (*color)) - min_delta)),
2368 max (0, min (0xff, (int) (GREEN_FROM_ULONG (*color)) - min_delta)),
2369 max (0, min (0xff, (int) (BLUE_FROM_ULONG (*color)) - min_delta)));
2370 else
2371 new = RGB_TO_ULONG (max (0, min (0xff, (int) (min_delta + RED_FROM_ULONG (*color)))),
2372 max (0, min (0xff, (int) (min_delta + GREEN_FROM_ULONG (*color)))),
2373 max (0, min (0xff, (int) (min_delta + BLUE_FROM_ULONG (*color)))));
2374 }
2375
2163 if (new == *color) 2376 if (new == *color)
2164 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))), 2377 new = RGB_TO_ULONG (max (0, min (0xff, (int) (delta + RED_FROM_ULONG (*color)))),
2165 max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))), 2378 max (0, min (0xff, (int) (delta + GREEN_FROM_ULONG (*color)))),
@@ -2204,7 +2417,8 @@ x_setup_relief_color (f, relief, factor, delta, default_pixel)
2204 /* Allocate new color. */ 2417 /* Allocate new color. */
2205 xgcv.foreground = default_pixel; 2418 xgcv.foreground = default_pixel;
2206 pixel = background; 2419 pixel = background;
2207 if (mac_alloc_lighter_color (f, &pixel, factor, delta)) 2420 if (dpyinfo->n_planes != 1
2421 && mac_alloc_lighter_color (f, &pixel, factor, delta))
2208 { 2422 {
2209 relief->allocated_p = 1; 2423 relief->allocated_p = 1;
2210 xgcv.foreground = relief->pixel = pixel; 2424 xgcv.foreground = relief->pixel = pixel;
@@ -2234,6 +2448,10 @@ x_setup_relief_colors (s)
2234 2448
2235 if (s->face->use_box_color_for_shadows_p) 2449 if (s->face->use_box_color_for_shadows_p)
2236 color = s->face->box_color; 2450 color = s->face->box_color;
2451 else if (s->first_glyph->type == IMAGE_GLYPH
2452 && s->img->pixmap
2453 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0))
2454 color = IMAGE_BACKGROUND (s->img, s->f, 0);
2237 else 2455 else
2238 { 2456 {
2239 XGCValues xgcv; 2457 XGCValues xgcv;
@@ -2267,9 +2485,11 @@ static void
2267x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, 2485x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2268 raised_p, left_p, right_p, clip_rect) 2486 raised_p, left_p, right_p, clip_rect)
2269 struct frame *f; 2487 struct frame *f;
2270 int left_x, top_y, right_x, bottom_y, left_p, right_p, raised_p; 2488 int left_x, top_y, right_x, bottom_y, width, left_p, right_p, raised_p;
2271 Rect *clip_rect; 2489 Rect *clip_rect;
2272{ 2490{
2491 Display *dpy = FRAME_MAC_DISPLAY (f);
2492 Window window = FRAME_MAC_WINDOW (f);
2273 int i; 2493 int i;
2274 GC gc; 2494 GC gc;
2275 2495
@@ -2277,41 +2497,41 @@ x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width,
2277 gc = f->output_data.mac->white_relief.gc; 2497 gc = f->output_data.mac->white_relief.gc;
2278 else 2498 else
2279 gc = f->output_data.mac->black_relief.gc; 2499 gc = f->output_data.mac->black_relief.gc;
2280 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), clip_rect); 2500 mac_set_clip_rectangle (dpy, window, clip_rect);
2281 2501
2282 /* Top. */ 2502 /* Top. */
2283 for (i = 0; i < width; ++i) 2503 for (i = 0; i < width; ++i)
2284 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2504 XDrawLine (dpy, window, gc,
2285 left_x + i * left_p, top_y + i, 2505 left_x + i * left_p, top_y + i,
2286 right_x + 1 - i * right_p, top_y + i); 2506 right_x - i * right_p, top_y + i);
2287 2507
2288 /* Left. */ 2508 /* Left. */
2289 if (left_p) 2509 if (left_p)
2290 for (i = 0; i < width; ++i) 2510 for (i = 0; i < width; ++i)
2291 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2511 XDrawLine (dpy, window, gc,
2292 left_x + i, top_y + i, left_x + i, bottom_y - i); 2512 left_x + i, top_y + i, left_x + i, bottom_y - i);
2293 2513
2294 mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); 2514 mac_reset_clipping (dpy, window);
2295 if (raised_p) 2515 if (raised_p)
2296 gc = f->output_data.mac->black_relief.gc; 2516 gc = f->output_data.mac->black_relief.gc;
2297 else 2517 else
2298 gc = f->output_data.mac->white_relief.gc; 2518 gc = f->output_data.mac->white_relief.gc;
2299 mac_set_clip_rectangle (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), 2519 mac_set_clip_rectangle (dpy, window,
2300 clip_rect); 2520 clip_rect);
2301 2521
2302 /* Bottom. */ 2522 /* Bottom. */
2303 for (i = 0; i < width; ++i) 2523 for (i = 0; i < width; ++i)
2304 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2524 XDrawLine (dpy, window, gc,
2305 left_x + i * left_p, bottom_y - i, 2525 left_x + i * left_p, bottom_y - i,
2306 right_x + 1 - i * right_p, bottom_y - i); 2526 right_x - i * right_p, bottom_y - i);
2307 2527
2308 /* Right. */ 2528 /* Right. */
2309 if (right_p) 2529 if (right_p)
2310 for (i = 0; i < width; ++i) 2530 for (i = 0; i < width; ++i)
2311 XDrawLine (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), gc, 2531 XDrawLine (dpy, window, gc,
2312 right_x - i, top_y + i + 1, right_x - i, bottom_y - i); 2532 right_x - i, top_y + i + 1, right_x - i, bottom_y - i - 1);
2313 2533
2314 mac_reset_clipping (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f)); 2534 mac_reset_clipping (dpy, window);
2315} 2535}
2316 2536
2317 2537
@@ -2326,7 +2546,7 @@ static void
2326x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, 2546x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2327 left_p, right_p, clip_rect) 2547 left_p, right_p, clip_rect)
2328 struct glyph_string *s; 2548 struct glyph_string *s;
2329 int left_x, top_y, right_x, bottom_y, left_p, right_p; 2549 int left_x, top_y, right_x, bottom_y, width, left_p, right_p;
2330 Rect *clip_rect; 2550 Rect *clip_rect;
2331{ 2551{
2332 XGCValues xgcv; 2552 XGCValues xgcv;
@@ -2336,21 +2556,21 @@ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
2336 2556
2337 /* Top. */ 2557 /* Top. */
2338 XFillRectangle (s->display, s->window, &xgcv, 2558 XFillRectangle (s->display, s->window, &xgcv,
2339 left_x, top_y, right_x - left_x, width); 2559 left_x, top_y, right_x - left_x + 1, width);
2340 2560
2341 /* Left. */ 2561 /* Left. */
2342 if (left_p) 2562 if (left_p)
2343 XFillRectangle (s->display, s->window, &xgcv, 2563 XFillRectangle (s->display, s->window, &xgcv,
2344 left_x, top_y, width, bottom_y - top_y); 2564 left_x, top_y, width, bottom_y - top_y + 1);
2345 2565
2346 /* Bottom. */ 2566 /* Bottom. */
2347 XFillRectangle (s->display, s->window, &xgcv, 2567 XFillRectangle (s->display, s->window, &xgcv,
2348 left_x, bottom_y - width, right_x - left_x, width); 2568 left_x, bottom_y - width + 1, right_x - left_x + 1, width);
2349 2569
2350 /* Right. */ 2570 /* Right. */
2351 if (right_p) 2571 if (right_p)
2352 XFillRectangle (s->display, s->window, &xgcv, 2572 XFillRectangle (s->display, s->window, &xgcv,
2353 right_x - width, top_y, width, bottom_y - top_y); 2573 right_x - width + 1, top_y, width, bottom_y - top_y + 1);
2354 2574
2355 mac_reset_clipping (s->display, s->window); 2575 mac_reset_clipping (s->display, s->window);
2356} 2576}
@@ -2385,9 +2605,9 @@ x_draw_glyph_string_box (s)
2385 width = abs (s->face->box_line_width); 2605 width = abs (s->face->box_line_width);
2386 raised_p = s->face->box == FACE_RAISED_BOX; 2606 raised_p = s->face->box == FACE_RAISED_BOX;
2387 left_x = s->x; 2607 left_x = s->x;
2388 right_x = ((s->row->full_width_p && s->extends_to_end_of_line_p 2608 right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
2389 ? last_x - 1 2609 ? last_x - 1
2390 : min (last_x, s->x + s->background_width) - 1)); 2610 : min (last_x, s->x + s->background_width) - 1);
2391 top_y = s->y; 2611 top_y = s->y;
2392 bottom_y = top_y + s->height - 1; 2612 bottom_y = top_y + s->height - 1;
2393 2613
@@ -2438,39 +2658,36 @@ x_draw_image_foreground (s)
2438 2658
2439 if (s->img->pixmap) 2659 if (s->img->pixmap)
2440 { 2660 {
2441#if 0 /* MAC_TODO: image mask */
2442 if (s->img->mask) 2661 if (s->img->mask)
2443 { 2662 {
2444 /* We can't set both a clip mask and use XSetClipRectangles 2663 Rect nr;
2445 because the latter also sets a clip mask. We also can't
2446 trust on the shape extension to be available
2447 (XShapeCombineRegion). So, compute the rectangle to draw
2448 manually. */
2449 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2450 | GCFunction);
2451 XGCValues xgcv;
2452 XRectangle clip_rect, image_rect, r; 2664 XRectangle clip_rect, image_rect, r;
2453 2665
2454 xgcv.clip_mask = s->img->mask; 2666 get_glyph_string_clip_rect (s, &nr);
2455 xgcv.clip_x_origin = x; 2667 CONVERT_TO_XRECT (clip_rect, nr);
2456 xgcv.clip_y_origin = y;
2457 xgcv.function = GXcopy;
2458 XChangeGC (s->display, s->gc, mask, &xgcv);
2459
2460 get_glyph_string_clip_rect (s, &clip_rect);
2461 image_rect.x = x; 2668 image_rect.x = x;
2462 image_rect.y = y; 2669 image_rect.y = y;
2463 image_rect.width = s->img->width; 2670 image_rect.width = s->img->width;
2464 image_rect.height = s->img->height; 2671 image_rect.height = s->img->height;
2465 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) 2672 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2466 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, 2673 mac_copy_area_with_mask (s->display, s->img->pixmap, s->img->mask,
2467 r.x - x, r.y - y, r.width, r.height, r.x, r.y); 2674 s->window, s->gc, r.x - x, r.y - y,
2675 r.width, r.height, r.x, r.y);
2468 } 2676 }
2469 else 2677 else
2470#endif /* MAC_TODO */
2471 { 2678 {
2472 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc, 2679 Rect nr;
2473 0, 0, s->img->width, s->img->height, x, y); 2680 XRectangle clip_rect, image_rect, r;
2681
2682 get_glyph_string_clip_rect (s, &nr);
2683 CONVERT_TO_XRECT (clip_rect, nr);
2684 image_rect.x = x;
2685 image_rect.y = y;
2686 image_rect.width = s->img->width;
2687 image_rect.height = s->img->height;
2688 if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
2689 mac_copy_area (s->display, s->img->pixmap, s->window, s->gc,
2690 r.x - x, r.y - y, r.width, r.height, r.x, r.y);
2474 2691
2475 /* When the image has a mask, we can expect that at 2692 /* When the image has a mask, we can expect that at
2476 least part of a mouse highlight or a block cursor will 2693 least part of a mouse highlight or a block cursor will
@@ -2494,7 +2711,6 @@ x_draw_image_foreground (s)
2494} 2711}
2495 2712
2496 2713
2497
2498/* Draw a relief around the image glyph string S. */ 2714/* Draw a relief around the image glyph string S. */
2499 2715
2500static void 2716static void
@@ -2567,30 +2783,12 @@ x_draw_image_foreground_1 (s, pixmap)
2567 2783
2568 if (s->img->pixmap) 2784 if (s->img->pixmap)
2569 { 2785 {
2570#if 0 /* MAC_TODO: image mask */
2571 if (s->img->mask) 2786 if (s->img->mask)
2572 { 2787 mac_copy_area_with_mask_to_pixmap (s->display, s->img->pixmap,
2573 /* We can't set both a clip mask and use XSetClipRectangles 2788 s->img->mask, pixmap, s->gc,
2574 because the latter also sets a clip mask. We also can't 2789 0, 0, s->img->width, s->img->height,
2575 trust on the shape extension to be available 2790 x, y);
2576 (XShapeCombineRegion). So, compute the rectangle to draw
2577 manually. */
2578 unsigned long mask = (GCClipMask | GCClipXOrigin | GCClipYOrigin
2579 | GCFunction);
2580 XGCValues xgcv;
2581
2582 xgcv.clip_mask = s->img->mask;
2583 xgcv.clip_x_origin = x;
2584 xgcv.clip_y_origin = y;
2585 xgcv.function = GXcopy;
2586 XChangeGC (s->display, s->gc, mask, &xgcv);
2587
2588 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc,
2589 0, 0, s->img->width, s->img->height, x, y);
2590 XSetClipMask (s->display, s->gc, None);
2591 }
2592 else 2791 else
2593#endif /* MAC_TODO */
2594 { 2792 {
2595 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc, 2793 mac_copy_area_to_pixmap (s->display, s->img->pixmap, pixmap, s->gc,
2596 0, 0, s->img->width, s->img->height, x, y); 2794 0, 0, s->img->width, s->img->height, x, y);
@@ -2605,15 +2803,16 @@ x_draw_image_foreground_1 (s, pixmap)
2605 { 2803 {
2606 int r = s->img->relief; 2804 int r = s->img->relief;
2607 if (r < 0) r = -r; 2805 if (r < 0) r = -r;
2608 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x - r, y - r, 2806 mac_draw_rectangle (s->display, s->window, s->gc, x - r, y - r,
2609 s->img->width + r*2 - 1, s->img->height + r*2 - 1); 2807 s->img->width + r*2 - 1,
2808 s->img->height + r*2 - 1);
2610 } 2809 }
2611 } 2810 }
2612 } 2811 }
2613 else 2812 else
2614 /* Draw a rectangle if image could not be loaded. */ 2813 /* Draw a rectangle if image could not be loaded. */
2615 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y, 2814 mac_draw_rectangle_to_pixmap (s->display, pixmap, s->gc, x, y,
2616 s->img->width - 1, s->img->height - 1); 2815 s->img->width - 1, s->img->height - 1);
2617} 2816}
2618 2817
2619 2818
@@ -2646,7 +2845,7 @@ x_draw_glyph_string_bg_rect (s, x, y, w, h)
2646 | s->face->box 2845 | s->face->box
2647 | 2846 |
2648 | +------------------------- 2847 | +-------------------------
2649 | | s->img->vmargin 2848 | | s->img->margin
2650 | | 2849 | |
2651 | | +------------------- 2850 | | +-------------------
2652 | | | the image 2851 | | | the image
@@ -2665,6 +2864,7 @@ x_draw_image_glyph_string (s)
2665 2864
2666 height = s->height - 2 * box_line_vwidth; 2865 height = s->height - 2 * box_line_vwidth;
2667 2866
2867
2668 /* Fill background with face under the image. Do it only if row is 2868 /* Fill background with face under the image. Do it only if row is
2669 taller than image or if image has a clip mask to reduce 2869 taller than image or if image has a clip mask to reduce
2670 flickering. */ 2870 flickering. */
@@ -2672,9 +2872,7 @@ x_draw_image_glyph_string (s)
2672 if (height > s->img->height 2872 if (height > s->img->height
2673 || s->img->hmargin 2873 || s->img->hmargin
2674 || s->img->vmargin 2874 || s->img->vmargin
2675#if 0 /* TODO: image mask */
2676 || s->img->mask 2875 || s->img->mask
2677#endif
2678 || s->img->pixmap == 0 2876 || s->img->pixmap == 0
2679 || s->width != s->background_width) 2877 || s->width != s->background_width)
2680 { 2878 {
@@ -2684,25 +2882,21 @@ x_draw_image_glyph_string (s)
2684 x = s->x; 2882 x = s->x;
2685 2883
2686 y = s->y + box_line_vwidth; 2884 y = s->y + box_line_vwidth;
2687#if 0 /* TODO: image mask */ 2885
2688 if (s->img->mask) 2886 if (s->img->mask)
2689 { 2887 {
2690 /* Create a pixmap as large as the glyph string. Fill it 2888 /* Create a pixmap as large as the glyph string. Fill it
2691 with the background color. Copy the image to it, using 2889 with the background color. Copy the image to it, using
2692 its mask. Copy the temporary pixmap to the display. */ 2890 its mask. Copy the temporary pixmap to the display. */
2693 Screen *screen = FRAME_X_SCREEN (s->f); 2891 int depth = one_mac_display_info.n_planes;
2694 int depth = DefaultDepthOfScreen (screen);
2695 2892
2696 /* Create a pixmap as large as the glyph string. */ 2893 /* Create a pixmap as large as the glyph string. */
2697 pixmap = XCreatePixmap (s->display, s->window, 2894 pixmap = XCreatePixmap (s->display, s->window,
2698 s->background_width, 2895 s->background_width,
2699 s->height, depth); 2896 s->height, depth);
2700 2897
2701 /* Don't clip in the following because we're working on the
2702 pixmap. */
2703 XSetClipMask (s->display, s->gc, None);
2704
2705 /* Fill the pixmap with the background color/stipple. */ 2898 /* Fill the pixmap with the background color/stipple. */
2899#if 0 /* TODO: stipple */
2706 if (s->stippled_p) 2900 if (s->stippled_p)
2707 { 2901 {
2708 /* Fill background with a stipple pattern. */ 2902 /* Fill background with a stipple pattern. */
@@ -2712,18 +2906,19 @@ x_draw_image_glyph_string (s)
2712 XSetFillStyle (s->display, s->gc, FillSolid); 2906 XSetFillStyle (s->display, s->gc, FillSolid);
2713 } 2907 }
2714 else 2908 else
2909#endif
2715 { 2910 {
2716 XGCValues xgcv; 2911 XGCValues xgcv;
2717 XGetGCValues (s->display, s->gc, GCForeground | GCBackground, 2912 XGetGCValues (s->display, s->gc, GCForeground | GCBackground,
2718 &xgcv); 2913 &xgcv);
2719 XSetForeground (s->display, s->gc, xgcv.background); 2914 XSetForeground (s->display, s->gc, xgcv.background);
2720 XFillRectangle (s->display, pixmap, s->gc, 2915 mac_fill_rectangle_to_pixmap (s->display, pixmap, s->gc,
2721 0, 0, s->background_width, s->height); 2916 0, 0, s->background_width,
2917 s->height);
2722 XSetForeground (s->display, s->gc, xgcv.foreground); 2918 XSetForeground (s->display, s->gc, xgcv.foreground);
2723 } 2919 }
2724 } 2920 }
2725 else 2921 else
2726#endif
2727 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); 2922 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
2728 2923
2729 s->background_filled_p = 1; 2924 s->background_filled_p = 1;
@@ -2735,7 +2930,7 @@ x_draw_image_glyph_string (s)
2735 x_draw_image_foreground_1 (s, pixmap); 2930 x_draw_image_foreground_1 (s, pixmap);
2736 x_set_glyph_string_clipping (s); 2931 x_set_glyph_string_clipping (s);
2737 mac_copy_area (s->display, pixmap, s->window, s->gc, 2932 mac_copy_area (s->display, pixmap, s->window, s->gc,
2738 0, 0, s->background_width, s->height, s->x, s->y); 2933 0, 0, s->background_width, s->height, s->x, s->y);
2739 mac_reset_clipping (s->display, s->window); 2934 mac_reset_clipping (s->display, s->window);
2740 XFreePixmap (s->display, pixmap); 2935 XFreePixmap (s->display, pixmap);
2741 } 2936 }
@@ -2772,10 +2967,10 @@ x_draw_stretch_glyph_string (s)
2772 /* Clear rest using the GC of the original non-cursor face. */ 2967 /* Clear rest using the GC of the original non-cursor face. */
2773 if (width < s->background_width) 2968 if (width < s->background_width)
2774 { 2969 {
2775 GC gc = s->face->gc;
2776 int x = s->x + width, y = s->y; 2970 int x = s->x + width, y = s->y;
2777 int w = s->background_width - width, h = s->height; 2971 int w = s->background_width - width, h = s->height;
2778 Rect r; 2972 Rect r;
2973 GC gc;
2779 2974
2780 if (s->row->mouse_face_p 2975 if (s->row->mouse_face_p
2781 && cursor_in_mouse_face_p (s->w)) 2976 && cursor_in_mouse_face_p (s->w))
@@ -2835,7 +3030,6 @@ x_draw_glyph_string (s)
2835 x_set_glyph_string_gc (s->next); 3030 x_set_glyph_string_gc (s->next);
2836 x_set_glyph_string_clipping (s->next); 3031 x_set_glyph_string_clipping (s->next);
2837 x_draw_glyph_string_background (s->next, 1); 3032 x_draw_glyph_string_background (s->next, 1);
2838
2839 } 3033 }
2840 3034
2841 /* Set up S->gc, set clipping and draw S. */ 3035 /* Set up S->gc, set clipping and draw S. */
@@ -2872,7 +3066,7 @@ x_draw_glyph_string (s)
2872 if (s->for_overlaps_p) 3066 if (s->for_overlaps_p)
2873 s->background_filled_p = 1; 3067 s->background_filled_p = 1;
2874 else 3068 else
2875 x_draw_glyph_string_background (s, 0); 3069 x_draw_glyph_string_background (s, 0);
2876 x_draw_glyph_string_foreground (s); 3070 x_draw_glyph_string_foreground (s);
2877 break; 3071 break;
2878 3072
@@ -2949,9 +3143,9 @@ x_draw_glyph_string (s)
2949 } 3143 }
2950 } 3144 }
2951 3145
2952 /* Draw relief. */ 3146 /* Draw relief if not yet drawn. */
2953 if (!relief_drawn_p && s->face->box != FACE_NO_BOX) 3147 if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
2954 x_draw_glyph_string_box (s); 3148 x_draw_glyph_string_box (s);
2955 } 3149 }
2956 3150
2957 /* Reset clipping. */ 3151 /* Reset clipping. */
@@ -2971,7 +3165,6 @@ mac_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
2971 x + shift_by, y); 3165 x + shift_by, y);
2972} 3166}
2973 3167
2974
2975/* Delete N glyphs at the nominal cursor position. Not implemented 3168/* Delete N glyphs at the nominal cursor position. Not implemented
2976 for X frames. */ 3169 for X frames. */
2977 3170
@@ -3026,6 +3219,7 @@ x_clear_frame ()
3026 3219
3027#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) 3220#if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT)
3028 3221
3222
3029/* Subtract the `struct timeval' values X and Y, storing the result in 3223/* Subtract the `struct timeval' values X and Y, storing the result in
3030 *RESULT. Return 1 if the difference is negative, otherwise 0. */ 3224 *RESULT. Return 1 if the difference is negative, otherwise 0. */
3031 3225
@@ -3129,7 +3323,7 @@ XTring_bell ()
3129 This, and those operations, are used only within an update 3323 This, and those operations, are used only within an update
3130 that is bounded by calls to x_update_begin and x_update_end. */ 3324 that is bounded by calls to x_update_begin and x_update_end. */
3131 3325
3132void 3326static void
3133XTset_terminal_window (n) 3327XTset_terminal_window (n)
3134 register int n; 3328 register int n;
3135{ 3329{
@@ -3165,7 +3359,7 @@ x_scroll_run (w, run)
3165 3359
3166 /* Get frame-relative bounding box of the text display area of W, 3360 /* Get frame-relative bounding box of the text display area of W,
3167 without mode lines. Include in this box the left and right 3361 without mode lines. Include in this box the left and right
3168 fringes of W. */ 3362 fringe of W. */
3169 window_box (w, -1, &x, &y, &width, &height); 3363 window_box (w, -1, &x, &y, &width, &height);
3170 3364
3171 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y); 3365 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->current_y);
@@ -3287,8 +3481,6 @@ static void
3287XTframe_rehighlight (frame) 3481XTframe_rehighlight (frame)
3288 struct frame *frame; 3482 struct frame *frame;
3289{ 3483{
3290
3291
3292 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame)); 3484 x_frame_rehighlight (FRAME_X_DISPLAY_INFO (frame));
3293} 3485}
3294 3486
@@ -4429,13 +4621,6 @@ x_draw_hollow_cursor (w, row)
4429 struct glyph *cursor_glyph; 4621 struct glyph *cursor_glyph;
4430 GC gc; 4622 GC gc;
4431 4623
4432 /* Compute frame-relative coordinates from window-relative
4433 coordinates. */
4434 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
4435 y = (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
4436 + row->ascent - w->phys_cursor_ascent);
4437 h = row->height - 1;
4438
4439 /* Get the glyph the cursor is on. If we can't tell because 4624 /* Get the glyph the cursor is on. If we can't tell because
4440 the current matrix is invalid or such, give up. */ 4625 the current matrix is invalid or such, give up. */
4441 cursor_glyph = get_phys_cursor_glyph (w); 4626 cursor_glyph = get_phys_cursor_glyph (w);
@@ -4450,6 +4635,20 @@ x_draw_hollow_cursor (w, row)
4450 if (cursor_glyph->type == STRETCH_GLYPH 4635 if (cursor_glyph->type == STRETCH_GLYPH
4451 && !x_stretch_cursor_p) 4636 && !x_stretch_cursor_p)
4452 wd = min (FRAME_COLUMN_WIDTH (f), wd); 4637 wd = min (FRAME_COLUMN_WIDTH (f), wd);
4638 w->phys_cursor_width = wd;
4639
4640 /* Compute frame-relative coordinates from window-relative
4641 coordinates. */
4642 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
4643 y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
4644
4645 /* Compute the proper height and ascent of the rectangle, based
4646 on the actual glyph. Using the full height of the row looks
4647 bad when there are tall images on that row. */
4648 h = max (FRAME_LINE_HEIGHT (f), cursor_glyph->ascent + cursor_glyph->descent);
4649 if (h < row->height)
4650 y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
4651 h--;
4453 4652
4454 /* The foreground of cursor_gc is typically the same as the normal 4653 /* The foreground of cursor_gc is typically the same as the normal
4455 background color, which can cause the cursor box to be invisible. */ 4654 background color, which can cause the cursor box to be invisible. */
@@ -4476,35 +4675,49 @@ x_draw_hollow_cursor (w, row)
4476 --gerd. */ 4675 --gerd. */
4477 4676
4478static void 4677static void
4479x_draw_bar_cursor (w, row, width) 4678x_draw_bar_cursor (w, row, width, kind)
4480 struct window *w; 4679 struct window *w;
4481 struct glyph_row *row; 4680 struct glyph_row *row;
4482 int width; 4681 int width;
4682 enum text_cursor_kinds kind;
4483{ 4683{
4484 /* If cursor hpos is out of bounds, don't draw garbage. This can 4684 struct frame *f = XFRAME (w->frame);
4485 happen in mini-buffer windows when switching between echo area 4685 struct glyph *cursor_glyph;
4486 glyphs and mini-buffer. */ 4686
4487 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) 4687 /* If cursor is out of bounds, don't draw garbage. This can happen
4688 in mini-buffer windows when switching between echo area glyphs
4689 and mini-buffer. */
4690 cursor_glyph = get_phys_cursor_glyph (w);
4691 if (cursor_glyph == NULL)
4692 return;
4693
4694 /* If on an image, draw like a normal cursor. That's usually better
4695 visible than drawing a bar, esp. if the image is large so that
4696 the bar might not be in the window. */
4697 if (cursor_glyph->type == IMAGE_GLYPH)
4488 { 4698 {
4489 struct frame *f = XFRAME (w->frame); 4699 struct glyph_row *row;
4490 struct glyph *cursor_glyph; 4700 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
4491 GC gc; 4701 draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
4492 int x; 4702 }
4493 unsigned long mask; 4703 else
4704 {
4705 Display *dpy = FRAME_MAC_DISPLAY (f);
4706 Window window = FRAME_MAC_WINDOW (f);
4707 GC gc = FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc;
4708 unsigned long mask = GCForeground | GCBackground;
4709 struct face *face = FACE_FROM_ID (f, cursor_glyph->face_id);
4494 XGCValues xgcv; 4710 XGCValues xgcv;
4495 Display *dpy;
4496 Window window;
4497 4711
4498 cursor_glyph = get_phys_cursor_glyph (w); 4712 /* If the glyph's background equals the color we normally draw
4499 if (cursor_glyph == NULL) 4713 the bar cursor in, the bar cursor in its normal color is
4500 return; 4714 invisible. Use the glyph's foreground color instead in this
4501 4715 case, on the assumption that the glyph's colors are chosen so
4502 xgcv.background = f->output_data.mac->cursor_pixel; 4716 that the glyph is legible. */
4503 xgcv.foreground = f->output_data.mac->cursor_pixel; 4717 if (face->background == f->output_data.mac->cursor_pixel)
4504 mask = GCForeground | GCBackground; 4718 xgcv.background = xgcv.foreground = face->foreground;
4505 dpy = FRAME_MAC_DISPLAY (f); 4719 else
4506 window = FRAME_MAC_WINDOW (f); 4720 xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel;
4507 gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
4508 4721
4509 if (gc) 4722 if (gc)
4510 XChangeGC (dpy, gc, mask, &xgcv); 4723 XChangeGC (dpy, gc, mask, &xgcv);
@@ -4516,14 +4729,24 @@ x_draw_bar_cursor (w, row, width)
4516 4729
4517 if (width < 0) 4730 if (width < 0)
4518 width = FRAME_CURSOR_WIDTH (f); 4731 width = FRAME_CURSOR_WIDTH (f);
4732 width = min (cursor_glyph->pixel_width, width);
4519 4733
4520 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); 4734 w->phys_cursor_width = width;
4521 x_clip_to_row (w, row, gc); 4735 x_clip_to_row (w, row, gc);
4522 XFillRectangle (dpy, window, gc, 4736
4523 x, 4737 if (kind == BAR_CURSOR)
4524 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), 4738 XFillRectangle (dpy, window, gc,
4525 min (cursor_glyph->pixel_width, width), 4739 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
4526 row->height); 4740 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
4741 width, row->height);
4742 else
4743 XFillRectangle (dpy, window, gc,
4744 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
4745 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
4746 row->height - width),
4747 cursor_glyph->pixel_width,
4748 width);
4749
4527 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f)); 4750 mac_reset_clipping (dpy, FRAME_MAC_WINDOW (f));
4528 } 4751 }
4529} 4752}
@@ -4565,7 +4788,6 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4565 if (on_p) 4788 if (on_p)
4566 { 4789 {
4567 w->phys_cursor_type = cursor_type; 4790 w->phys_cursor_type = cursor_type;
4568 w->phys_cursor_width = cursor_width;
4569 w->phys_cursor_on_p = 1; 4791 w->phys_cursor_on_p = 1;
4570 4792
4571 if (glyph_row->exact_window_width_line_p 4793 if (glyph_row->exact_window_width_line_p
@@ -4573,9 +4795,8 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4573 { 4795 {
4574 glyph_row->cursor_in_fringe_p = 1; 4796 glyph_row->cursor_in_fringe_p = 1;
4575 draw_fringe_bitmap (w, glyph_row, 0); 4797 draw_fringe_bitmap (w, glyph_row, 0);
4576 return;
4577 } 4798 }
4578 4799 else
4579 switch (cursor_type) 4800 switch (cursor_type)
4580 { 4801 {
4581 case HOLLOW_BOX_CURSOR: 4802 case HOLLOW_BOX_CURSOR:
@@ -4586,13 +4807,16 @@ mac_draw_window_cursor (w, glyph_row, x, y, cursor_type, cursor_width, on_p, act
4586 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR); 4807 draw_phys_cursor_glyph (w, glyph_row, DRAW_CURSOR);
4587 break; 4808 break;
4588 4809
4589 case HBAR_CURSOR:
4590 /* TODO. For now, just draw bar cursor. */
4591 case BAR_CURSOR: 4810 case BAR_CURSOR:
4592 x_draw_bar_cursor (w, glyph_row, cursor_width); 4811 x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR);
4812 break;
4813
4814 case HBAR_CURSOR:
4815 x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR);
4593 break; 4816 break;
4594 4817
4595 case NO_CURSOR: 4818 case NO_CURSOR:
4819 w->phys_cursor_width = 0;
4596 break; 4820 break;
4597 4821
4598 default: 4822 default:
@@ -5117,6 +5341,8 @@ x_make_frame_visible (f)
5117 FRAME_SAMPLE_VISIBILITY (f); 5341 FRAME_SAMPLE_VISIBILITY (f);
5118 } 5342 }
5119 } 5343 }
5344#else
5345 UNBLOCK_INPUT;
5120#endif /* MAC_TODO */ 5346#endif /* MAC_TODO */
5121} 5347}
5122 5348
@@ -5173,10 +5399,10 @@ x_iconify_frame (f)
5173} 5399}
5174 5400
5175 5401
5176/* Destroy the X window of frame F. */ 5402/* Free X resources of frame F. */
5177 5403
5178void 5404void
5179x_destroy_window (f) 5405x_free_frame_resources (f)
5180 struct frame *f; 5406 struct frame *f;
5181{ 5407{
5182 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f); 5408 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
@@ -5186,10 +5412,15 @@ x_destroy_window (f)
5186 DisposeWindow (FRAME_MAC_WINDOW (f)); 5412 DisposeWindow (FRAME_MAC_WINDOW (f));
5187 5413
5188 free_frame_menubar (f); 5414 free_frame_menubar (f);
5189 free_frame_faces (f); 5415
5416 if (FRAME_FACE_CACHE (f))
5417 free_frame_faces (f);
5418
5419 x_free_gcs (f);
5190 5420
5191 xfree (f->output_data.mac); 5421 xfree (f->output_data.mac);
5192 f->output_data.mac = 0; 5422 f->output_data.mac = NULL;
5423
5193 if (f == dpyinfo->x_focus_frame) 5424 if (f == dpyinfo->x_focus_frame)
5194 dpyinfo->x_focus_frame = 0; 5425 dpyinfo->x_focus_frame = 0;
5195 if (f == dpyinfo->x_focus_event_frame) 5426 if (f == dpyinfo->x_focus_event_frame)
@@ -5197,8 +5428,6 @@ x_destroy_window (f)
5197 if (f == dpyinfo->x_highlight_frame) 5428 if (f == dpyinfo->x_highlight_frame)
5198 dpyinfo->x_highlight_frame = 0; 5429 dpyinfo->x_highlight_frame = 0;
5199 5430
5200 dpyinfo->reference_count--;
5201
5202 if (f == dpyinfo->mouse_face_mouse_frame) 5431 if (f == dpyinfo->mouse_face_mouse_frame)
5203 { 5432 {
5204 dpyinfo->mouse_face_beg_row 5433 dpyinfo->mouse_face_beg_row
@@ -5212,6 +5441,21 @@ x_destroy_window (f)
5212 5441
5213 UNBLOCK_INPUT; 5442 UNBLOCK_INPUT;
5214} 5443}
5444
5445
5446/* Destroy the X window of frame F. */
5447
5448void
5449x_destroy_window (f)
5450 struct frame *f;
5451{
5452 struct mac_display_info *dpyinfo = FRAME_MAC_DISPLAY_INFO (f);
5453
5454 x_free_frame_resources (f);
5455
5456 dpyinfo->reference_count--;
5457}
5458
5215 5459
5216/* Setting window manager hints. */ 5460/* Setting window manager hints. */
5217 5461
@@ -5478,6 +5722,7 @@ char **font_name_table = NULL;
5478int font_name_table_size = 0; 5722int font_name_table_size = 0;
5479int font_name_count = 0; 5723int font_name_count = 0;
5480 5724
5725#if 0
5481/* compare two strings ignoring case */ 5726/* compare two strings ignoring case */
5482static int 5727static int
5483stricmp (const char *s, const char *t) 5728stricmp (const char *s, const char *t)
@@ -5557,13 +5802,53 @@ mac_font_match (char *mf, char *xf)
5557 && wildstrieq (m_charset, x_charset)) 5802 && wildstrieq (m_charset, x_charset))
5558 || mac_font_pattern_match (mf, xf); 5803 || mac_font_pattern_match (mf, xf);
5559} 5804}
5805#endif
5806
5807static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr;
5808
5809static void
5810decode_mac_font_name (char *name, int size, short scriptcode)
5811{
5812 Lisp_Object coding_system;
5813 struct coding_system coding;
5814 char *buf;
5815
5816 switch (scriptcode)
5817 {
5818 case smTradChinese:
5819 coding_system = Qbig5;
5820 break;
5821 case smSimpChinese:
5822 coding_system = Qcn_gb;
5823 break;
5824 case smJapanese:
5825 coding_system = Qsjis;
5826 break;
5827 case smKorean:
5828 coding_system = Qeuc_kr;
5829 break;
5830 default:
5831 return;
5832 }
5833
5834 setup_coding_system (coding_system, &coding);
5835 coding.src_multibyte = 0;
5836 coding.dst_multibyte = 1;
5837 coding.mode |= CODING_MODE_LAST_BLOCK;
5838 coding.composing = COMPOSITION_DISABLED;
5839 buf = (char *) alloca (size);
5840
5841 decode_coding (&coding, name, buf, strlen (name), size - 1);
5842 bcopy (buf, name, coding.produced);
5843 name[coding.produced] = '\0';
5844}
5560 5845
5561 5846
5562static char * 5847static char *
5563mac_to_x_fontname (char *name, int size, Style style, short scriptcode) 5848mac_to_x_fontname (char *name, int size, Style style, short scriptcode)
5564{ 5849{
5565 char foundry[32], family[32], cs[32]; 5850 char foundry[32], family[32], cs[32];
5566 char xf[255], *result, *p; 5851 char xf[256], *result, *p;
5567 5852
5568 if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3) 5853 if (sscanf (name, "%31[^-]-%31[^-]-%31s", foundry, family, cs) != 3)
5569 { 5854 {
@@ -5622,6 +5907,8 @@ static void
5622x_font_name_to_mac_font_name (char *xf, char *mf) 5907x_font_name_to_mac_font_name (char *xf, char *mf)
5623{ 5908{
5624 char foundry[32], family[32], weight[20], slant[2], cs[32]; 5909 char foundry[32], family[32], weight[20], slant[2], cs[32];
5910 Lisp_Object coding_system = Qnil;
5911 struct coding_system coding;
5625 5912
5626 strcpy (mf, ""); 5913 strcpy (mf, "");
5627 5914
@@ -5631,13 +5918,29 @@ x_font_name_to_mac_font_name (char *xf, char *mf)
5631 foundry, family, weight, slant, cs) != 5) 5918 foundry, family, weight, slant, cs) != 5)
5632 return; 5919 return;
5633 5920
5634 if (strcmp (cs, "big5-0") == 0 || strcmp (cs, "gb2312.1980-0") == 0 5921 if (strcmp (cs, "big5-0") == 0)
5635 || strcmp (cs, "jisx0208.1983-sjis") == 0 5922 coding_system = Qbig5;
5636 || strcmp (cs, "jisx0201.1976-0") == 0 5923 else if (strcmp (cs, "gb2312.1980-0") == 0)
5637 || strcmp (cs, "ksc5601.1989-0") == 0 || strcmp (cs, "mac-roman") == 0) 5924 coding_system = Qcn_gb;
5638 strcpy(mf, family); 5925 else if (strcmp (cs, "jisx0208.1983-sjis") == 0
5926 || strcmp (cs, "jisx0201.1976-0") == 0)
5927 coding_system = Qsjis;
5928 else if (strcmp (cs, "ksc5601.1989-0") == 0)
5929 coding_system = Qeuc_kr;
5930 else if (strcmp (cs, "mac-roman") == 0)
5931 strcpy (mf, family);
5639 else 5932 else
5640 sprintf(mf, "%s-%s-%s", foundry, family, cs); 5933 sprintf (mf, "%s-%s-%s", foundry, family, cs);
5934
5935 if (!NILP (coding_system))
5936 {
5937 setup_coding_system (coding_system, &coding);
5938 coding.src_multibyte = 1;
5939 coding.dst_multibyte = 1;
5940 coding.mode |= CODING_MODE_LAST_BLOCK;
5941 encode_coding (&coding, family, mf, strlen (family), sizeof (Str32) - 1);
5942 mf[coding.produced] = '\0';
5943 }
5641} 5944}
5642 5945
5643 5946
@@ -5701,36 +6004,45 @@ init_font_name_table ()
5701 if (FMGetFontFamilyName (ff, name) != noErr) 6004 if (FMGetFontFamilyName (ff, name) != noErr)
5702 break; 6005 break;
5703 p2cstr (name); 6006 p2cstr (name);
6007 if (*name == '.')
6008 continue;
5704 6009
5705 sc = FontToScript (ff); 6010 sc = FontToScript (ff);
6011 decode_mac_font_name (name, sizeof (name), sc);
5706 6012
5707 /* Point the instance iterator at the current font family. */ 6013 /* Point the instance iterator at the current font family. */
5708 if (FMResetFontFamilyInstanceIterator(ff, &ffii) != noErr) 6014 if (FMResetFontFamilyInstanceIterator (ff, &ffii) != noErr)
5709 break; 6015 break;
5710 6016
5711 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size) 6017 while (FMGetNextFontFamilyInstance (&ffii, &font, &style, &size)
5712 == noErr) 6018 == noErr)
5713 if (size == 0) 6019 {
5714 { 6020 /* Both jisx0208.1983-sjis and jisx0201.1976-0 parts are
5715 add_font_name_table_entry (mac_to_x_fontname (name, size, 6021 contained in Apple Japanese (SJIS) font. */
5716 style, sc)); 6022 again:
5717 add_font_name_table_entry (mac_to_x_fontname (name, size, 6023 if (size == 0)
5718 italic, sc)); 6024 {
5719 add_font_name_table_entry (mac_to_x_fontname (name, size, 6025 add_font_name_table_entry (mac_to_x_fontname (name, size,
5720 bold, sc)); 6026 style, sc));
5721 add_font_name_table_entry (mac_to_x_fontname (name, size, 6027 add_font_name_table_entry (mac_to_x_fontname (name, size,
5722 italic | bold, 6028 italic, sc));
5723 sc)); 6029 add_font_name_table_entry (mac_to_x_fontname (name, size,
5724 } 6030 bold, sc));
5725 else 6031 add_font_name_table_entry (mac_to_x_fontname (name, size,
5726 { 6032 italic | bold,
6033 sc));
6034 }
6035 else
5727 add_font_name_table_entry (mac_to_x_fontname (name, size, 6036 add_font_name_table_entry (mac_to_x_fontname (name, size,
5728 style, sc)); 6037 style, sc));
5729 if (smJapanese == sc) 6038 if (sc == smJapanese)
5730 add_font_name_table_entry (mac_to_x_fontname (name, size, 6039 {
5731 style, 6040 sc = -smJapanese;
5732 -smJapanese)); 6041 goto again;
5733 } 6042 }
6043 else if (sc == -smJapanese)
6044 sc = smJapanese;
6045 }
5734 } 6046 }
5735 6047
5736 /* Dispose of the iterators. */ 6048 /* Dispose of the iterators. */
@@ -5772,6 +6084,7 @@ init_font_name_table ()
5772 6084
5773 TextFont (fontnum); 6085 TextFont (fontnum);
5774 scriptcode = FontToScript (fontnum); 6086 scriptcode = FontToScript (fontnum);
6087 decode_mac_font_name (name, sizeof (name), scriptcode);
5775 do 6088 do
5776 { 6089 {
5777 HLock (font_handle); 6090 HLock (font_handle);
@@ -5806,9 +6119,9 @@ init_font_name_table ()
5806 assc_entry->fontSize, 6119 assc_entry->fontSize,
5807 assc_entry->fontStyle, 6120 assc_entry->fontStyle,
5808 scriptcode); 6121 scriptcode);
5809 /* Both jisx0208.1983-sjis and 6122 /* Both jisx0208.1983-sjis and jisx0201.1976-0
5810 jisx0201.1976-sjis parts are contained in 6123 parts are contained in Apple Japanese (SJIS)
5811 Apple Japanese (SJIS) font. */ 6124 font. */
5812 if (smJapanese == scriptcode) 6125 if (smJapanese == scriptcode)
5813 { 6126 {
5814 font_name_table[font_name_count++] 6127 font_name_table[font_name_count++]
@@ -5835,6 +6148,145 @@ init_font_name_table ()
5835} 6148}
5836 6149
5837 6150
6151enum xlfd_scalable_field_index
6152 {
6153 XLFD_SCL_PIXEL_SIZE,
6154 XLFD_SCL_POINT_SIZE,
6155 XLFD_SCL_AVGWIDTH,
6156 XLFD_SCL_LAST
6157 };
6158
6159static int xlfd_scalable_fields[] =
6160 {
6161 6, /* PIXEL_SIZE */
6162 7, /* POINT_SIZE */
6163 11, /* AVGWIDTH */
6164 -1
6165 };
6166
6167static Lisp_Object
6168mac_do_list_fonts (pattern, maxnames)
6169 char *pattern;
6170 int maxnames;
6171{
6172 int i, n_fonts = 0;
6173 Lisp_Object font_list = Qnil, pattern_regex, fontname;
6174 char *regex = (char *) alloca (strlen (pattern) * 2 + 3);
6175 char scaled[256];
6176 char *ptr;
6177 int scl_val[XLFD_SCL_LAST], *field, *val;
6178
6179 for (i = 0; i < XLFD_SCL_LAST; i++)
6180 scl_val[i] = -1;
6181
6182 /* If the pattern contains 14 dashes and one of PIXEL_SIZE,
6183 POINT_SIZE, and AVGWIDTH fields is explicitly specified, scalable
6184 fonts are scaled according to the specified size. */
6185 ptr = pattern;
6186 i = 0;
6187 field = xlfd_scalable_fields;
6188 val = scl_val;
6189 if (*ptr == '-')
6190 do
6191 {
6192 ptr++;
6193 if (i == *field)
6194 {
6195 if ('1' <= *ptr && *ptr <= '9')
6196 {
6197 *val = *ptr++ - '0';
6198 while ('0' <= *ptr && *ptr <= '9' && *val < 10000)
6199 *val = *val * 10 + *ptr++ - '0';
6200 if (*ptr != '-')
6201 *val = -1;
6202 }
6203 field++;
6204 val++;
6205 }
6206 ptr = strchr (ptr, '-');
6207 i++;
6208 }
6209 while (ptr && i < 14);
6210
6211 if (i == 14 && ptr == NULL)
6212 {
6213 if (scl_val[XLFD_SCL_POINT_SIZE] > 0)
6214 {
6215 scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_POINT_SIZE] / 10;
6216 scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_POINT_SIZE];
6217 }
6218 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0)
6219 {
6220 scl_val[XLFD_SCL_POINT_SIZE] =
6221 scl_val[XLFD_SCL_AVGWIDTH] = scl_val[XLFD_SCL_PIXEL_SIZE] * 10;
6222 }
6223 else if (scl_val[XLFD_SCL_AVGWIDTH] > 0)
6224 {
6225 scl_val[XLFD_SCL_PIXEL_SIZE] = scl_val[XLFD_SCL_AVGWIDTH] / 10;
6226 scl_val[XLFD_SCL_POINT_SIZE] = scl_val[XLFD_SCL_AVGWIDTH];
6227 }
6228 }
6229 else
6230 scl_val[XLFD_SCL_PIXEL_SIZE] = -1;
6231
6232 ptr = regex;
6233 *ptr++ = '^';
6234
6235 /* Turn pattern into a regexp and do a regexp match. */
6236 for (; *pattern; pattern++)
6237 {
6238 if (*pattern == '?')
6239 *ptr++ = '.';
6240 else if (*pattern == '*')
6241 {
6242 *ptr++ = '.';
6243 *ptr++ = '*';
6244 }
6245 else
6246 *ptr++ = tolower (*pattern);
6247 }
6248 *ptr = '$';
6249 *(ptr + 1) = '\0';
6250
6251 pattern_regex = build_string (regex);
6252
6253 for (i = 0; i < font_name_count; i++)
6254 {
6255 fontname = build_string (font_name_table[i]);
6256 if (fast_string_match (pattern_regex, fontname) >= 0)
6257 {
6258 font_list = Fcons (fontname, font_list);
6259
6260 n_fonts++;
6261 if (maxnames > 0 && n_fonts >= maxnames)
6262 break;
6263 }
6264 else if (scl_val[XLFD_SCL_PIXEL_SIZE] > 0
6265 && (ptr = strstr (font_name_table[i], "-0-0-75-75-m-0-")))
6266 {
6267 int former_len = ptr - font_name_table[i];
6268
6269 memcpy (scaled, font_name_table[i], former_len);
6270 sprintf (scaled + former_len,
6271 "-%d-%d-75-75-m-%d-%s",
6272 scl_val[XLFD_SCL_PIXEL_SIZE],
6273 scl_val[XLFD_SCL_POINT_SIZE],
6274 scl_val[XLFD_SCL_AVGWIDTH],
6275 ptr + sizeof ("-0-0-75-75-m-0-") - 1);
6276 fontname = build_string (scaled);
6277 if (fast_string_match (pattern_regex, fontname) >= 0)
6278 {
6279 font_list = Fcons (fontname, font_list);
6280
6281 n_fonts++;
6282 if (maxnames > 0 && n_fonts >= maxnames)
6283 break;
6284 }
6285 }
6286 }
6287 return font_list;
6288}
6289
5838/* Return a list of at most MAXNAMES font specs matching the one in 6290/* Return a list of at most MAXNAMES font specs matching the one in
5839 PATTERN. Cache matching fonts for patterns in 6291 PATTERN. Cache matching fonts for patterns in
5840 dpyinfo->name_list_element to avoid looking them up again by 6292 dpyinfo->name_list_element to avoid looking them up again by
@@ -5847,11 +6299,7 @@ x_list_fonts (struct frame *f,
5847 int size, 6299 int size,
5848 int maxnames) 6300 int maxnames)
5849{ 6301{
5850 char *ptnstr;
5851 Lisp_Object newlist = Qnil, tem, key; 6302 Lisp_Object newlist = Qnil, tem, key;
5852 int n_fonts = 0;
5853 int i;
5854 struct gcpro gcpro1, gcpro2;
5855 struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL; 6303 struct mac_display_info *dpyinfo = f ? FRAME_MAC_DISPLAY_INFO (f) : NULL;
5856 6304
5857 if (font_name_table == NULL) /* Initialize when first used. */ 6305 if (font_name_table == NULL) /* Initialize when first used. */
@@ -5870,27 +6318,10 @@ x_list_fonts (struct frame *f,
5870 } 6318 }
5871 } 6319 }
5872 6320
5873 ptnstr = SDATA (pattern); 6321 newlist = mac_do_list_fonts (SDATA (pattern), maxnames);
5874
5875 GCPRO2 (pattern, newlist);
5876
5877 /* Scan and matching bitmap fonts. */
5878 for (i = 0; i < font_name_count; i++)
5879 {
5880 if (mac_font_pattern_match (font_name_table[i], ptnstr))
5881 {
5882 newlist = Fcons (build_string (font_name_table[i]), newlist);
5883
5884 n_fonts++;
5885 if (maxnames > 0 && n_fonts >= maxnames)
5886 break;
5887 }
5888 }
5889 6322
5890 /* MAC_TODO: add code for matching outline fonts here */ 6323 /* MAC_TODO: add code for matching outline fonts here */
5891 6324
5892 UNGCPRO;
5893
5894 if (dpyinfo) 6325 if (dpyinfo)
5895 { 6326 {
5896 XSETCDR (dpyinfo->name_list_element, 6327 XSETCDR (dpyinfo->name_list_element,
@@ -6050,14 +6481,12 @@ XLoadQueryFont (Display *dpy, char *fontname)
6050 name = fontname; 6481 name = fontname;
6051 else 6482 else
6052 { 6483 {
6053 for (i = 0; i < font_name_count; i++) 6484 Lisp_Object matched_fonts;
6054 if (mac_font_pattern_match (font_name_table[i], fontname))
6055 break;
6056 6485
6057 if (i >= font_name_count) 6486 matched_fonts = mac_do_list_fonts (fontname, 1);
6058 return NULL; 6487 if (NILP (matched_fonts))
6059 6488 return NULL;
6060 name = font_name_table[i]; 6489 name = SDATA (XCAR (matched_fonts));
6061 } 6490 }
6062 6491
6063 GetPort (&port); /* save the current font number used */ 6492 GetPort (&port); /* save the current font number used */
@@ -6179,7 +6608,8 @@ XLoadQueryFont (Display *dpy, char *fontname)
6179 for (c = 0x20; c <= 0xff; c++) 6608 for (c = 0x20; c <= 0xff; c++)
6180 { 6609 {
6181 font->per_char[c - 0x20] = font->max_bounds; 6610 font->per_char[c - 0x20] = font->max_bounds;
6182 font->per_char[c - 0x20].width = CharWidth (c); 6611 font->per_char[c - 0x20].width =
6612 font->per_char[c - 0x20].rbearing = CharWidth (c);
6183 } 6613 }
6184 } 6614 }
6185 } 6615 }
@@ -7833,14 +8263,32 @@ XTread_socket (int sd, struct input_event *bufp, int numchars, int expected)
7833 } 8263 }
7834 else 8264 else
7835 { 8265 {
7836 bufp->kind = MOUSE_CLICK_EVENT; 8266 Lisp_Object window;
8267
8268 bufp->kind = MOUSE_CLICK_EVENT;
7837 XSETFRAME (bufp->frame_or_window, mwp->mFP); 8269 XSETFRAME (bufp->frame_or_window, mwp->mFP);
7838 if (er.what == mouseDown) 8270 if (er.what == mouseDown)
7839 mouse_tracking_in_progress 8271 mouse_tracking_in_progress
7840 = mouse_tracking_mouse_movement; 8272 = mouse_tracking_mouse_movement;
7841 else 8273 else
7842 mouse_tracking_in_progress = mouse_tracking_none; 8274 mouse_tracking_in_progress = mouse_tracking_none;
7843 } 8275 window = window_from_coordinates (mwp->mFP, bufp->x, bufp->y, 0, 0, 0, 1);
8276
8277 if (EQ (window, mwp->mFP->tool_bar_window))
8278 {
8279 if (er.what == mouseDown)
8280 handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 1, 0);
8281 else
8282 handle_tool_bar_click (mwp->mFP, bufp->x, bufp->y, 0,
8283#if USE_CARBON_EVENTS
8284 mac_event_to_emacs_modifiers (eventRef)
8285#else
8286 er.modifiers
8287#endif
8288 );
8289 break;
8290 }
8291 }
7844 8292
7845#if USE_CARBON_EVENTS 8293#if USE_CARBON_EVENTS
7846 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef); 8294 bufp->modifiers = mac_event_to_emacs_modifiers (eventRef);
@@ -8352,12 +8800,16 @@ mac_initialize_display_info ()
8352 dpyinfo->reference_count = 0; 8800 dpyinfo->reference_count = 0;
8353 dpyinfo->resx = 75.0; 8801 dpyinfo->resx = 75.0;
8354 dpyinfo->resy = 75.0; 8802 dpyinfo->resy = 75.0;
8355 dpyinfo->n_planes = 1; 8803 dpyinfo->color_p = TestDeviceAttribute (main_device_handle, gdDevType);
8356 dpyinfo->n_cbits = 16; 8804 for (dpyinfo->n_planes = 32; dpyinfo->n_planes > 0; dpyinfo->n_planes >>= 1)
8805 if (HasDepth (main_device_handle, dpyinfo->n_planes,
8806 gdDevType, dpyinfo->color_p))
8807 break;
8357 dpyinfo->height = (**main_device_handle).gdRect.bottom; 8808 dpyinfo->height = (**main_device_handle).gdRect.bottom;
8358 dpyinfo->width = (**main_device_handle).gdRect.right; 8809 dpyinfo->width = (**main_device_handle).gdRect.right;
8359 dpyinfo->grabbed = 0; 8810 dpyinfo->grabbed = 0;
8360 dpyinfo->root_window = NULL; 8811 dpyinfo->root_window = NULL;
8812 dpyinfo->image_cache = make_image_cache ();
8361 8813
8362 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 8814 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
8363 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 8815 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
@@ -8696,6 +9148,18 @@ syms_of_macterm ()
8696 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); 9148 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop");
8697 staticpro (&Qmac_ready_for_drag_n_drop); 9149 staticpro (&Qmac_ready_for_drag_n_drop);
8698 9150
9151 Qbig5 = intern ("big5");
9152 staticpro (&Qbig5);
9153
9154 Qcn_gb = intern ("cn-gb");
9155 staticpro (&Qcn_gb);
9156
9157 Qsjis = intern ("sjis");
9158 staticpro (&Qsjis);
9159
9160 Qeuc_kr = intern ("euc-kr");
9161 staticpro (&Qeuc_kr);
9162
8699 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, 9163 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p,
8700 doc: /* *Non-nil means autoselect window with mouse pointer. */); 9164 doc: /* *Non-nil means autoselect window with mouse pointer. */);
8701 x_autoselect_window_p = 0; 9165 x_autoselect_window_p = 0;