Mercurial > emacs
comparison src/macterm.c @ 83066:887bb2eb4a89
Merged in changes from CVS HEAD
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-116
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-117
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-106
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Sat, 28 Feb 2004 01:33:17 +0000 |
parents | 03a73693678e 6c8849d06ab3 |
children | b44978264e1d |
comparison
equal
deleted
inserted
replaced
83065:a871be7b26a5 | 83066:887bb2eb4a89 |
---|---|
33 #ifndef MAC_OSX | 33 #ifndef MAC_OSX |
34 #include <alloca.h> | 34 #include <alloca.h> |
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. */ |
64 #define USE_CARBON_EVENTS 1 | 41 #define USE_CARBON_EVENTS 1 |
65 #else /* not MAC_OSX */ | 42 #else /* not MAC_OSX */ |
301 static void frame_unhighlight P_ ((struct frame *)); | 278 static void frame_unhighlight P_ ((struct frame *)); |
302 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); | 279 static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); |
303 static void XTframe_rehighlight P_ ((struct frame *)); | 280 static void XTframe_rehighlight P_ ((struct frame *)); |
304 static void x_frame_rehighlight P_ ((struct x_display_info *)); | 281 static void x_frame_rehighlight P_ ((struct x_display_info *)); |
305 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); | 282 static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); |
306 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); | 283 static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, |
284 enum text_cursor_kinds)); | |
285 | |
307 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); | 286 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, GC)); |
308 static void x_flush P_ ((struct frame *f)); | 287 static void x_flush P_ ((struct frame *f)); |
309 static void x_update_begin P_ ((struct frame *)); | 288 static void x_update_begin P_ ((struct frame *)); |
310 static void x_update_window_begin P_ ((struct window *)); | 289 static void x_update_window_begin P_ ((struct window *)); |
311 static void x_after_update_window_line P_ ((struct glyph_row *)); | 290 static void x_after_update_window_line P_ ((struct glyph_row *)); |
325 extern void menubar_selection_callback (FRAME_PTR, int); | 304 extern void menubar_selection_callback (FRAME_PTR, int); |
326 extern void set_frame_menubar (FRAME_PTR, int, int); | 305 extern void set_frame_menubar (FRAME_PTR, int, int); |
327 | 306 |
328 /* X display function emulation */ | 307 /* X display function emulation */ |
329 | 308 |
330 static void | 309 void |
331 XFreePixmap (display, pixmap) | 310 XFreePixmap (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 |
342 /* Set foreground color for subsequent QuickDraw commands. Assume | 318 /* Set foreground color for subsequent QuickDraw commands. Assume |
343 graphic port has already been set. */ | 319 graphic port has already been set. */ |
345 static void | 321 static void |
346 mac_set_forecolor (unsigned long color) | 322 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 } |
356 | 332 |
357 | 333 |
361 static void | 337 static void |
362 mac_set_backcolor (unsigned long color) | 338 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 } |
372 | 348 |
373 /* Set foreground and background color for subsequent QuickDraw | 349 /* Set foreground and background color for subsequent QuickDraw |
397 | 373 |
398 mac_set_colors (gc); | 374 mac_set_colors (gc); |
399 | 375 |
400 MoveTo (x1, y1); | 376 MoveTo (x1, y1); |
401 LineTo (x2, y2); | 377 LineTo (x2, y2); |
378 } | |
379 | |
380 void | |
381 mac_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)); | |
402 } | 395 } |
403 | 396 |
404 /* Mac version of XClearArea. */ | 397 /* Mac version of XClearArea. */ |
405 | 398 |
406 void | 399 void |
477 { | 470 { |
478 BitMap bitmap; | 471 BitMap bitmap; |
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 |
486 SetPort (GetWindowPort (w)); | 479 SetPort (GetWindowPort (w)); |
487 #else | 480 #else |
488 SetPort (w); | 481 SetPort (w); |
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); |
507 #endif /* not TARGET_API_MAC_CARBON */ | 495 #endif /* not TARGET_API_MAC_CARBON */ |
508 } | 496 } |
544 SetRect (&r, -32767, -32767, 32767, 32767); | 532 SetRect (&r, -32767, -32767, 32767, 32767); |
545 ClipRect (&r); | 533 ClipRect (&r); |
546 } | 534 } |
547 | 535 |
548 | 536 |
537 /* XBM bits seem to be backward within bytes compared with how | |
538 Mac does things. */ | |
539 static unsigned char | |
540 reflect_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 |
551 static void | 556 static void |
552 mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h) | 557 mac_create_bitmap_from_bitmap_data (bitmap, bits, w, h) |
553 BitMap *bitmap; | 558 BitMap *bitmap; |
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; |
558 | 563 char *p; |
559 bitmap->rowBytes = (w + 15) / 16 * 2; /* must be on word boundary */ | 564 |
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 } |
572 | 578 |
573 | 579 |
575 mac_free_bitmap (bitmap) | 581 mac_free_bitmap (bitmap) |
576 BitMap *bitmap; | 582 BitMap *bitmap; |
577 { | 583 { |
578 xfree (bitmap->baseAddr); | 584 xfree (bitmap->baseAddr); |
579 } | 585 } |
586 | |
587 | |
588 Pixmap | |
589 XCreatePixmap (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 | |
613 Pixmap | |
614 XCreatePixmapFromBitmapData (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 | |
580 | 647 |
581 /* Mac replacement for XFillRectangle. */ | 648 /* Mac replacement for XFillRectangle. */ |
582 | 649 |
583 static void | 650 static void |
584 XFillRectangle (display, w, gc, x, y, width, height) | 651 XFillRectangle (display, w, gc, x, y, width, height) |
601 | 668 |
602 PaintRect (&r); /* using foreground color of gc */ | 669 PaintRect (&r); /* using foreground color of gc */ |
603 } | 670 } |
604 | 671 |
605 | 672 |
673 static void | |
674 mac_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 |
608 static void | 695 static void |
609 mac_draw_rectangle (display, w, gc, x, y, width, height) | 696 mac_draw_rectangle (display, w, gc, x, y, width, height) |
610 Display *display; | 697 Display *display; |
636 Pixmap p; | 723 Pixmap p; |
637 GC gc; | 724 GC gc; |
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 |
658 static void | 740 static void |
659 mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, | 741 mac_draw_string_common (display, w, gc, x, y, buf, nchars, mode, |
764 SetPort (GetWindowPort (dest)); | 846 SetPort (GetWindowPort (dest)); |
765 #else | 847 #else |
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), |
777 | 861 GetPortBitMapForCopyBits (GetWindowPort (dest)), |
778 LockPortBits (GetWindowPort (dest)); | 862 &src_r, &dest_r, srcCopy, 0); |
779 pmh = GetPortPixMap (GetWindowPort (dest)); | 863 UnlockPortBits (GetWindowPort (dest)); |
780 CopyBits ((BitMap *) &src, (BitMap *) *pmh, &src_r, &dest_r, srcCopy, 0); | |
781 UnlockPortBits (GetWindowPort (dest)); | |
782 } | |
783 #else /* not TARGET_API_MAC_CARBON */ | 864 #else /* not TARGET_API_MAC_CARBON */ |
784 CopyBits ((BitMap *) &src, &(dest->portBits), &src_r, &dest_r, srcCopy, 0); | 865 CopyBits (&(((GrafPtr)src)->portBits), &(dest->portBits), |
866 &src_r, &dest_r, srcCopy, 0); | |
785 #endif /* not TARGET_API_MAC_CARBON */ | 867 #endif /* not TARGET_API_MAC_CARBON */ |
868 UnlockPixels (GetGWorldPixMap (src)); | |
869 } | |
870 | |
871 | |
872 static void | |
873 mac_copy_area_with_mask (display, src, mask, dest, gc, src_x, src_y, | |
874 width, height, dest_x, dest_y) | |
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)); | |
905 #else /* not TARGET_API_MAC_CARBON */ | |
906 CopyMask (&(((GrafPtr)src)->portBits), &(((GrafPtr)mask)->portBits), | |
907 &(dest->portBits), &src_r, &src_r, &dest_r); | |
908 #endif /* not TARGET_API_MAC_CARBON */ | |
909 UnlockPixels (GetGWorldPixMap (mask)); | |
910 UnlockPixels (GetGWorldPixMap (src)); | |
786 } | 911 } |
787 | 912 |
788 | 913 |
789 #if 0 | 914 #if 0 |
790 /* Convert a pair of local coordinates to global (screen) coordinates. | 915 /* Convert a pair of local coordinates to global (screen) coordinates. |
815 unsigned int width, height; | 940 unsigned int width, height; |
816 int dest_x, dest_y; | 941 int 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); |
824 | 948 |
825 SetPort (GetWindowPort (w)); | 949 SetPort (GetWindowPort (w)); |
826 | 950 |
827 ForeColor (blackColor); | 951 ForeColor (blackColor); |
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); |
836 #else /* not TARGET_API_MAC_CARBON */ | 962 #else /* not TARGET_API_MAC_CARBON */ |
837 Rect src_r, dest_r; | 963 Rect src_r, dest_r; |
870 | 996 |
871 static void | 997 static void |
872 mac_copy_area_to_pixmap (display, src, dest, gc, src_x, src_y, width, height, | 998 mac_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; | 1008 |
884 int src_bottom = ((PixMap *) src)->bounds.bottom; | 1009 SetGWorld (dest, NULL); |
885 int w = src_right - src_x; | 1010 ForeColor (blackColor); |
886 int h = src_bottom - src_y; | 1011 BackColor (whiteColor); |
887 | 1012 |
888 mac_set_colors (gc); | 1013 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); |
889 | 1014 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); |
890 SetRect (&src_r, src_x, src_y, src_right, src_bottom); | 1015 |
891 SetRect (&dest_r, dest_x, dest_y, dest_x + w, dest_y + h); | 1016 LockPixels (GetGWorldPixMap (src)); |
892 | 1017 LockPixels (GetGWorldPixMap (dest)); |
893 CopyBits ((BitMap *) &src, (BitMap *) &dest, &src_r, &dest_r, srcCopy, 0); | 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 | |
1030 static void | |
1031 mac_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); | |
1045 | |
1046 SetRect (&src_r, src_x, src_y, src_x + width, src_y + height); | |
1047 SetRect (&dest_r, dest_x, dest_y, dest_x + width, dest_y + height); | |
1048 | |
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 |
897 /* Mac replacement for XChangeGC. */ | 1065 /* Mac replacement for XChangeGC. */ |
898 | 1066 |
945 } | 1113 } |
946 | 1114 |
947 | 1115 |
948 /* Mac replacement for XSetForeground. */ | 1116 /* Mac replacement for XSetForeground. */ |
949 | 1117 |
950 static void | 1118 void |
951 XSetForeground (display, gc, color) | 1119 XSetForeground (display, gc, color) |
952 Display *display; | 1120 Display *display; |
953 GC gc; | 1121 GC gc; |
954 unsigned long color; | 1122 unsigned long color; |
955 { | 1123 { |
2137 return color.pixel; | 2305 return color.pixel; |
2138 } | 2306 } |
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 |
2145 values have DELTA added. Return the allocated color in *COLOR. | 2328 values have DELTA added. Return the allocated color in *COLOR. |
2146 DISPLAY is the X display, CMAP is the colormap to operate on. | 2329 DISPLAY is the X display, CMAP is the colormap to operate on. |
2152 unsigned long *color; | 2335 unsigned long *color; |
2153 double factor; | 2336 double factor; |
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)))), |
2166 max (0, min (0xff, (int) (delta + BLUE_FROM_ULONG (*color))))); | 2379 max (0, min (0xff, (int) (delta + BLUE_FROM_ULONG (*color))))); |
2167 | 2380 |
2202 /* MAC_TODO: Free colors (if using palette)? */ | 2415 /* MAC_TODO: Free colors (if using palette)? */ |
2203 | 2416 |
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; |
2211 } | 2425 } |
2212 | 2426 |
2232 struct mac_output *di = s->f->output_data.mac; | 2446 struct mac_output *di = s->f->output_data.mac; |
2233 unsigned long color; | 2447 unsigned long color; |
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; |
2240 | 2458 |
2241 /* Get the background color of the face. */ | 2459 /* Get the background color of the face. */ |
2265 | 2483 |
2266 static void | 2484 static void |
2267 x_draw_relief_rect (f, left_x, top_y, right_x, bottom_y, width, | 2485 x_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 |
2276 if (raised_p) | 2496 if (raised_p) |
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 |
2318 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y, | 2538 /* Draw a box on frame F inside the rectangle given by LEFT_X, TOP_Y, |
2319 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to | 2539 RIGHT_X, and BOTTOM_Y. WIDTH is the thickness of the lines to |
2324 | 2544 |
2325 static void | 2545 static void |
2326 x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width, | 2546 x_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; |
2333 | 2553 |
2334 xgcv.foreground = s->face->box_color; | 2554 xgcv.foreground = s->face->box_color; |
2335 mac_set_clip_rectangle (s->display, s->window, clip_rect); | 2555 mac_set_clip_rectangle (s->display, s->window, clip_rect); |
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 } |
2357 | 2577 |
2358 | 2578 |
2383 : s->first_glyph + s->nchars - 1); | 2603 : s->first_glyph + s->nchars - 1); |
2384 | 2604 |
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 |
2394 left_p = (s->first_glyph->left_box_line_p | 2614 left_p = (s->first_glyph->left_box_line_p |
2395 || (s->hl == DRAW_MOUSE_FACE | 2615 || (s->hl == DRAW_MOUSE_FACE |
2436 x += s->img->hmargin; | 2656 x += s->img->hmargin; |
2437 y += s->img->vmargin; | 2657 y += s->img->vmargin; |
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 |
2477 be visible. If the image doesn't have a mask, make | 2694 be visible. If the image doesn't have a mask, make |
2478 a block cursor visible by drawing a rectangle around | 2695 a block cursor visible by drawing a rectangle around |
2492 mac_draw_rectangle (s->display, s->window, s->gc, x, y, | 2709 mac_draw_rectangle (s->display, s->window, s->gc, x, y, |
2493 s->img->width - 1, s->img->height - 1); | 2710 s->img->width - 1, s->img->height - 1); |
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 |
2500 static void | 2716 static void |
2501 x_draw_image_relief (s) | 2717 x_draw_image_relief (s) |
2502 struct glyph_string *s; | 2718 struct glyph_string *s; |
2565 x += s->img->hmargin; | 2781 x += s->img->hmargin; |
2566 y += s->img->vmargin; | 2782 y += s->img->vmargin; |
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); |
2597 | 2795 |
2598 /* When the image has a mask, we can expect that at | 2796 /* When the image has a mask, we can expect that at |
2603 nothing here for mouse-face. */ | 2801 nothing here for mouse-face. */ |
2604 if (s->hl == DRAW_CURSOR) | 2802 if (s->hl == DRAW_CURSOR) |
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 |
2620 /* Draw part of the background of glyph string S. X, Y, W, and H | 2819 /* Draw part of the background of glyph string S. X, Y, W, and H |
2621 give the rectangle to draw. */ | 2820 give the rectangle to draw. */ |
2644 s->y | 2843 s->y |
2645 s->x +------------------------- | 2844 s->x +------------------------- |
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 |
2653 | 2852 |
2654 */ | 2853 */ |
2662 int box_line_vwidth = max (s->face->box_line_width, 0); | 2861 int box_line_vwidth = max (s->face->box_line_width, 0); |
2663 int height; | 2862 int height; |
2664 Pixmap pixmap = 0; | 2863 Pixmap pixmap = 0; |
2665 | 2864 |
2666 height = s->height - 2 * box_line_vwidth; | 2865 height = s->height - 2 * box_line_vwidth; |
2866 | |
2667 | 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. */ |
2671 s->stippled_p = s->face->stipple != 0; | 2871 s->stippled_p = s->face->stipple != 0; |
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 { |
2681 if (box_line_hwidth && s->first_glyph->left_box_line_p) | 2879 if (box_line_hwidth && s->first_glyph->left_box_line_p) |
2682 x = s->x + box_line_hwidth; | 2880 x = s->x + box_line_hwidth; |
2683 else | 2881 else |
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. */ |
2709 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); | 2903 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); |
2710 XFillRectangle (s->display, pixmap, s->gc, | 2904 XFillRectangle (s->display, pixmap, s->gc, |
2711 0, 0, s->background_width, s->height); | 2905 0, 0, s->background_width, s->height); |
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; |
2730 } | 2925 } |
2731 | 2926 |
2733 if (pixmap != 0) | 2928 if (pixmap != 0) |
2734 { | 2929 { |
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 } |
2742 else | 2937 else |
2743 x_draw_image_foreground (s); | 2938 x_draw_image_foreground (s); |
2770 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height); | 2965 x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height); |
2771 | 2966 |
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)) |
2782 { | 2977 { |
2783 x_set_mouse_face_gc (s); | 2978 x_set_mouse_face_gc (s); |
2833 { | 3028 { |
2834 xassert (s->next->img == NULL); | 3029 xassert (s->next->img == NULL); |
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. */ |
2842 x_set_glyph_string_gc (s); | 3036 x_set_glyph_string_gc (s); |
2843 | 3037 |
2870 | 3064 |
2871 case CHAR_GLYPH: | 3065 case CHAR_GLYPH: |
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 |
2879 case COMPOSITE_GLYPH: | 3073 case COMPOSITE_GLYPH: |
2880 if (s->for_overlaps_p || s->gidx > 0) | 3074 if (s->for_overlaps_p || s->gidx > 0) |
2947 s->width, h); | 3141 s->width, h); |
2948 XSetForeground (s->display, s->gc, xgcv.foreground); | 3142 XSetForeground (s->display, s->gc, xgcv.foreground); |
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. */ |
2958 mac_reset_clipping (s->display, s->window); | 3152 mac_reset_clipping (s->display, s->window); |
2959 } | 3153 } |
2968 mac_scroll_area (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), | 3162 mac_scroll_area (FRAME_MAC_DISPLAY (f), FRAME_MAC_WINDOW (f), |
2969 f->output_data.mac->normal_gc, | 3163 f->output_data.mac->normal_gc, |
2970 x, y, width, height, | 3164 x, y, width, height, |
2971 x + shift_by, y); | 3165 x + shift_by, y); |
2972 } | 3166 } |
2973 | |
2974 | 3167 |
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 |
2978 static void | 3171 static void |
3024 /* We use the select system call to do the waiting, so we have to make | 3217 /* We use the select system call to do the waiting, so we have to make |
3025 sure it's available. If it isn't, we just won't do visual bells. */ | 3218 sure it's available. If it isn't, we just won't do visual bells. */ |
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 |
3032 static int | 3226 static int |
3033 timeval_subtract (result, x, y) | 3227 timeval_subtract (result, x, y) |
3127 /* Specify how many text lines, from the top of the window, | 3321 /* Specify how many text lines, from the top of the window, |
3128 should be affected by insert-lines and delete-lines operations. | 3322 should be affected by insert-lines and delete-lines operations. |
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 |
3132 void | 3326 static void |
3133 XTset_terminal_window (n) | 3327 XTset_terminal_window (n) |
3134 register int n; | 3328 register int n; |
3135 { | 3329 { |
3136 /* This function intentionally left blank. */ | 3330 /* This function intentionally left blank. */ |
3137 } | 3331 } |
3163 struct frame *f = XFRAME (w->frame); | 3357 struct frame *f = XFRAME (w->frame); |
3164 int x, y, width, height, from_y, to_y, bottom_y; | 3358 int x, y, width, height, from_y, to_y, bottom_y; |
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); |
3172 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); | 3366 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, run->desired_y); |
3173 bottom_y = y + height; | 3367 bottom_y = y + height; |
3285 | 3479 |
3286 static void | 3480 static void |
3287 XTframe_rehighlight (frame) | 3481 XTframe_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 |
3295 static void | 3487 static void |
3296 x_frame_rehighlight (dpyinfo) | 3488 x_frame_rehighlight (dpyinfo) |
4427 int x, y, wd, h; | 4619 int x, y, wd, h; |
4428 XGCValues xgcv; | 4620 XGCValues xgcv; |
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); |
4442 if (cursor_glyph == NULL) | 4627 if (cursor_glyph == NULL) |
4443 return; | 4628 return; |
4448 width instead. */ | 4633 width instead. */ |
4449 wd = cursor_glyph->pixel_width - 1; | 4634 wd = cursor_glyph->pixel_width - 1; |
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. */ |
4456 xgcv.foreground = f->output_data.mac->cursor_pixel; | 4655 xgcv.foreground = f->output_data.mac->cursor_pixel; |
4457 if (dpyinfo->scratch_cursor_gc) | 4656 if (dpyinfo->scratch_cursor_gc) |
4474 angle equal to the one given by the font property XA_ITALIC_ANGLE. | 4673 angle equal to the one given by the font property XA_ITALIC_ANGLE. |
4475 Unfortunately, I didn't find a font yet that has this property set. | 4674 Unfortunately, I didn't find a font yet that has this property set. |
4476 --gerd. */ | 4675 --gerd. */ |
4477 | 4676 |
4478 static void | 4677 static void |
4479 x_draw_bar_cursor (w, row, width) | 4678 x_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; |
4483 { | 4682 enum text_cursor_kinds kind; |
4484 /* If cursor hpos is out of bounds, don't draw garbage. This can | 4683 { |
4485 happen in mini-buffer windows when switching between echo area | 4684 struct frame *f = XFRAME (w->frame); |
4486 glyphs and mini-buffer. */ | 4685 struct glyph *cursor_glyph; |
4487 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) | 4686 |
4488 { | 4687 /* If cursor is out of bounds, don't draw garbage. This can happen |
4489 struct frame *f = XFRAME (w->frame); | 4688 in mini-buffer windows when switching between echo area glyphs |
4490 struct glyph *cursor_glyph; | 4689 and mini-buffer. */ |
4491 GC gc; | 4690 cursor_glyph = get_phys_cursor_glyph (w); |
4492 int x; | 4691 if (cursor_glyph == NULL) |
4493 unsigned long mask; | 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) | |
4698 { | |
4699 struct glyph_row *row; | |
4700 row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos); | |
4701 draw_phys_cursor_glyph (w, row, DRAW_CURSOR); | |
4702 } | |
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; | 4711 |
4496 Window window; | 4712 /* If the glyph's background equals the color we normally draw |
4497 | 4713 the bar cursor in, the bar cursor in its normal color is |
4498 cursor_glyph = get_phys_cursor_glyph (w); | 4714 invisible. Use the glyph's foreground color instead in this |
4499 if (cursor_glyph == NULL) | 4715 case, on the assumption that the glyph's colors are chosen so |
4500 return; | 4716 that the glyph is legible. */ |
4501 | 4717 if (face->background == f->output_data.mac->cursor_pixel) |
4502 xgcv.background = f->output_data.mac->cursor_pixel; | 4718 xgcv.background = xgcv.foreground = face->foreground; |
4503 xgcv.foreground = f->output_data.mac->cursor_pixel; | 4719 else |
4504 mask = GCForeground | GCBackground; | 4720 xgcv.background = xgcv.foreground = f->output_data.mac->cursor_pixel; |
4505 dpy = FRAME_MAC_DISPLAY (f); | |
4506 window = FRAME_MAC_WINDOW (f); | |
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); |
4511 else | 4724 else |
4512 { | 4725 { |
4514 FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc = gc; | 4727 FRAME_MAC_DISPLAY_INFO (f)->scratch_cursor_gc = gc; |
4515 } | 4728 } |
4516 | 4729 |
4517 if (width < 0) | 4730 if (width < 0) |
4518 width = FRAME_CURSOR_WIDTH (f); | 4731 width = FRAME_CURSOR_WIDTH (f); |
4519 | 4732 width = min (cursor_glyph->pixel_width, width); |
4520 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); | 4733 |
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 } |
4530 | 4753 |
4531 | 4754 |
4563 int on_p, active_p; | 4786 int on_p, active_p; |
4564 { | 4787 { |
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 |
4572 && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]) | 4794 && w->phys_cursor.hpos >= glyph_row->used[TEXT_AREA]) |
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: |
4582 x_draw_hollow_cursor (w, glyph_row); | 4803 x_draw_hollow_cursor (w, glyph_row); |
4583 break; | 4804 break; |
4584 | 4805 |
4585 case FILLED_BOX_CURSOR: | 4806 case FILLED_BOX_CURSOR: |
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 |
4810 case BAR_CURSOR: | |
4811 x_draw_bar_cursor (w, glyph_row, cursor_width, BAR_CURSOR); | |
4812 break; | |
4813 | |
4589 case HBAR_CURSOR: | 4814 case HBAR_CURSOR: |
4590 /* TODO. For now, just draw bar cursor. */ | 4815 x_draw_bar_cursor (w, glyph_row, cursor_width, HBAR_CURSOR); |
4591 case BAR_CURSOR: | |
4592 x_draw_bar_cursor (w, glyph_row, cursor_width); | |
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: |
4599 abort (); | 4823 abort (); |
4600 } | 4824 } |
5115 | 5339 |
5116 /* See if a MapNotify event has been processed. */ | 5340 /* See if a MapNotify event has been processed. */ |
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 |
5123 /* Change from mapped state to withdrawn state. */ | 5349 /* Change from mapped state to withdrawn state. */ |
5124 | 5350 |
5171 | 5397 |
5172 UNBLOCK_INPUT; | 5398 UNBLOCK_INPUT; |
5173 } | 5399 } |
5174 | 5400 |
5175 | 5401 |
5176 /* Destroy the X window of frame F. */ | 5402 /* Free X resources of frame F. */ |
5177 | 5403 |
5178 void | 5404 void |
5179 x_destroy_window (f) | 5405 x_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); |
5183 | 5409 |
5184 BLOCK_INPUT; | 5410 BLOCK_INPUT; |
5185 | 5411 |
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) |
5196 dpyinfo->x_focus_event_frame = 0; | 5427 dpyinfo->x_focus_event_frame = 0; |
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 | |
5200 dpyinfo->reference_count--; | |
5201 | 5430 |
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 |
5205 = dpyinfo->mouse_face_beg_col = -1; | 5434 = dpyinfo->mouse_face_beg_col = -1; |
5210 dpyinfo->mouse_face_mouse_frame = 0; | 5439 dpyinfo->mouse_face_mouse_frame = 0; |
5211 } | 5440 } |
5212 | 5441 |
5213 UNBLOCK_INPUT; | 5442 UNBLOCK_INPUT; |
5214 } | 5443 } |
5444 | |
5445 | |
5446 /* Destroy the X window of frame F. */ | |
5447 | |
5448 void | |
5449 x_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 |
5218 /* Set the normal size hints for the window manager, for frame F. | 5462 /* Set the normal size hints for the window manager, for frame F. |
5219 FLAGS is the flags word to use--or 0 meaning preserve the flags | 5463 FLAGS is the flags word to use--or 0 meaning preserve the flags |
5476 /* the global font name table */ | 5720 /* the global font name table */ |
5477 char **font_name_table = NULL; | 5721 char **font_name_table = NULL; |
5478 int font_name_table_size = 0; | 5722 int font_name_table_size = 0; |
5479 int font_name_count = 0; | 5723 int font_name_count = 0; |
5480 | 5724 |
5725 #if 0 | |
5481 /* compare two strings ignoring case */ | 5726 /* compare two strings ignoring case */ |
5482 static int | 5727 static int |
5483 stricmp (const char *s, const char *t) | 5728 stricmp (const char *s, const char *t) |
5484 { | 5729 { |
5485 for ( ; tolower (*s) == tolower (*t); s++, t++) | 5730 for ( ; tolower (*s) == tolower (*t); s++, t++) |
5555 && wildstrieq (m_weight, x_weight) | 5800 && wildstrieq (m_weight, x_weight) |
5556 && wildstrieq (m_slant, x_slant) | 5801 && wildstrieq (m_slant, x_slant) |
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 | |
5807 static Lisp_Object Qbig5, Qcn_gb, Qsjis, Qeuc_kr; | |
5808 | |
5809 static void | |
5810 decode_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 |
5562 static char * | 5847 static char * |
5563 mac_to_x_fontname (char *name, int size, Style style, short scriptcode) | 5848 mac_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 { |
5570 strcpy(foundry, "Apple"); | 5855 strcpy(foundry, "Apple"); |
5571 strcpy(family, name); | 5856 strcpy(family, name); |
5620 names are handled accordingly. */ | 5905 names are handled accordingly. */ |
5621 static void | 5906 static void |
5622 x_font_name_to_mac_font_name (char *xf, char *mf) | 5907 x_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 |
5628 if (sscanf (xf, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", | 5915 if (sscanf (xf, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", |
5629 foundry, family, weight, slant, cs) != 5 && | 5916 foundry, family, weight, slant, cs) != 5 && |
5630 sscanf (xf, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", | 5917 sscanf (xf, "-%31[^-]-%31[^-]-%19[^-]-%1[^-]-%*[^-]--%*[^-]-%*[^-]-%*[^-]-%*[^-]-%*c-%*[^-]-%31s", |
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 |
5644 static void | 5947 static void |
5645 add_font_name_table_entry (char *font_name) | 5948 add_font_name_table_entry (char *font_name) |
5699 SInt16 sc; | 6002 SInt16 sc; |
5700 | 6003 |
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 |
6021 contained in Apple Japanese (SJIS) font. */ | |
6022 again: | |
6023 if (size == 0) | |
6024 { | |
6025 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
6026 style, sc)); | |
6027 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
6028 italic, sc)); | |
6029 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
6030 bold, sc)); | |
6031 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
6032 italic | bold, | |
6033 sc)); | |
6034 } | |
6035 else | |
5715 add_font_name_table_entry (mac_to_x_fontname (name, size, | 6036 add_font_name_table_entry (mac_to_x_fontname (name, size, |
5716 style, sc)); | 6037 style, sc)); |
5717 add_font_name_table_entry (mac_to_x_fontname (name, size, | 6038 if (sc == smJapanese) |
5718 italic, sc)); | 6039 { |
5719 add_font_name_table_entry (mac_to_x_fontname (name, size, | 6040 sc = -smJapanese; |
5720 bold, sc)); | 6041 goto again; |
5721 add_font_name_table_entry (mac_to_x_fontname (name, size, | 6042 } |
5722 italic | bold, | 6043 else if (sc == -smJapanese) |
5723 sc)); | 6044 sc = smJapanese; |
5724 } | 6045 } |
5725 else | |
5726 { | |
5727 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
5728 style, sc)); | |
5729 if (smJapanese == sc) | |
5730 add_font_name_table_entry (mac_to_x_fontname (name, size, | |
5731 style, | |
5732 -smJapanese)); | |
5733 } | |
5734 } | 6046 } |
5735 | 6047 |
5736 /* Dispose of the iterators. */ | 6048 /* Dispose of the iterators. */ |
5737 FMDisposeFontFamilyIterator (&ffi); | 6049 FMDisposeFontFamilyIterator (&ffi); |
5738 FMDisposeFontFamilyInstanceIterator (&ffii); | 6050 FMDisposeFontFamilyInstanceIterator (&ffii); |
5770 if (fontnum == 0) | 6082 if (fontnum == 0) |
5771 continue; | 6083 continue; |
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); |
5778 | 6091 |
5779 if (GetResourceSizeOnDisk (font_handle) | 6092 if (GetResourceSizeOnDisk (font_handle) |
5804 font_name_table[font_name_count++] | 6117 font_name_table[font_name_count++] |
5805 = mac_to_x_fontname (name, | 6118 = mac_to_x_fontname (name, |
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++] |
5815 = mac_to_x_fontname (name, | 6128 = mac_to_x_fontname (name, |
5816 assc_entry->fontSize, | 6129 assc_entry->fontSize, |
5833 } | 6146 } |
5834 #endif /* TARGET_API_MAC_CARBON */ | 6147 #endif /* TARGET_API_MAC_CARBON */ |
5835 } | 6148 } |
5836 | 6149 |
5837 | 6150 |
6151 enum 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 | |
6159 static int xlfd_scalable_fields[] = | |
6160 { | |
6161 6, /* PIXEL_SIZE */ | |
6162 7, /* POINT_SIZE */ | |
6163 11, /* AVGWIDTH */ | |
6164 -1 | |
6165 }; | |
6166 | |
6167 static Lisp_Object | |
6168 mac_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 |
5841 calling mac_font_pattern_match (slow). Return as many matching | 6293 calling mac_font_pattern_match (slow). Return as many matching |
5842 fonts as possible if MAXNAMES = -1. */ | 6294 fonts as possible if MAXNAMES = -1. */ |
5845 x_list_fonts (struct frame *f, | 6297 x_list_fonts (struct frame *f, |
5846 Lisp_Object pattern, | 6298 Lisp_Object pattern, |
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. */ |
5858 init_font_name_table (); | 6306 init_font_name_table (); |
5859 | 6307 |
5868 newlist = Fcdr_safe (newlist); | 6316 newlist = Fcdr_safe (newlist); |
5869 goto label_cached; | 6317 goto label_cached; |
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 | |
5892 UNGCPRO; | |
5893 | 6324 |
5894 if (dpyinfo) | 6325 if (dpyinfo) |
5895 { | 6326 { |
5896 XSETCDR (dpyinfo->name_list_element, | 6327 XSETCDR (dpyinfo->name_list_element, |
5897 Fcons (Fcons (key, newlist), | 6328 Fcons (Fcons (key, newlist), |
6048 | 6479 |
6049 if (is_fully_specified_xlfd (fontname)) | 6480 if (is_fully_specified_xlfd (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)) | 6485 |
6055 break; | 6486 matched_fonts = mac_do_list_fonts (fontname, 1); |
6056 | 6487 if (NILP (matched_fonts)) |
6057 if (i >= font_name_count) | 6488 return NULL; |
6058 return NULL; | 6489 name = SDATA (XCAR (matched_fonts)); |
6059 | |
6060 name = font_name_table[i]; | |
6061 } | 6490 } |
6062 | 6491 |
6063 GetPort (&port); /* save the current font number used */ | 6492 GetPort (&port); /* save the current font number used */ |
6064 #if TARGET_API_MAC_CARBON | 6493 #if TARGET_API_MAC_CARBON |
6065 old_fontnum = GetPortTextFont (port); | 6494 old_fontnum = GetPortTextFont (port); |
6177 int c; | 6606 int c; |
6178 | 6607 |
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 } |
6186 | 6616 |
6187 TextFont (old_fontnum); /* restore previous font number, size and face */ | 6617 TextFont (old_fontnum); /* restore previous font number, size and face */ |
7831 tracked_scroll_bar = NULL; | 8261 tracked_scroll_bar = NULL; |
7832 } | 8262 } |
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); |
7847 #else | 8295 #else |
7848 bufp->modifiers = mac_to_emacs_modifiers (er.modifiers); | 8296 bufp->modifiers = mac_to_emacs_modifiers (er.modifiers); |
8350 main_device_handle = LMGetMainDevice(); | 8798 main_device_handle = LMGetMainDevice(); |
8351 | 8799 |
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; |
8364 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID; | 8816 dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID; |
8365 dpyinfo->mouse_face_window = Qnil; | 8817 dpyinfo->mouse_face_window = Qnil; |
8695 last_mouse_press_frame = Qnil; | 9147 last_mouse_press_frame = Qnil; |
8696 | 9148 |
8697 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); | 9149 Qmac_ready_for_drag_n_drop = intern ("mac-ready-for-drag-n-drop"); |
8698 staticpro (&Qmac_ready_for_drag_n_drop); | 9150 staticpro (&Qmac_ready_for_drag_n_drop); |
8699 | 9151 |
9152 Qbig5 = intern ("big5"); | |
9153 staticpro (&Qbig5); | |
9154 | |
9155 Qcn_gb = intern ("cn-gb"); | |
9156 staticpro (&Qcn_gb); | |
9157 | |
9158 Qsjis = intern ("sjis"); | |
9159 staticpro (&Qsjis); | |
9160 | |
9161 Qeuc_kr = intern ("euc-kr"); | |
9162 staticpro (&Qeuc_kr); | |
9163 | |
8700 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, | 9164 DEFVAR_BOOL ("x-autoselect-window", &x_autoselect_window_p, |
8701 doc: /* *Non-nil means autoselect window with mouse pointer. */); | 9165 doc: /* *Non-nil means autoselect window with mouse pointer. */); |
8702 x_autoselect_window_p = 0; | 9166 x_autoselect_window_p = 0; |
8703 | 9167 |
8704 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, | 9168 DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, |