From e1adb1392e09cf5b57b93671e77ef0b583b0d44e Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Wed, 23 Apr 2008 08:56:12 +0000 Subject: [PATCH 1/5] (Vmac_ts_active_input_buf) [USE_MAC_TSM]: New variable. (syms_of_macterm) [USE_MAC_TSM]: Defvar it. (Qmouse_drag_overlay) [MAC_OSX]: New variable. (syms_of_macterm) [MAC_OSX]: Intern and staticpro it. (mac_get_selected_range, mac_store_buffer_text_to_unicode_chars) (mac_ax_selected_text_range) [MAC_OSX]: New functions. (mac_ax_number_of_characters) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: Likewise. --- src/macterm.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 1 deletion(-) diff --git a/src/macterm.c b/src/macterm.c index 2a8142938a9..1efa2667f15 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -8154,7 +8154,7 @@ Lisp_Object Qtoolbar_switch_mode; #if USE_MAC_TSM Lisp_Object Qtext_input; Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; -Lisp_Object Vmac_ts_active_input_overlay; +Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf; static Lisp_Object Vmac_ts_script_language_on_focus; static Lisp_Object saved_ts_script_language_on_focus; static ScriptLanguageRecord saved_ts_language; @@ -8162,6 +8162,7 @@ static Component saved_ts_component; #endif #ifdef MAC_OSX Lisp_Object Qservice, Qpaste, Qperform; +Lisp_Object Qmouse_drag_overlay; #endif #endif /* TARGET_API_MAC_CARBON */ extern Lisp_Object Qundefined; @@ -8336,6 +8337,138 @@ mac_get_emulated_btn ( UInt32 modifiers ) return result; } +#ifdef MAC_OSX +void +mac_get_selected_range (w, range) + struct window *w; + CFRange *range; +{ + Lisp_Object overlay = find_symbol_value (Qmouse_drag_overlay); + struct buffer *b = XBUFFER (w->buffer); + int begv = BUF_BEGV (b), zv = BUF_ZV (b); + int start, end; + + if (OVERLAYP (overlay) + && EQ (Foverlay_buffer (overlay), w->buffer) + && (start = XINT (Foverlay_start (overlay)), + end = XINT (Foverlay_end (overlay)), + start != end)) + ; + else + { + if (w == XWINDOW (selected_window) && b == current_buffer) + start = PT; + else + start = marker_position (w->pointm); + + if (NILP (Vtransient_mark_mode) || NILP (b->mark_active)) + end = start; + else + { + int mark_pos = marker_position (b->mark); + + if (start <= mark_pos) + end = mark_pos; + else + { + end = start; + start = mark_pos; + } + } + } + + if (start != end) + { + if (start < begv) + start = begv; + else if (start > zv) + start = zv; + + if (end < begv) + end = begv; + else if (end > zv) + end = zv; + } + + range->location = start - begv; + range->length = end - start; +} + +/* Store the text of the buffer BUF from START to END as Unicode + characters in CHARACTERS. Return non-zero if successful. */ + +int +mac_store_buffer_text_to_unicode_chars (buf, start, end, characters) + struct buffer *buf; + int start, end; + UniChar *characters; +{ + int start_byte, end_byte, char_count, byte_count; + struct coding_system coding; + unsigned char *dst = (unsigned char *) characters; + + start_byte = buf_charpos_to_bytepos (buf, start); + end_byte = buf_charpos_to_bytepos (buf, end); + char_count = end - start; + byte_count = end_byte - start_byte; + + if (setup_coding_system ( +#ifdef WORDS_BIG_ENDIAN + intern ("utf-16be") +#else + intern ("utf-16le") +#endif + , &coding) < 0) + return 0; + + coding.src_multibyte = !NILP (buf->enable_multibyte_characters); + coding.dst_multibyte = 0; + coding.mode |= CODING_MODE_LAST_BLOCK; + coding.composing = COMPOSITION_DISABLED; + + if (BUF_GPT_BYTE (buf) <= start_byte || end_byte <= BUF_GPT_BYTE (buf)) + encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst, + byte_count, char_count * sizeof (UniChar)); + else + { + int first_byte_count = BUF_GPT_BYTE (buf) - start_byte; + + encode_coding (&coding, BUF_BYTE_ADDRESS (buf, start_byte), dst, + first_byte_count, char_count * sizeof (UniChar)); + if (coding.result == CODING_FINISH_NORMAL) + encode_coding (&coding, + BUF_BYTE_ADDRESS (buf, start_byte + first_byte_count), + dst + coding.produced, + byte_count - first_byte_count, + char_count * sizeof (UniChar) - coding.produced); + } + + if (coding.result != CODING_FINISH_NORMAL) + return 0; + + return 1; +} + +void +mac_ax_selected_text_range (f, range) + struct frame *f; + CFRange *range; +{ + mac_get_selected_range (XWINDOW (f->selected_window), range); +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 +unsigned int +mac_ax_number_of_characters (f) + struct frame *f; +{ + struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer); + + return BUF_ZV (b) - BUF_BEGV (b); +} +#endif +#endif + #if USE_MAC_TSM OSStatus mac_restore_keyboard_input_source () @@ -9377,6 +9510,9 @@ syms_of_macterm () Qservice = intern ("service"); staticpro (&Qservice); Qpaste = intern ("paste"); staticpro (&Qpaste); Qperform = intern ("perform"); staticpro (&Qperform); + + Qmouse_drag_overlay = intern ("mouse-drag-overlay"); + staticpro (&Qmouse_drag_overlay); #endif #if USE_MAC_TSM Qtext_input = intern ("text-input"); staticpro (&Qtext_input); @@ -9537,6 +9673,11 @@ CODING_SYSTEM is a coding system corresponding to TEXT-ENCODING. */); doc: /* Overlay used to display Mac TSM active input area. */); Vmac_ts_active_input_overlay = Qnil; + DEFVAR_LISP ("mac-ts-active-input-buf", &Vmac_ts_active_input_buf, + doc: /* Byte sequence of the current Mac TSM active input area. */); + /* `empty_string' is not ready yet on Mac OS Classic. */ + Vmac_ts_active_input_buf = build_string (""); + DEFVAR_LISP ("mac-ts-script-language-on-focus", &Vmac_ts_script_language_on_focus, doc: /* *How to change Mac TSM script/language when a frame gets focus. If the value is t, the input script and language are restored to those From 415cf4bcd1677c6ce10b0fcbadd15b1e9e207561 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Wed, 23 Apr 2008 08:56:20 +0000 Subject: [PATCH 2/5] (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. --- src/mactoolbox.c | 383 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 360 insertions(+), 23 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; static TSMDocumentID tsm_document_id; extern Lisp_Object Qtext_input; extern Lisp_Object Qupdate_active_input_area, Qunicode_for_key_event; -extern Lisp_Object Vmac_ts_active_input_overlay; +extern Lisp_Object Vmac_ts_active_input_overlay, Vmac_ts_active_input_buf; extern Lisp_Object Qbefore_string; #endif @@ -134,6 +134,14 @@ extern OSStatus mac_store_event_ref_as_apple_event P_ ((AEEventClass, AEEventID, EventRef, UInt32, const EventParamName *, const EventParamType *)); +extern int fast_find_position P_ ((struct window *, int, int *, int *, + int *, int *, Lisp_Object)); +extern struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, + int *, int *, int *, int *, int *)); +extern void mac_ax_selected_text_range P_ ((struct frame *, CFRange *)); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 +extern unsigned int mac_ax_number_of_characters P_ ((struct frame *)); +#endif #if USE_MAC_TSM extern OSStatus mac_restore_keyboard_input_source P_ ((void)); @@ -374,6 +382,10 @@ mac_handle_mouse_event (next_handler, event, data) } #if USE_MAC_TSM +extern void mac_get_selected_range P_ ((struct window *, CFRange *)); +extern int mac_store_buffer_text_to_unicode_chars P_ ((struct buffer *, + int, int, UniChar *)); + static pascal OSStatus mac_handle_text_input_event (next_handler, event, data) EventHandlerCallRef next_handler; @@ -512,43 +524,269 @@ mac_handle_text_input_event (next_handler, event, data) case kEventTextInputOffsetToPos: { + long byte_offset; struct frame *f; struct window *w; Point p; - if (!OVERLAYP (Vmac_ts_active_input_overlay)) + err = GetEventParameter (event, kEventParamTextInputSendTextOffset, + typeLongInteger, NULL, sizeof (long), NULL, + &byte_offset); + if (err != noErr) break; - /* Strictly speaking, this is not always correct because - previous events may change some states about display. */ - if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string))) + if (STRINGP (Vmac_ts_active_input_buf) + && SBYTES (Vmac_ts_active_input_buf) != 0) { - /* Active input area is displayed around the current point. */ - f = SELECTED_FRAME (); - w = XWINDOW (f->selected_window); - } - else if (WINDOWP (echo_area_window)) - { - /* Active input area is displayed in the echo area. */ - w = XWINDOW (echo_area_window); - f = WINDOW_XFRAME (w); + if (!OVERLAYP (Vmac_ts_active_input_overlay)) + break; + + /* Strictly speaking, this is not always correct because + previous events may change some states about display. */ + if (!NILP (Foverlay_get (Vmac_ts_active_input_overlay, Qbefore_string))) + { + /* Active input area is displayed around the current point. */ + f = SELECTED_FRAME (); + w = XWINDOW (f->selected_window); + } + else if (WINDOWP (echo_area_window)) + { + /* Active input area is displayed in the echo area. */ + w = XWINDOW (echo_area_window); + f = WINDOW_XFRAME (w); + } + else + break; + + p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x) + + WINDOW_LEFT_FRINGE_WIDTH (w) + + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f)); + p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y) + + FONT_BASE (FRAME_FONT (f)) + + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f)); } else - break; + { +#ifndef MAC_OSX + break; +#else /* MAC_OSX */ + CFRange sel_range; + int charpos; + int hpos, vpos, x, y; + struct glyph_row *row; + struct glyph *glyph; + XFontStruct *font; + + f = mac_focus_frame (&one_mac_display_info); + w = XWINDOW (f->selected_window); + mac_get_selected_range (w, &sel_range); + charpos = (BUF_BEGV (XBUFFER (w->buffer)) + sel_range.location + + byte_offset / (long) sizeof (UniChar)); + + if (!fast_find_position (w, charpos, &hpos, &vpos, &x, &y, Qnil)) + { + result = errOffsetInvalid; + break; + } + + row = MATRIX_ROW (w->current_matrix, vpos); + glyph = row->glyphs[TEXT_AREA] + hpos; + if (glyph->type != CHAR_GLYPH || glyph->glyph_not_available_p) + break; + + p.h = (WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x) + + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f)); + p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, y) + + row->visible_height + + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f)); + + font = FACE_FROM_ID (f, glyph->face_id)->font; + if (font) + { + Fixed point_size = Long2Fix (font->mac_fontsize); + short height = row->visible_height; + short ascent = row->ascent; + + SetEventParameter (event, + kEventParamTextInputReplyPointSize, + typeFixed, sizeof (Fixed), &point_size); + SetEventParameter (event, + kEventParamTextInputReplyLineHeight, + typeShortInteger, sizeof (short), &height); + SetEventParameter (event, + kEventParamTextInputReplyLineAscent, + typeShortInteger, sizeof (short), &ascent); + if (font->mac_fontnum != -1) + { + OSStatus err1; + FMFont fm_font; + FMFontStyle style; + + err1 = FMGetFontFromFontFamilyInstance (font->mac_fontnum, + font->mac_fontface, + &fm_font, &style); + if (err1 == noErr) + SetEventParameter (event, kEventParamTextInputReplyFMFont, + typeUInt32, sizeof (UInt32), &fm_font); + else + { + long qd_font = font->mac_fontnum; + + SetEventParameter (event, kEventParamTextInputReplyFont, + typeLongInteger, sizeof (long), + &qd_font); + } + } + else if (font->mac_style) + { + OSStatus err1; + ATSUFontID font_id; + + err1 = ATSUGetAttribute (font->mac_style, kATSUFontTag, + sizeof (ATSUFontID), &font_id, + NULL); + if (err1 == noErr) + SetEventParameter (event, kEventParamTextInputReplyFMFont, + typeUInt32, sizeof (UInt32), &font_id); + } + else + abort (); + } +#endif /* MAC_OSX */ + } - p.h = (WINDOW_TO_FRAME_PIXEL_X (w, w->cursor.x) - + WINDOW_LEFT_FRINGE_WIDTH (w) - + f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f)); - p.v = (WINDOW_TO_FRAME_PIXEL_Y (w, w->cursor.y) - + FONT_BASE (FRAME_FONT (f)) - + f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f)); err = SetEventParameter (event, kEventParamTextInputReplyPoint, - typeQDPoint, sizeof (typeQDPoint), &p); + typeQDPoint, sizeof (Point), &p); if (err == noErr) result = noErr; } break; +#ifdef MAC_OSX + case kEventTextInputPosToOffset: + { + Point point; + Boolean leading_edge_p = true; + struct frame *f; + int x, y; + Lisp_Object window; + enum window_part part; + long region_class = kTSMOutsideOfBody, byte_offset = 0; + + err = GetEventParameter (event, kEventParamTextInputSendCurrentPoint, + typeQDPoint, NULL, sizeof (Point), NULL, + &point); + if (err != noErr) + break; + + GetEventParameter (event, kEventParamTextInputReplyLeadingEdge, + typeBoolean, NULL, sizeof (Boolean), NULL, + &leading_edge_p); + + f = mac_focus_frame (&one_mac_display_info); + x = point.h - (f->left_pos + FRAME_OUTER_TO_INNER_DIFF_X (f)); + y = point.v - (f->top_pos + FRAME_OUTER_TO_INNER_DIFF_Y (f)); + window = window_from_coordinates (f, x, y, &part, 0, 0, 1); + if (WINDOWP (window) && EQ (window, f->selected_window)) + { + struct window *w; + struct buffer *b; + + /* Convert to window-relative pixel coordinates. */ + w = XWINDOW (window); + frame_to_window_pixel_xy (w, &x, &y); + + /* Are we in a window whose display is up to date? + And verify the buffer's text has not changed. */ + b = XBUFFER (w->buffer); + if (part == ON_TEXT + && EQ (w->window_end_valid, w->buffer) + && XINT (w->last_modified) == BUF_MODIFF (b) + && XINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) + { + int hpos, vpos, area; + struct glyph *glyph; + + /* Find the glyph under X/Y. */ + glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area); + + if (glyph != NULL && area == TEXT_AREA) + { + byte_offset = ((glyph->charpos - BUF_BEGV (b)) + * sizeof (UniChar)); + region_class = kTSMInsideOfBody; + } + } + } + + err = SetEventParameter (event, kEventParamTextInputReplyRegionClass, + typeLongInteger, sizeof (long), + ®ion_class); + if (err == noErr) + err = SetEventParameter (event, kEventParamTextInputReplyTextOffset, + typeLongInteger, sizeof (long), + &byte_offset); + if (err == noErr) + result = noErr; + } + break; + + case kEventTextInputGetSelectedText: + { + struct frame *f = mac_focus_frame (&one_mac_display_info); + struct window *w = XWINDOW (f->selected_window); + struct buffer *b = XBUFFER (w->buffer); + CFRange sel_range; + int start, end; + UniChar *characters, c; + + if (poll_suppress_count == 0 && !NILP (Vinhibit_quit)) + /* Don't try to get buffer contents as the gap might be + being altered. */ + break; + + mac_get_selected_range (w, &sel_range); + if (sel_range.length == 0) + { + Boolean leading_edge_p; + + err = GetEventParameter (event, + kEventParamTextInputReplyLeadingEdge, + typeBoolean, NULL, sizeof (Boolean), NULL, + &leading_edge_p); + if (err != noErr) + break; + + start = BUF_BEGV (b) + sel_range.location; + if (!leading_edge_p) + start--; + end = start + 1; + characters = &c; + + if (start < BUF_BEGV (b) || end > BUF_ZV (b)) + break; + } + else + { + start = BUF_BEGV (b) + sel_range.location; + end = start + sel_range.length; + characters = xmalloc (sel_range.length * sizeof (UniChar)); + } + + if (mac_store_buffer_text_to_unicode_chars (b, start, end, characters)) + err = SetEventParameter (event, kEventParamTextInputReplyText, + typeUnicodeText, + sel_range.length * sizeof (UniChar), + characters); + if (characters != &c) + xfree (characters); + + if (err == noErr) + result = noErr; + } + break; +#endif /* MAC_OSX */ + default: abort (); } @@ -559,6 +797,86 @@ mac_handle_text_input_event (next_handler, event, data) names, types); return result; } + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 +static pascal OSStatus +mac_handle_document_access_event (next_handler, event, data) + EventHandlerCallRef next_handler; + EventRef event; + void *data; +{ + OSStatus err, result; + struct frame *f = mac_focus_frame (&one_mac_display_info); + + result = CallNextEventHandler (next_handler, event); + if (result != eventNotHandledErr) + return result; + + switch (GetEventKind (event)) + { + case kEventTSMDocumentAccessGetLength: + { + CFIndex count = mac_ax_number_of_characters (f); + + err = SetEventParameter (event, kEventParamTSMDocAccessCharacterCount, + typeCFIndex, sizeof (CFIndex), &count); + if (err == noErr) + result = noErr; + } + break; + + case kEventTSMDocumentAccessGetSelectedRange: + { + CFRange sel_range; + + mac_ax_selected_text_range (f, &sel_range); + err = SetEventParameter (event, + kEventParamTSMDocAccessReplyCharacterRange, + typeCFRange, sizeof (CFRange), &sel_range); + if (err == noErr) + result = noErr; + } + break; + + case kEventTSMDocumentAccessGetCharacters: + { + struct buffer *b = XBUFFER (XWINDOW (f->selected_window)->buffer); + CFRange range; + Ptr characters; + int start, end; + + if (poll_suppress_count == 0 && !NILP (Vinhibit_quit)) + /* Don't try to get buffer contents as the gap might be + being altered. */ + break; + + err = GetEventParameter (event, + kEventParamTSMDocAccessSendCharacterRange, + typeCFRange, NULL, sizeof (CFRange), NULL, + &range); + if (err == noErr) + err = GetEventParameter (event, + kEventParamTSMDocAccessSendCharactersPtr, + typePtr, NULL, sizeof (Ptr), NULL, + &characters); + if (err != noErr) + break; + + start = BUF_BEGV (b) + range.location; + end = start + range.length; + if (mac_store_buffer_text_to_unicode_chars (b, start, end, + (UniChar *) characters)) + result = noErr; + } + break; + + default: + abort (); + } + + return result; +} +#endif #endif OSStatus @@ -607,13 +925,32 @@ install_application_handler () static const EventTypeSpec specs[] = {{kEventClassTextInput, kEventTextInputUpdateActiveInputArea}, {kEventClassTextInput, kEventTextInputUnicodeForKeyEvent}, - {kEventClassTextInput, kEventTextInputOffsetToPos}}; + {kEventClassTextInput, kEventTextInputOffsetToPos}, +#ifdef MAC_OSX + {kEventClassTextInput, kEventTextInputPosToOffset}, + {kEventClassTextInput, kEventTextInputGetSelectedText} +#endif + }; err = InstallApplicationEventHandler (NewEventHandlerUPP (mac_handle_text_input_event), GetEventTypeCount (specs), specs, NULL, NULL); } + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 + if (err == noErr) + { + static const EventTypeSpec specs[] = + {{kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetLength}, + {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetSelectedRange}, + {kEventClassTSMDocumentAccess, kEventTSMDocumentAccessGetCharacters}}; + + err = InstallApplicationEventHandler (mac_handle_document_access_event, + GetEventTypeCount (specs), + specs, NULL, NULL); + } +#endif #endif if (err == noErr) From 1289aeb85cb7c330283fa3049f7f11f092055004 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Wed, 23 Apr 2008 08:56:42 +0000 Subject: [PATCH 3/5] (x_y_to_hpos_vpos, fast_find_position) [HAVE_CARBON]: Make functions non-static. --- src/ChangeLog | 29 +++++++++++++++++++++++++++++ src/xdisp.c | 10 ++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index aaa49be146d..456d03c07b3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,32 @@ +2008-04-23 YAMAMOTO Mitsuharu + + * macterm.c (Vmac_ts_active_input_buf) [USE_MAC_TSM]: New variable. + (syms_of_macterm) [USE_MAC_TSM]: Defvar it. + (Qmouse_drag_overlay) [MAC_OSX]: New variable. + (syms_of_macterm) [MAC_OSX]: Intern and staticpro it. + (mac_get_selected_range, mac_store_buffer_text_to_unicode_chars) + (mac_ax_selected_text_range) [MAC_OSX]: New functions. + (mac_ax_number_of_characters) [MAC_OS_X_VERSION_MAX_ALLOWED >= 1030]: + Likewise. + + * mactoolbox.c (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. + + * xdisp.c (x_y_to_hpos_vpos, fast_find_position) [HAVE_CARBON]: + Make functions non-static. + 2008-04-19 YAMAMOTO Mitsuharu * mac.c (create_apple_event) [TARGET_API_MAC_CARBON]: diff --git a/src/xdisp.c b/src/xdisp.c index f20aaedd2f7..897dd440f15 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1700,7 +1700,10 @@ glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y) text, or we can't tell because W's current matrix is not up to date. */ -static struct glyph * +#ifndef HAVE_CARBON +static +#endif +struct glyph * x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area) struct window *w; int x, y; @@ -22079,7 +22082,10 @@ cursor_in_mouse_face_p (w) in 20.x as well, and I think it's too risky to install so near the release of 21.1. 2001-09-25 gerd. */ -static int +#ifndef HAVE_CARBON +static +#endif +int fast_find_position (w, charpos, hpos, vpos, x, y, stop) struct window *w; int charpos; From 9f0d1d6f744a15997572318cffe2bfb65322137c Mon Sep 17 00:00:00 2001 From: YAMAMOTO Mitsuharu Date: Wed, 23 Apr 2008 08:57:18 +0000 Subject: [PATCH 4/5] (mac-ts-active-input-buf): Move defvar to macterm.c. --- lisp/ChangeLog | 4 ++++ lisp/term/mac-win.el | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 20f04983fbd..e2d01ec3ba0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2008-04-23 YAMAMOTO Mitsuharu + + * term/mac-win.el (mac-ts-active-input-buf): Move defvar to macterm.c. + 2008-04-12 Nick Roberts * progmodes/gdb-ui.el (gdb-init-buffer): New function. diff --git a/lisp/term/mac-win.el b/lisp/term/mac-win.el index eaa0e35fa5b..e63ffdf486c 100644 --- a/lisp/term/mac-win.el +++ b/lisp/term/mac-win.el @@ -83,6 +83,7 @@ (defvar mac-apple-event-map) (defvar mac-font-panel-mode) (defvar mac-ts-active-input-overlay) +(defvar mac-ts-active-input-buf) (defvar x-invocation-args) (defvar x-command-line-resources nil) @@ -1859,8 +1860,6 @@ With numeric ARG, display the font panel if and only if ARG is positive." ) ;; (fboundp 'mac-set-font-panel-visible-p) ;;; Text Services -(defvar mac-ts-active-input-buf "" - "Byte sequence of the current Mac TSM active input area.") (defvar mac-ts-update-active-input-area-seqno 0 "Number of processed update-active-input-area events.") (setq mac-ts-active-input-overlay (make-overlay 0 0)) From 285935fe5dbd6c60096abe4991ddac12d81a3ab6 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 24 Apr 2008 04:51:03 +0000 Subject: [PATCH 5/5] Merge from gnus--rel--5.10 Revision: emacs@sv.gnu.org/emacs--rel--22--patch-257 --- etc/GNUS-NEWS | 10 ++++++-- lisp/gnus/ChangeLog | 35 +++++++++++++++++++++++++ lisp/gnus/gnus-diary.el | 8 ++---- lisp/gnus/gnus-sum.el | 27 +++++++++++++++++-- lisp/gnus/message.el | 57 +++++++++++++++++++++++++++++++---------- man/ChangeLog | 33 ++++++++++++++++++++++++ man/gnus-faq.texi | 21 +++++++++------ man/gnus.texi | 22 ++++++++++------ man/message.texi | 7 +++++ 9 files changed, 180 insertions(+), 40 deletions(-) diff --git a/etc/GNUS-NEWS b/etc/GNUS-NEWS index 89df6ab2df8..6631897523f 100644 --- a/etc/GNUS-NEWS +++ b/etc/GNUS-NEWS @@ -26,6 +26,8 @@ installer issues a warning if other Gnus installations which will shadow the latest one are detected. You can then remove those shadows manually or remove them using `make remove-installed-shadows'. +** The installation directory name is allowed to have spaces and/or tabs. + ** New `make.bat' for compiling and installing Gnus under MS Windows Use `make.bat' if you want to install Gnus under MS Windows, the first @@ -436,6 +438,10 @@ The variable `gnus-use-idna' controls this. `mml-dnd-protocol-alist' and `mml-dnd-attach-options'. *Note MIME: (message)MIME. +** `auto-fill-mode' is enabled by default in Message mode. See +`message-fill-column'. *Note Message Headers: (message)Various Message +Variables. (New in Gnus 5.10.12 / Emacs 22.3) + * Changes in back ends @@ -473,8 +479,8 @@ renamed to "Gnus". stuff, like signing and encryption (*note Security: (message)Security.). ** The tool bars have been updated to use GNOME icons in Group, Summary and -Message mode. You can also customize the tool bars. This is a new -feature in Gnus 5.10.9. (Only for Emacs, not in XEmacs.) +Message mode. You can also customize the tool bars: `M-x customize-apropos +RET -tool-bar$' should get you started. (Only for Emacs, not in XEmacs.) ** The tool bar icons are now (de)activated correctly in the group buffer, see the variable `gnus-group-update-tool-bar'. Its default value diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 4207753cb15..f0ba8af760e 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,38 @@ +2008-04-13 Reiner Steib + + [Backport GNKSA related changes from the Gnus trunk.] + + * message.el (message-fill-column): New variable. + (message-mode): Use it. + + * message.el (message-signature-separator): Change default. Improve + custom type. + (message-cite-function): Change default to + message-cite-original-without-signature. + + * gnus-sum.el (gnus-summary-make-menu-bar): Add message-cite-function + toggle. + + * message.el (message-check-news-body-syntax): Fix signature check. + (message-setup-1): Mark buffer as unmodified _after_ running + message-setup-hook and handling message-alternative-emails. + (message-shorten-references): Be more strict when building list of + valid references to comply with GNKSA. + +2008-04-12 Adrian Aichner + + * gnus-sum.el (gnus-summary-goto-subject): Typo fix. + +2008-04-12 Reiner Steib + + * gnus-diary.el (gnus-article-edit-mode-map, message-mode-map): Remove + binding for `gnus-diary-version'. Bind `gnus-diary-check-message' to + `C-c C-f d'. + +2008-03-29 Sven Joachim + + * gnus-sum.el (gnus-summary-make-menu-bar): Add missing dots. + 2008-03-24 Reiner Steib * message.el (message-cite-original-without-signature): Mention diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el index 30c92d7cd10..39fa3823174 100644 --- a/lisp/gnus/gnus-diary.el +++ b/lisp/gnus/gnus-diary.el @@ -390,8 +390,8 @@ If ARG (or prefix) is non-nil, force prompting for all fields." (add-hook 'nndiary-request-accept-article-hooks (lambda () (gnus-diary-check-message nil))) -(define-key message-mode-map "\C-cDc" 'gnus-diary-check-message) -(define-key gnus-article-edit-mode-map "\C-cDc" 'gnus-diary-check-message) +(define-key message-mode-map "\C-c\C-fd" 'gnus-diary-check-message) +(define-key gnus-article-edit-mode-map "\C-c\C-fd" 'gnus-diary-check-message) ;; The end ================================================================== @@ -401,10 +401,6 @@ If ARG (or prefix) is non-nil, force prompting for all fields." (interactive) (message "NNDiary version %s" nndiary-version)) -(define-key message-mode-map "\C-cDv" 'gnus-diary-version) -(define-key gnus-article-edit-mode-map "\C-cDv" 'gnus-diary-version) - - (provide 'gnus-diary) ;;; arch-tag: 98467e70-337e-4ddc-b92d-45d403ff1b4b diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index 626ce26d2fd..a60211ba8b7 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el @@ -2134,7 +2134,7 @@ increase the score of each group you read." ["Set mark below..." gnus-score-set-mark-below t] ["Set expunge below..." gnus-score-set-expunge-below t] ["Edit current score file" gnus-score-edit-current-scores t] - ["Edit score file" gnus-score-edit-file t] + ["Edit score file..." gnus-score-edit-file t] ["Trace score" gnus-score-find-trace t] ["Find words" gnus-score-find-favourite-words t] ["Rescore buffer" gnus-summary-rescore t] @@ -2408,6 +2408,29 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs)))) ["Followup via news" gnus-summary-followup-to-mail t] ["Followup via news and yank" gnus-summary-followup-to-mail-with-original t] + ["Strip signature on reply" + (lambda () + (interactive) + (if (not (memq message-cite-function + '(message-cite-original-without-signature + message-cite-original))) + ;; Stupid workaround for XEmacs not honoring :visible. + (message "Can't toggle this value of `message-cite-function'") + (setq message-cite-function + (if (eq message-cite-function + 'message-cite-original-without-signature) + 'message-cite-original + 'message-cite-original-without-signature)))) + ;; XEmacs barfs on :visible. + ,@(if (featurep 'xemacs) nil + '(:visible (memq message-cite-function + '(message-cite-original-without-signature + message-cite-original)))) + :style toggle + :selected (eq message-cite-function + 'message-cite-original-without-signature) + ,@(if (featurep 'xemacs) nil + '(:help "Strip signature from cited article when replying."))] ;;("Draft" ;;["Send" gnus-summary-send-draft t] ;;["Send bounced" gnus-resend-bounced-mail t]) @@ -7249,7 +7272,7 @@ If optional argument UNREAD is non-nil, only unread article is selected." (gnus-summary-position-point)) (defun gnus-summary-goto-subject (article &optional force silent) - "Go the subject line of ARTICLE. + "Go to the subject line of ARTICLE. If FORCE, also allow jumping to articles not currently shown." (interactive "nArticle number: ") (unless (numberp article) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 5b998f947a7..fa25bb1f20b 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -411,10 +411,17 @@ for `message-cross-post-insert-note'." ;;; End of variables adopted from `message-utils.el'. -;;;###autoload -(defcustom message-signature-separator "^-- *$" - "Regexp matching the signature separator." - :type 'regexp +(defcustom message-signature-separator "^-- $" + "Regexp matching the signature separator. +This variable is used to strip off the signature from quoted text +when `message-cite-function' is +`message-cite-original-without-signature'. Most useful values +are \"^-- $\" (strict) and \"^-- *$\" (loose; allow missing +whitespace)." + :type '(choice (const :tag "strict" "^-- $") + (const :tag "loose" "^-- *$") + regexp) + :version "22.3" ;; Gnus 5.10.12 (changed default) :link '(custom-manual "(message)Various Message Variables") :group 'message-various) @@ -821,6 +828,15 @@ will not have a visible effect for those headers." (const :tag "All" t) (repeat (sexp :tag "Header")))) +(defcustom message-fill-column 72 + "Column beyond which automatic line-wrapping should happen. +Local value for message buffers. If non-nil, also turn on +auto-fill in message buffers." + :group 'message-various + ;; :link '(custom-manual "(message)Message Headers") + :type '(choice (const :tag "Don't turn on auto fill" nil) + (integer))) + (defcustom message-setup-hook nil "Normal hook, run each time a new outgoing message is initialized. The function `message-setup' runs this hook." @@ -904,7 +920,7 @@ Used by `message-yank-original' via `message-yank-cite'." :type 'integer) ;;;###autoload -(defcustom message-cite-function 'message-cite-original +(defcustom message-cite-function 'message-cite-original-without-signature "*Function for citing an original message. Predefined functions include `message-cite-original' and `message-cite-original-without-signature'. @@ -914,6 +930,7 @@ Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil." (function-item sc-cite-original) (function :tag "Other")) :link '(custom-manual "(message)Insertion Variables") + :version "22.3" ;; Gnus 5.10.12 (changed default) :group 'message-insertion) ;;;###autoload @@ -2632,6 +2649,9 @@ M-RET `message-newline-and-reformat' (break the line and reformat)." (set (make-local-variable 'message-checksum) nil) (set (make-local-variable 'message-mime-part) 0) (message-setup-fill-variables) + (when message-fill-column + (setq fill-column message-fill-column) + (turn-on-auto-fill)) ;; Allow using comment commands to add/remove quoting. ;; (set (make-local-variable 'comment-start) message-yank-prefix) (when message-yank-prefix @@ -4625,12 +4645,16 @@ Otherwise, generate and save a value for `canlock-password' first." ;; Check the length of the signature. (message-check 'signature (goto-char (point-max)) - (if (> (count-lines (point) (point-max)) 5) - (y-or-n-p - (format - "Your .sig is %d lines; it should be max 4. Really post? " - (1- (count-lines (point) (point-max))))) - t)) + (if (not (re-search-backward message-signature-separator nil t)) + t + (if (>= (count-lines (1+ (point-at-eol)) (point-max)) 5) + (if (message-gnksa-enable-p 'signature) + (y-or-n-p + (format "Signature is excessively long (%d lines). Really post? " + (count-lines (1+ (point-at-eol)) (point-max)))) + (message "Denied posting -- Excessive signature.") + nil) + t))) ;; Ensure that text follows last quoted portion. (message-check 'quoting-style (goto-char (point-max)) @@ -5424,8 +5448,10 @@ than 988 characters long, and if they are not, trim them until they are." (with-temp-buffer (insert references) (goto-char (point-min)) - ;; Cons a list of valid references. - (while (re-search-forward "<[^>]+>" nil t) + ;; Cons a list of valid references. GNKSA says we must not include MIDs + ;; with whitespace or missing brackets (7.a "Does not propagate broken + ;; Message-IDs in original References"). + (while (re-search-forward "<[^ <]+@[^ <]+>" nil t) (push (match-string 0) refs)) (setq refs (nreverse refs) count (length refs))) @@ -5761,8 +5787,9 @@ are not included." (save-restriction (message-narrow-to-headers) (run-hooks 'message-header-setup-hook)) - (set-buffer-modified-p nil) (setq buffer-undo-list nil) + ;; Gnus posting styles are applied via buffer-local `message-setup-hook' + ;; values. (run-hooks 'message-setup-hook) ;; Do this last to give it precedence over posting styles, etc. (when (message-mail-p) @@ -5771,6 +5798,8 @@ are not included." (if message-alternative-emails (message-use-alternative-email-as-from)))) (message-position-point) + ;; Allow correct handling of `message-checksum' in `message-yank-original': + (set-buffer-modified-p nil) (undo-boundary)) (defun message-set-auto-save-file-name () diff --git a/man/ChangeLog b/man/ChangeLog index 6d8af5334b3..ba08ada4bc2 100644 --- a/man/ChangeLog +++ b/man/ChangeLog @@ -1,8 +1,41 @@ +2008-04-13 Reiner Steib + + * gnus-faq.texi ([5.2]): Adjust for message-fill-column. + + * gnus.texi (Oort Gnus): Add message-fill-column. + + * message.texi (Various Message Variables): Add message-fill-column. + +2008-04-12 Adrian Aichner + + * gnus.texi (Mail Source Specifiers): Typo fix. + +2008-04-12 Reiner Steib + + * gnus.texi (Diary Headers Generation): Update key binding for + `gnus-diary-check-message'. + +2008-04-11 Reiner Steib + + * gnus.texi, gnus-faq.texi, message.texi: Bump version to 5.10.11. + 2008-04-11 Mirko Vukovic (tiny change) * maintaining.texi (Maintaining): * emacs.texi (Top): Typo. +2008-04-10 Reiner Steib + + * gnus.texi, gnus-faq.texi, message.texi: Gnus v5.10.10 is released. + +2008-04-10 Reiner Steib + + * gnus.texi (Emacsen): Give recommendations for Emacs 22 and Emacs 23. + +2008-04-09 Reiner Steib + + * gnus.texi (Oort Gnus): Mention customizing of tool bars. + 2008-04-09 Michael Albinus * trampver.texi: Update release number. diff --git a/man/gnus-faq.texi b/man/gnus-faq.texi index 3ee0141585b..fd5106fac4b 100644 --- a/man/gnus-faq.texi +++ b/man/gnus-faq.texi @@ -129,7 +129,7 @@ What is the latest version of Gnus? Jingle please: Gnus 5.10 is released, get it while it's hot! As well as the step in version number is rather small, Gnus 5.10 has tons of new features which you -shouldn't miss. The current release (5.10.9) should be at +shouldn't miss. The current release (5.10.11) should be at least as stable as the latest release of the 5.8 series. @node [1.2] @@ -1287,18 +1287,23 @@ How to enable automatic word-wrap when composing messages? @subsubheading Answer -Say +Starting from Gnus 5.10.12, automatic word-wrap is already enabled by +default, see the variable message-fill-column. + +For other versions of Gnus, say @example -(add-hook 'message-mode-hook - (lambda () - (setq fill-column 72) - (turn-on-auto-fill))) +(unless (boundp 'message-fill-column) + (add-hook 'message-mode-hook + (lambda () + (setq fill-column 72) + (turn-on-auto-fill)))) @end example @noindent -in ~/.gnus.el. You can reformat a paragraph by hitting -@samp{M-q} (as usual) +in ~/.gnus.el. + +You can reformat a paragraph by hitting @samp{M-q} (as usual). @node [5.3] @subsubheading Question 5.3 diff --git a/man/gnus.texi b/man/gnus.texi index af04f81f6bf..b0642673d12 100644 --- a/man/gnus.texi +++ b/man/gnus.texi @@ -13959,7 +13959,7 @@ corresponding keywords. @item :mailbox The name of the mailbox to get mail from. The default is @samp{INBOX} -which normally is the mailbox which receive incoming mail. +which normally is the mailbox which receives incoming mail. @item :predicate The predicate used to find articles to fetch. The default, @samp{UNSEEN @@ -18299,9 +18299,9 @@ needed. This function is hooked into the @code{nndiary} back end, so that moving or copying an article to a diary group will trigger it -automatically. It is also bound to @kbd{C-c D c} in @code{message-mode} -and @code{article-edit-mode} in order to ease the process of converting -a usual mail to a diary one. +automatically. It is also bound to @kbd{C-c C-f d} in +@code{message-mode} and @code{article-edit-mode} in order to ease the +process of converting a usual mail to a diary one. This function takes a prefix argument which will force prompting of all diary headers, regardless of their presence or validity. That way, @@ -25570,7 +25570,7 @@ know. @cindex Mule @cindex Emacs -Gnus should work on: +This Gnus version should work on: @itemize @bullet @@ -27240,7 +27240,12 @@ controls this. @item You can now drag and drop attachments to the Message buffer. See @code{mml-dnd-protocol-alist} and @code{mml-dnd-attach-options}. @xref{MIME, ,MIME, message, Message Manual}. -@c New in 5.10.9 / 5.11 +@c New in 5.10.9 / 5.11 (Emacs 21.1) + +@item @code{auto-fill-mode} is enabled by default in Message mode. +See @code{message-fill-column}. @xref{Various Message Variables, , +Message Headers, message, Message Manual}. +@c New in Gnus 5.10.12 / 5.11 (Emacs 22.3) @end itemize @@ -27293,8 +27298,9 @@ message, Message Manual}). @item The tool bars have been updated to use GNOME icons in Group, Summary and -Message mode. You can also customize the tool bars. This is a new -feature in Gnus 5.10.9. (Only for Emacs, not in XEmacs.) +Message mode. You can also customize the tool bars: @kbd{M-x +customize-apropos RET -tool-bar$} should get you started. This is a new +feature in Gnus 5.10.10. (Only for Emacs, not in XEmacs.) @item The tool bar icons are now (de)activated correctly in the group buffer, see the variable @code{gnus-group-update-tool-bar}. diff --git a/man/message.texi b/man/message.texi index 6d5bc34dd4e..b1d9e58e09e 100644 --- a/man/message.texi +++ b/man/message.texi @@ -1968,6 +1968,13 @@ Emacsen.) @xref{Charset Translation, , Charset Translation, emacs-mime, Emacs MIME Manual}, for details on the @sc{mule}-to-@acronym{MIME} translation process. +@item message-fill-column +@vindex message-fill-column +@cindex auto-fill +Local value for the column beyond which automatic line-wrapping should +happen for message buffers. If non-nil (the default), also turn on +auto-fill in message buffers. + @item message-signature-separator @vindex message-signature-separator Regexp matching the signature separator. It is @samp{^-- *$} by