aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2008-04-23 08:56:20 +0000
committerYAMAMOTO Mitsuharu2008-04-23 08:56:20 +0000
commit415cf4bcd1677c6ce10b0fcbadd15b1e9e207561 (patch)
treea8ee3ae631410083f851fdcde8ee3b04e369285e /src
parente1adb1392e09cf5b57b93671e77ef0b583b0d44e (diff)
downloademacs-415cf4bcd1677c6ce10b0fcbadd15b1e9e207561.tar.gz
emacs-415cf4bcd1677c6ce10b0fcbadd15b1e9e207561.zip
(Vmac_ts_active_input_buf) [USE_MAC_TSM]: Add extern.
(fast_find_position, x_y_to_hpos_vpos, mac_ax_selected_text_range): (mac_ax_number_of_characters): Add externs. (mac_get_selected_range, mac_store_buffer_text_to_unicode_chars) [USE_MAC_TSM]: Likewise. (mac_handle_text_input_event) [MAC_OSX]: Handle kEventTextInputOffsetToPos for no active input area case. Handle kEventTextInputPosToOffset and kEventTextInputGetSelectedText. (mac_handle_document_access_event) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: New function. (install_application_handler) [MAC_OSX]: Register handlers for kEventTextInputPosToOffset and kEventTextInputGetSelectedText. (install_application_handler) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Register mac_handle_document_access_event.
Diffstat (limited to 'src')
-rw-r--r--src/mactoolbox.c379
1 files changed, 358 insertions, 21 deletions
diff --git a/src/mactoolbox.c b/src/mactoolbox.c
index 71abce23fe0..45a86135422 100644
--- a/src/mactoolbox.c
+++ b/src/mactoolbox.c
@@ -118,7 +118,7 @@ extern Lisp_Object Qhi_command;
118static TSMDocumentID tsm_document_id; 118static TSMDocumentID tsm_document_id;
119extern Lisp_Object Qtext_input; 119extern Lisp_Object Qtext_input;
120extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; 120extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event;
121extern Lisp_Object Vmac_ts_active_input_overlay; 121extern Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf;
122extern Lisp_Object Qbefore_string; 122extern Lisp_Object Qbefore_string;
123#endif 123#endif
124 124
@@ -134,6 +134,14 @@ extern OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID,
134 EventRef, UInt32, 134 EventRef, UInt32,
135 const EventParamName *, 135 const EventParamName *,
136 const EventParamType *)); 136 const EventParamType *));
137extern int fast_find_position P_ ((struct window *, int, int *, int *,
138 int *, int *, Lisp_Object));
139extern struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
140 int *, int *, int *, int *, int *));
141extern void mac_ax_selected_text_range P_ ((struct frame *, CFRange *));
142#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
143extern unsigned int mac_ax_number_of_characters P_ ((struct frame *));
144#endif
137 145
138#if USE_MAC_TSM 146#if USE_MAC_TSM
139extern OSStatus mac_restore_keyboard_input_source P_ ((void)); 147extern OSStatus mac_restore_keyboard_input_source P_ ((void));
@@ -374,6 +382,10 @@ mac_handle_mouse_event (next_handler, event, data)
374} 382}
375 383
376#if USE_MAC_TSM 384#if USE_MAC_TSM
385extern void mac_get_selected_range P_ ((struct window *, CFRange *));
386extern int mac_store_buffer_text_to_unicode_chars P_ ((struct buffer *,
387 int, int, UniChar *));
388
377static pascal OSStatus 389static pascal OSStatus
378mac_handle_text_input_event (next_handler, event, data) 390mac_handle_text_input_event (next_handler, event, data)
379 EventHandlerCallRef next_handler; 391 EventHandlerCallRef next_handler;
@@ -512,42 +524,268 @@ mac_handle_text_input_event (next_handler, event, data)
512 524
513 case kEventTextInputOffsetToPos: 525 case kEventTextInputOffsetToPos:
514 { 526 {
527 long byte_offset;
515 struct frame *f; 528 struct frame *f;
516 struct window *w; 529 struct window *w;
517 Point p; 530 Point p;
518 531
519 if (!OVERLAYP (Vmac_ts_active_input_overlay)) 532 err = GetEventParameter (event, kEventParamTextInputSendTextOffset,
533 typeLongInteger, NULL, sizeof (long), NULL,
534 &byte_offset);
535 if (err != noErr)
520 break; 536 break;
521 537
522 /* Strictly speaking, this is not always correct because 538 if (STRINGP (Vmac_ts_active_input_buf)
523 previous events may change some states about display. */ 539 && SBYTES (Vmac_ts_active_input_buf) != 0)
524 if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string))) 540 {
541 if (!OVERLAYP (Vmac_ts_active_input_overlay))
542 break;
543
544 /* Strictly speaking, this is not always correct because
545 previous events may change some states about display. */
546 if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string)))
547 {
548 /* Active input area is displayed around the current point. */
549 f = SELECTED_FRAME ();
550 w = XWINDOW (f->selected_window);
551 }
552 else if (WINDOWP (echo_area_window))
553 {
554 /* Active input area is displayed in the echo area. */
555 w = XWINDOW (echo_area_window);
556 f = WINDOW_XFRAME (w);
557 }
558 else
559 break;
560
561 p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x)
562 + WINDOW_LEFT_FRINGE_WIDTH (w)
563 + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
564 p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y)
565 + FONT_BASE (FRAME_FONT (f))
566 + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
567 }
568 else
525 { 569 {
526 /* Active input area is displayed around the current point. */ 570#ifndef MAC_OSX
527 f = SELECTED_FRAME (); 571 break;
572#else /* MAC_OSX */
573 CFRange sel_range;
574 int charpos;
575 int hpos, vpos, x, y;
576 struct glyph_row *row;
577 struct glyph *glyph;
578 XFontStruct *font;
579
580 f = mac_focus_frame (&one_mac_display_info);
528 w = XWINDOW (f->selected_window); 581 w = XWINDOW (f->selected_window);
582 mac_get_selected_range (w, &sel_range);
583 charpos = (BUF_BEGV (XBUFFER (w->buffer)) + sel_range.location
584 + byte_offset / (long) sizeof (UniChar));
585
586 if (!fast_find_position (w, charpos, &hpos, &vpos, &x, &y, Qnil))
587 {
588 result = errOffsetInvalid;
589 break;
590 }
591
592 row = MATRIX_ROW (w->current_matrix, vpos);
593 glyph = row->glyphs[TEXT_AREA] + hpos;
594 if (glyph->type != CHAR_GLYPH || glyph->glyph_not_available_p)
595 break;
596
597 p.h = (WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x)
598 + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
599 p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, y)
600 + row->visible_height
601 + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
602
603 font = FACE_FROM_ID (f, glyph->face_id)->font;
604 if (font)
605 {
606 Fixed point_size = Long2Fix (font->mac_fontsize);
607 short height = row->visible_height;
608 short ascent = row->ascent;
609
610 SetEventParameter (event,
611 kEventParamTextInputReplyPointSize,
612 typeFixed, sizeof (Fixed), &point_size);
613 SetEventParameter (event,
614 kEventParamTextInputReplyLineHeight,
615 typeShortInteger, sizeof (short), &height);
616 SetEventParameter (event,
617 kEventParamTextInputReplyLineAscent,
618 typeShortInteger, sizeof (short), &ascent);
619 if (font->mac_fontnum != -1)
620 {
621 OSStatus err1;
622 FMFont fm_font;
623 FMFontStyle style;
624
625 err1 = FMGetFontFromFontFamilyInstance (font->mac_fontnum,
626 font->mac_fontface,
627 &fm_font, &style);
628 if (err1 == noErr)
629 SetEventParameter (event, kEventParamTextInputReplyFMFont,
630 typeUInt32, sizeof (UInt32), &fm_font);
631 else
632 {
633 long qd_font = font->mac_fontnum;
634
635 SetEventParameter (event, kEventParamTextInputReplyFont,
636 typeLongInteger, sizeof (long),
637 &qd_font);
638 }
639 }
640 else if (font->mac_style)
641 {
642 OSStatus err1;
643 ATSUFontID font_id;
644
645 err1 = ATSUGetAttribute (font->mac_style, kATSUFontTag,
646 sizeof (ATSUFontID), &font_id,
647 NULL);
648 if (err1 == noErr)
649 SetEventParameter (event, kEventParamTextInputReplyFMFont,
650 typeUInt32, sizeof (UInt32), &font_id);
651 }
652 else
653 abort ();
654 }
655#endif /* MAC_OSX */
529 } 656 }
530 else if (WINDOWP (echo_area_window)) 657
658 err = SetEventParameter (event, kEventParamTextInputReplyPoint,
659 typeQDPoint, sizeof (Point), &p);
660 if (err == noErr)
661 result = noErr;
662 }
663 break;
664
665#ifdef MAC_OSX
666 case kEventTextInputPosToOffset:
667 {
668 Point point;
669 Boolean leading_edge_p = true;
670 struct frame *f;
671 int x, y;
672 Lisp_Object window;
673 enum window_part part;
674 long region_class = kTSMOutsideOfBody, byte_offset = 0;
675
676 err = GetEventParameter (event, kEventParamTextInputSendCurrentPoint,
677 typeQDPoint, NULL, sizeof (Point), NULL,
678 &point);
679 if (err != noErr)
680 break;
681
682 GetEventParameter (event, kEventParamTextInputReplyLeadingEdge,
683 typeBoolean, NULL, sizeof (Boolean), NULL,
684 &leading_edge_p);
685
686 f = mac_focus_frame (&one_mac_display_info);
687 x = point.h - (f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f));
688 y = point.v - (f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f));
689 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
690 if (WINDOWP (window) && EQ (window, f->selected_window))
531 { 691 {
532 /* Active input area is displayed in the echo area. */ 692 struct window *w;
533 w = XWINDOW (echo_area_window); 693 struct buffer *b;
534 f = WINDOW_XFRAME (w); 694
695 /* Convert to window-relative pixel coordinates. */
696 w = XWINDOW (window);
697 frame_to_window_pixel_xy (w, &x, &y);
698
699 /* Are we in a window whose display is up to date?
700 And verify the buffer's text has not changed. */
701 b = XBUFFER (w->buffer);
702 if (part == ON_TEXT
703 && EQ (w->window_end_valid, w->buffer)
704 && XINT (w->last_modified) == BUF_MODIFF (b)
705 && XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
706 {
707 int hpos, vpos, area;
708 struct glyph *glyph;
709
710 /* Find the glyph under X/Y. */
711 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area);
712
713 if (glyph != NULL && area == TEXT_AREA)
714 {
715 byte_offset = ((glyph->charpos - BUF_BEGV (b))
716 * sizeof (UniChar));
717 region_class = kTSMInsideOfBody;
718 }
719 }
535 } 720 }
536 else 721
722 err = SetEventParameter (event, kEventParamTextInputReplyRegionClass,
723 typeLongInteger, sizeof (long),
724 &region_class);
725 if (err == noErr)
726 err = SetEventParameter (event, kEventParamTextInputReplyTextOffset,
727 typeLongInteger, sizeof (long),
728 &byte_offset);
729 if (err == noErr)
730 result = noErr;
731 }
732 break;
733
734 case kEventTextInputGetSelectedText:
735 {
736 struct frame *f = mac_focus_frame (&one_mac_display_info);
737 struct window *w = XWINDOW (f->selected_window);
738 struct buffer *b = XBUFFER (w->buffer);
739 CFRange sel_range;
740 int start, end;
741 UniChar *characters, c;
742
743 if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
744 /* Don't try to get buffer contents as the gap might be
745 being altered. */
537 break; 746 break;
538 747
539 p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x) 748 mac_get_selected_range (w, &sel_range);
540 + WINDOW_LEFT_FRINGE_WIDTH (w) 749 if (sel_range.length == 0)
541 + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f)); 750 {
542 p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y) 751 Boolean leading_edge_p;
543 + FONT_BASE (FRAME_FONT (f)) 752
544 + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f)); 753 err = GetEventParameter (event,
545 err = SetEventParameter (event, kEventParamTextInputReplyPoint, 754 kEventParamTextInputReplyLeadingEdge,
546 typeQDPoint, sizeof (typeQDPoint), &p); 755 typeBoolean, NULL, sizeof (Boolean), NULL,
756 &leading_edge_p);
757 if (err != noErr)
758 break;
759
760 start = BUF_BEGV (b) + sel_range.location;
761 if (!leading_edge_p)
762 start--;
763 end = start + 1;
764 characters = &c;
765
766 if (start < BUF_BEGV (b) || end > BUF_ZV (b))
767 break;
768 }
769 else
770 {
771 start = BUF_BEGV (b) + sel_range.location;
772 end = start + sel_range.length;
773 characters = xmalloc (sel_range.length * sizeof (UniChar));
774 }
775
776 if (mac_store_buffer_text_to_unicode_chars (b, start, end, characters))
777 err = SetEventParameter (event, kEventParamTextInputReplyText,
778 typeUnicodeText,
779 sel_range.length * sizeof (UniChar),
780 characters);
781 if (characters != &c)
782 xfree (characters);
783
547 if (err == noErr) 784 if (err == noErr)
548 result = noErr; 785 result = noErr;
549 } 786 }
550 break; 787 break;
788#endif /* MAC_OSX */
551 789
552 default: 790 default:
553 abort (); 791 abort ();
@@ -559,6 +797,86 @@ mac_handle_text_input_event (next_handler, event, data)
559 names, types); 797 names, types);
560 return result; 798 return result;
561} 799}
800
801#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
802static pascal OSStatus
803mac_handle_document_access_event (next_handler, event, data)
804 EventHandlerCallRef next_handler;
805 EventRef event;
806 void *data;
807{
808 OSStatus err, result;
809 struct frame *f = mac_focus_frame (&one_mac_display_info);
810
811 result = CallNextEventHandler (next_handler, event);
812 if (result != eventNotHandledErr)
813 return result;
814
815 switch (GetEventKind (event))
816 {
817 case kEventTSMDocumentAccessGetLength:
818 {
819 CFIndex count = mac_ax_number_of_characters (f);
820
821 err = SetEventParameter (event, kEventParamTSMDocAccessCharacterCount,
822 typeCFIndex, sizeof (CFIndex), &count);
823 if (err == noErr)
824 result = noErr;
825 }
826 break;
827
828 case kEventTSMDocumentAccessGetSelectedRange:
829 {
830 CFRange sel_range;
831
832 mac_ax_selected_text_range (f, &sel_range);
833 err = SetEventParameter (event,
834 kEventParamTSMDocAccessReplyCharacterRange,
835 typeCFRange, sizeof (CFRange), &sel_range);
836 if (err == noErr)
837 result = noErr;
838 }
839 break;
840
841 case kEventTSMDocumentAccessGetCharacters:
842 {
843 struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer);
844 CFRange range;
845 Ptr characters;
846 int start, end;
847
848 if (poll_suppress_count == 0 && !NILP (Vinhibit_quit))
849 /* Don't try to get buffer contents as the gap might be
850 being altered. */
851 break;
852
853 err = GetEventParameter (event,
854 kEventParamTSMDocAccessSendCharacterRange,
855 typeCFRange, NULL, sizeof (CFRange), NULL,
856 &range);
857 if (err == noErr)
858 err = GetEventParameter (event,
859 kEventParamTSMDocAccessSendCharactersPtr,
860 typePtr, NULL, sizeof (Ptr), NULL,
861 &characters);
862 if (err != noErr)
863 break;
864
865 start = BUF_BEGV (b) + range.location;
866 end = start + range.length;
867 if (mac_store_buffer_text_to_unicode_chars (b, start, end,
868 (UniChar *) characters))
869 result = noErr;
870 }
871 break;
872
873 default:
874 abort ();
875 }
876
877 return result;
878}
879#endif
562#endif 880#endif
563 881
564OSStatus 882OSStatus
@@ -607,13 +925,32 @@ install_application_handler ()
607 static const EventTypeSpec specs[] = 925 static const EventTypeSpec specs[] =
608 {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea}, 926 {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea},
609 {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent}, 927 {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent},
610 {kEventClassTextInput, kEventTextInputOffsetToPos}}; 928 {kEventClassTextInput, kEventTextInputOffsetToPos},
929#ifdef MAC_OSX
930 {kEventClassTextInput, kEventTextInputPosToOffset},
931 {kEventClassTextInput, kEventTextInputGetSelectedText}
932#endif
933 };
611 934
612 err = InstallApplicationEventHandler (NewEventHandlerUPP 935 err = InstallApplicationEventHandler (NewEventHandlerUPP
613 (mac_handle_text_input_event), 936 (mac_handle_text_input_event),
614 GetEventTypeCount (specs), 937 GetEventTypeCount (specs),
615 specs, NULL, NULL); 938 specs, NULL, NULL);
616 } 939 }
940
941#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
942 if (err == noErr)
943 {
944 static const EventTypeSpec specs[] =
945 {{kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength},
946 {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange},
947 {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters}};
948
949 err = InstallApplicationEventHandler (mac_handle_document_access_event,
950 GetEventTypeCount (specs),
951 specs, NULL, NULL);
952 }
953#endif
617#endif 954#endif
618 955
619 if (err == noErr) 956 if (err == noErr)