# HG changeset patch # User YAMAMOTO Mitsuharu # Date 1115366604 0 # Node ID 2d42fd79f829742edf1e628cc55b09a57539e5e7 # Parent b710f3bc2da3e2dbfc2695402c15b33d9e57142c (toolkit_scroll_bar_interaction): Remove unused variable. (mac_handle_tool_bar_click): Remove unused function and declaration. [USE_TOOLKIT_SCROLL_BARS] (scroll_bar_timer_callback) (install_scroll_bar_timer, set_scroll_bar_timer) (control_part_code_to_scroll_bar_part, construct_scroll_bar_click) (get_control_part_bound, x_scroll_bar_handle_press) (x_scroll_bar_handle_release, x_scroll_bar_handle_drag) (x_set_toolkit_scroll_bar_thumb): New functions and declarations. [USE_TOOLKIT_SCROLL_BARS] (last_scroll_bar_part, scroll_bar_timer) (scroll_bar_timer_event_posted_p): New variables. [USE_TOOLKIT_SCROLL_BARS] (SCROLL_BAR_FIRST_DELAY) (SCROLL_BAR_CONTINUOUS_DELAY): New macros. (x_scroll_bar_create): Set control reference with NewControl. (x_scroll_bar_create) [USE_TOOLKIT_SCROLL_BARS]: Initialize track_top and track_height to nil. (x_scroll_bar_set_handle, x_scroll_bar_note_movement): Put functions in #ifndef USE_TOOLKIT_SCROLL_BARS. (XTset_vertical_scroll_bar): Don't make space between scroll bar and associated window. (XTset_vertical_scroll_bar) [MAC_OSX]: Get scroll bar area width from window config. (XTset_vertical_scroll_bar) [USE_TOOLKIT_SCROLL_BARS]: Set track_top and track_height to nil when scroll bar size is changed. Recalculate them if they are nil. (XTread_socket) [MAC_OSX]: Use control kind to determine if the clicked control is a scroll bar. (XTread_socket) [USE_TOOLKIT_SCROLL_BARS]: Use toolkit scroll bar event handler functions. Don't add modifiers to scroll bar click events. Call scroll bar release handler when window is deactivated. (mac_initialize): Remove unused code for X toolkit. (syms_of_macterm) [!USE_TOOLKIT_SCROLL_BARS]: Initialize Vx_toolkit_scroll_bars to nil. diff -r b710f3bc2da3 -r 2d42fd79f829 src/macterm.c --- a/src/macterm.c Fri May 06 08:03:08 2005 +0000 +++ b/src/macterm.c Fri May 06 08:03:24 2005 +0000 @@ -154,10 +154,6 @@ struct frame *pending_autoraise_frame; -/* Non-zero means user is interacting with a toolkit scroll bar. */ - -static int toolkit_scroll_bar_interaction; - /* Mouse movement. Formerly, we used PointerMotionHintMask (in standard_event_mask) @@ -256,7 +252,6 @@ struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr); struct mac_display_info *mac_display_info_for_display (Display *); static void x_update_window_end P_ ((struct window *, int, int)); -static void mac_handle_tool_bar_click P_ ((struct frame *, EventRecord *)); static int x_io_error_quitter P_ ((Display *)); int x_catch_errors P_ ((Display *)); void x_uncatch_errors P_ ((Display *, int)); @@ -4131,29 +4126,315 @@ } -/*********************************************************************** - Tool-bars - ***********************************************************************/ - -/* Handle mouse button event on the tool-bar of frame F, at - frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress - or ButtonRelase. */ - -static void -mac_handle_tool_bar_click (f, button_event) - struct frame *f; - EventRecord *button_event; -{ - int x = button_event->where.h; - int y = button_event->where.v; - - if (button_event->what == mouseDown) - handle_tool_bar_click (f, x, y, 1, 0); +/************************************************************************ + Toolkit scroll bars + ************************************************************************/ + +#ifdef USE_TOOLKIT_SCROLL_BARS + +static pascal void scroll_bar_timer_callback P_ ((EventLoopTimerRef, void *)); +static OSStatus install_scroll_bar_timer P_ ((void)); +static OSStatus set_scroll_bar_timer P_ ((EventTimerInterval)); +static int control_part_code_to_scroll_bar_part P_((ControlPartCode)); +static void construct_scroll_bar_click P_ ((struct scroll_bar *, int, + unsigned long, + struct input_event *)); +static OSErr get_control_part_bound P_((ControlHandle, ControlPartCode, + Rect *)); +static void x_scroll_bar_handle_press P_ ((struct scroll_bar *, + ControlPartCode, + unsigned long, + struct input_event *)); +static void x_scroll_bar_handle_release P_ ((struct scroll_bar *, + unsigned long, + struct input_event *)); +static void x_scroll_bar_handle_drag P_ ((WindowPtr, struct scroll_bar *, + Point, unsigned long, + struct input_event *)); +static void x_set_toolkit_scroll_bar_thumb P_ ((struct scroll_bar *, + int, int, int)); + +/* Last scroll bar part sent in x_scroll_bar_handle_*. */ + +static int last_scroll_bar_part; + +static EventLoopTimerRef scroll_bar_timer; + +static int scroll_bar_timer_event_posted_p; + +#define SCROLL_BAR_FIRST_DELAY 0.5 +#define SCROLL_BAR_CONTINUOUS_DELAY (1.0 / 15) + +static pascal void +scroll_bar_timer_callback (timer, data) + EventLoopTimerRef timer; + void *data; +{ + EventRef event = NULL; + OSErr err; + + err = CreateEvent (NULL, kEventClassMouse, kEventMouseMoved, 0, + kEventAttributeNone, &event); + if (err == noErr) + { + Point mouse_pos; + + GetMouse (&mouse_pos); + LocalToGlobal (&mouse_pos); + err = SetEventParameter (event, kEventParamMouseLocation, typeQDPoint, + sizeof (Point), &mouse_pos); + } + if (err == noErr) + { + UInt32 modifiers = GetCurrentKeyModifiers (); + + err = SetEventParameter (event, kEventParamKeyModifiers, typeUInt32, + sizeof (UInt32), &modifiers); + } + if (err == noErr) + err = PostEventToQueue (GetCurrentEventQueue (), event, + kEventPriorityStandard); + if (err == noErr) + scroll_bar_timer_event_posted_p = 1; + + if (event) + ReleaseEvent (event); +} + +static OSStatus +install_scroll_bar_timer () +{ + static EventLoopTimerUPP scroll_bar_timer_callbackUPP = NULL; + + if (scroll_bar_timer_callbackUPP == NULL) + scroll_bar_timer_callbackUPP = + NewEventLoopTimerUPP (scroll_bar_timer_callback); + + if (scroll_bar_timer == NULL) + /* Mac OS X and CarbonLib 1.5 and later allow us to specify + kEventDurationForever as delays. */ + return + InstallEventLoopTimer (GetCurrentEventLoop (), + kEventDurationForever, kEventDurationForever, + scroll_bar_timer_callbackUPP, NULL, + &scroll_bar_timer); +} + +static OSStatus +set_scroll_bar_timer (delay) + EventTimerInterval delay; +{ + if (scroll_bar_timer == NULL) + install_scroll_bar_timer (); + + scroll_bar_timer_event_posted_p = 0; + + return SetEventLoopTimerNextFireTime (scroll_bar_timer, delay); +} + +static int +control_part_code_to_scroll_bar_part (part_code) + ControlPartCode part_code; +{ + switch (part_code) + { + case kControlUpButtonPart: return scroll_bar_up_arrow; + case kControlDownButtonPart: return scroll_bar_down_arrow; + case kControlPageUpPart: return scroll_bar_above_handle; + case kControlPageDownPart: return scroll_bar_below_handle; + case kControlIndicatorPart: return scroll_bar_handle; + } + + return -1; +} + +static void +construct_scroll_bar_click (bar, part, timestamp, bufp) + struct scroll_bar *bar; + int part; + unsigned long timestamp; + struct input_event *bufp; +{ + bufp->kind = SCROLL_BAR_CLICK_EVENT; + bufp->frame_or_window = bar->window; + bufp->arg = Qnil; + bufp->part = part; + bufp->code = 0; + bufp->timestamp = timestamp; + XSETINT (bufp->x, 0); + XSETINT (bufp->y, 0); + bufp->modifiers = 0; +} + +static OSErr +get_control_part_bound (ch, part_code, rect) + ControlHandle ch; + ControlPartCode part_code; + Rect *rect; +{ + RgnHandle region = NewRgn (); + OSStatus err; + + err = GetControlRegion (ch, part_code, region); + if (err == noErr) + GetRegionBounds (region, rect); + DisposeRgn (region); + + return err; +} + +static void +x_scroll_bar_handle_press (bar, part_code, timestamp, bufp) + struct scroll_bar *bar; + ControlPartCode part_code; + unsigned long timestamp; + struct input_event *bufp; +{ + int part = control_part_code_to_scroll_bar_part (part_code); + + if (part < 0) + return; + + if (part != scroll_bar_handle) + { + construct_scroll_bar_click (bar, part, timestamp, bufp); + HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code); + set_scroll_bar_timer (SCROLL_BAR_FIRST_DELAY); + } + + last_scroll_bar_part = part; + bar->dragging = Qnil; + tracked_scroll_bar = bar; +} + +static void +x_scroll_bar_handle_release (bar, timestamp, bufp) + struct scroll_bar *bar; + unsigned long timestamp; + struct input_event *bufp; +{ + if (last_scroll_bar_part != scroll_bar_handle + || !GC_NILP (bar->dragging)) + construct_scroll_bar_click (bar, scroll_bar_end_scroll, timestamp, bufp); + + HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0); + set_scroll_bar_timer (kEventDurationForever); + + last_scroll_bar_part = -1; + bar->dragging = Qnil; + tracked_scroll_bar = NULL; +} + +static void +x_scroll_bar_handle_drag (win, bar, mouse_pos, timestamp, bufp) + WindowPtr win; + struct scroll_bar *bar; + Point mouse_pos; + unsigned long timestamp; + struct input_event *bufp; +{ + ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); + + if (last_scroll_bar_part == scroll_bar_handle) + { + int top, top_range; + Rect r; + + get_control_part_bound (SCROLL_BAR_CONTROL_HANDLE (bar), + kControlIndicatorPart, &r); + + if (GC_NILP (bar->dragging)) + XSETINT (bar->dragging, mouse_pos.v - r.top); + + top = mouse_pos.v - XINT (bar->dragging) - XINT (bar->track_top); + top_range = (XINT (bar->track_height) - (r.bottom - r.top)) * + (1.0 + (float) GetControlViewSize (ch) / GetControl32BitMaximum (ch)) + + .5; + + if (top < 0) + top = 0; + if (top > top_range) + top = top_range; + + construct_scroll_bar_click (bar, scroll_bar_handle, timestamp, bufp); + XSETINT (bufp->x, top); + XSETINT (bufp->y, top_range); + } else - handle_tool_bar_click (f, x, y, 0, - x_mac_to_emacs_modifiers (FRAME_MAC_DISPLAY_INFO (f), - button_event->modifiers)); -} + { + ControlPartCode part_code; + int unhilite_p = 0, part; + + if (ch != FindControlUnderMouse (mouse_pos, win, &part_code)) + unhilite_p = 1; + else + { + part = control_part_code_to_scroll_bar_part (part_code); + + switch (last_scroll_bar_part) + { + case scroll_bar_above_handle: + case scroll_bar_below_handle: + if (part != scroll_bar_above_handle + && part != scroll_bar_below_handle) + unhilite_p = 1; + break; + + case scroll_bar_up_arrow: + case scroll_bar_down_arrow: + if (part != scroll_bar_up_arrow + && part != scroll_bar_down_arrow) + unhilite_p = 1; + break; + } + } + + if (unhilite_p) + HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), 0); + else if (part != last_scroll_bar_part + || scroll_bar_timer_event_posted_p) + { + construct_scroll_bar_click (bar, part, timestamp, bufp); + last_scroll_bar_part = part; + HiliteControl (SCROLL_BAR_CONTROL_HANDLE (bar), part_code); + set_scroll_bar_timer (SCROLL_BAR_CONTINUOUS_DELAY); + } + } +} + +/* Set the thumb size and position of scroll bar BAR. We are currently + displaying PORTION out of a whole WHOLE, and our position POSITION. */ + +static void +x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole) + struct scroll_bar *bar; + int portion, position, whole; +{ + ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); + + int value, viewsize, maximum; + + if (whole == 0 || XINT (bar->track_height) == 0) + value = 0, viewsize = 1, maximum = 0; + else + { + value = position; + viewsize = portion; + maximum = max (0, whole - portion); + } + + BLOCK_INPUT; + + SetControl32BitMinimum (ch, 0); + SetControl32BitMaximum (ch, maximum); + SetControl32BitValue (ch, value); + SetControlViewSize (ch, viewsize); + + UNBLOCK_INPUT; +} + +#endif /* USE_TOOLKIT_SCROLL_BARS */ + /************************************************************************ @@ -4185,13 +4466,12 @@ #if TARGET_API_MAC_CARBON ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0, - kControlScrollBarProc, 0L); + kControlScrollBarProc, (long) bar); #else - ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0, scrollBarProc, - 0L); + ch = NewControl (FRAME_MAC_WINDOW (f), &r, "\p", 1, 0, 0, 0, + scrollBarProc, (long) bar); #endif SET_SCROLL_BAR_CONTROL_HANDLE (bar, ch); - SetControlReference (ch, (long) bar); XSETWINDOW (bar->window, w); XSETINT (bar->top, top); @@ -4201,6 +4481,10 @@ XSETINT (bar->start, 0); XSETINT (bar->end, 0); bar->dragging = Qnil; +#ifdef USE_TOOLKIT_SCROLL_BARS + bar->track_top = Qnil; + bar->track_height = Qnil; +#endif /* Add bar to its frame's list of scroll bars. */ bar->next = FRAME_SCROLL_BARS (f); @@ -4227,6 +4511,8 @@ the bar's top is as far down as it goes; otherwise, there's no way to move to the very end of the buffer. */ +#ifndef USE_TOOLKIT_SCROLL_BARS + static void x_scroll_bar_set_handle (bar, start, end, rebuild) struct scroll_bar *bar; @@ -4286,6 +4572,7 @@ UNBLOCK_INPUT; } +#endif /* !USE_TOOLKIT_SCROLL_BARS */ /* Destroy scroll bar BAR, and set its Emacs window's scroll bar to nil. */ @@ -4324,11 +4611,7 @@ /* Get window dimensions. */ window_box (w, -1, 0, &window_y, 0, &window_height); top = window_y; -#ifdef MAC_OSX - width = 16; -#else width = WINDOW_CONFIG_SCROLL_BAR_COLS (w) * FRAME_COLUMN_WIDTH (f); -#endif height = window_height; /* Compute the left edge of the scroll bar area. */ @@ -4343,9 +4626,9 @@ /* Compute the left edge of the scroll bar. */ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)) - sb_left = left + width - sb_width - (width - sb_width) / 2; + sb_left = left; else - sb_left = left + (width - sb_width) / 2; + sb_left = left + width - sb_width; /* Adjustments according to Inside Macintosh to make it look nice */ disp_top = top; @@ -4418,11 +4701,44 @@ XSETINT (bar->top, top); XSETINT (bar->width, sb_width); XSETINT (bar->height, height); +#ifdef USE_TOOLKIT_SCROLL_BARS + bar->track_top = Qnil; + bar->track_height = Qnil; +#endif } UNBLOCK_INPUT; } +#ifdef USE_TOOLKIT_SCROLL_BARS + if (NILP (bar->track_top)) + { + ControlHandle ch = SCROLL_BAR_CONTROL_HANDLE (bar); + Rect r0, r1; + + BLOCK_INPUT; + + SetControl32BitMinimum (ch, 0); + SetControl32BitMaximum (ch, 1); + SetControlViewSize (ch, 1); + + /* Move the scroll bar thumb to the top. */ + SetControl32BitValue (ch, 0); + get_control_part_bound (ch, kControlIndicatorPart, &r0); + + /* Move the scroll bar thumb to the bottom. */ + SetControl32BitValue (ch, 1); + get_control_part_bound (ch, kControlIndicatorPart, &r1); + + UnionRect (&r0, &r1, &r0); + XSETINT (bar->track_top, r0.top); + XSETINT (bar->track_height, r0.bottom - r0.top); + + UNBLOCK_INPUT; + } + + x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); +#else /* not USE_TOOLKIT_SCROLL_BARS */ /* Set the scroll bar's current state, unless we're currently being dragged. */ if (NILP (bar->dragging)) @@ -4438,6 +4754,7 @@ x_scroll_bar_set_handle (bar, start, end, 0); } } +#endif /* not USE_TOOLKIT_SCROLL_BARS */ } @@ -4619,6 +4936,7 @@ XSETINT (bufp->y, top_range); } +#ifndef USE_TOOLKIT_SCROLL_BARS /* Handle some mouse motion while someone is dragging the scroll bar. @@ -4653,6 +4971,7 @@ } } +#endif /* !USE_TOOLKIT_SCROLL_BARS */ /* Return information to the user about the current position of the mouse on the scroll bar. */ @@ -8657,6 +8976,9 @@ SInt16 control_part_code; ControlHandle ch; Point mouse_loc = er.where; +#ifdef MAC_OSX + ControlKind control_kind; +#endif f = mac_window_to_frame (window_ptr); /* convert to local coordinates of new window */ @@ -8666,6 +8988,10 @@ #if TARGET_API_MAC_CARBON ch = FindControlUnderMouse (mouse_loc, window_ptr, &control_part_code); +#ifdef MAC_OSX + if (ch) + GetControlKind (ch, &control_kind); +#endif #else control_part_code = FindControl (mouse_loc, window_ptr, &ch); @@ -8684,19 +9010,42 @@ /* ticks to milliseconds */ if (dpyinfo->grabbed && tracked_scroll_bar + || ch != 0 +#ifndef USE_TOOLKIT_SCROLL_BARS /* control_part_code becomes kControlNoPart if - a progress indicator is clicked. */ - || ch != 0 && control_part_code != kControlNoPart) + a progress indicator is clicked. */ + && control_part_code != kControlNoPart +#else /* USE_TOOLKIT_SCROLL_BARS */ +#ifdef MAC_OSX + && control_kind.kind == kControlKindScrollBar +#endif /* MAC_OSX */ +#endif /* USE_TOOLKIT_SCROLL_BARS */ + ) { struct scroll_bar *bar; if (dpyinfo->grabbed && tracked_scroll_bar) { bar = tracked_scroll_bar; +#ifndef USE_TOOLKIT_SCROLL_BARS control_part_code = kControlIndicatorPart; +#endif } else bar = (struct scroll_bar *) GetControlReference (ch); +#ifdef USE_TOOLKIT_SCROLL_BARS + /* Make the "Ctrl-Mouse-2 splits window" work + for toolkit scroll bars. */ + if (er.modifiers & controlKey) + x_scroll_bar_handle_click (bar, control_part_code, + &er, &inev); + else if (er.what == mouseDown) + x_scroll_bar_handle_press (bar, control_part_code, + inev.timestamp, &inev); + else + x_scroll_bar_handle_release (bar, inev.timestamp, + &inev); +#else /* not USE_TOOLKIT_SCROLL_BARS */ x_scroll_bar_handle_click (bar, control_part_code, &er, &inev); if (er.what == mouseDown @@ -8704,6 +9053,7 @@ tracked_scroll_bar = bar; else tracked_scroll_bar = NULL; +#endif /* not USE_TOOLKIT_SCROLL_BARS */ } else { @@ -8753,15 +9103,18 @@ dpyinfo->grabbed &= ~(1 << inev.code); } - switch (er.what) - { - case mouseDown: - inev.modifiers |= down_modifier; - break; - case mouseUp: - inev.modifiers |= up_modifier; - break; - } +#ifdef USE_TOOLKIT_SCROLL_BARS + if (inev.kind == MOUSE_CLICK_EVENT) +#endif + switch (er.what) + { + case mouseDown: + inev.modifiers |= down_modifier; + break; + case mouseUp: + inev.modifiers |= up_modifier; + break; + } } break; @@ -8863,10 +9216,16 @@ GlobalToLocal (&mouse_pos); if (dpyinfo->grabbed && tracked_scroll_bar) +#ifdef USE_TOOLKIT_SCROLL_BARS + x_scroll_bar_handle_drag (wp, tracked_scroll_bar, + mouse_pos, er.when * (1000 / 60), + &inev); +#else /* not USE_TOOLKIT_SCROLL_BARS */ x_scroll_bar_note_movement (tracked_scroll_bar, mouse_pos.v - XINT (tracked_scroll_bar->top), - TickCount() * (1000 / 60)); + er.when * (1000 / 60)); +#endif /* not USE_TOOLKIT_SCROLL_BARS */ else { /* Generate SELECT_WINDOW_EVENTs when needed. */ @@ -8941,6 +9300,23 @@ else { /* A window has been deactivated */ +#if USE_TOOLKIT_SCROLL_BARS + if (dpyinfo->grabbed && tracked_scroll_bar) + { + struct input_event event; + + EVENT_INIT (event); + event.kind = NO_EVENT; + x_scroll_bar_handle_release (tracked_scroll_bar, + er.when * (1000 / 60), + &event); + if (event.kind != NO_EVENT) + { + kbd_buffer_store_event_hold (&event, hold_quit); + count++; + } + } +#endif dpyinfo->grabbed = 0; x_detect_focus_change (dpyinfo, &er, &inev); @@ -9719,42 +10095,6 @@ /* Try to use interrupt input; if we can't, then start polling. */ Fset_input_mode (Qt, Qnil, Qt, Qnil); -#ifdef USE_X_TOOLKIT - XtToolkitInitialize (); - Xt_app_con = XtCreateApplicationContext (); - XtAppSetFallbackResources (Xt_app_con, Xt_default_resources); - - /* Install an asynchronous timer that processes Xt timeout events - every 0.1s. This is necessary because some widget sets use - timeouts internally, for example the LessTif menu bar, or the - Xaw3d scroll bar. When Xt timouts aren't processed, these - widgets don't behave normally. */ - { - EMACS_TIME interval; - EMACS_SET_SECS_USECS (interval, 0, 100000); - start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts, 0); - } -#endif - -#if USE_TOOLKIT_SCROLL_BARS - xaw3d_arrow_scroll = False; - xaw3d_pick_top = True; -#endif - -#if 0 - /* Note that there is no real way portable across R3/R4 to get the - original error handler. */ - XSetErrorHandler (x_error_handler); - XSetIOErrorHandler (x_io_error_quitter); - - /* Disable Window Change signals; they are handled by X events. */ -#ifdef SIGWINCH - signal (SIGWINCH, SIG_DFL); -#endif /* ! defined (SIGWINCH) */ - - signal (SIGPIPE, x_connection_signal); -#endif - BLOCK_INPUT; #if TARGET_API_MAC_CARBON @@ -9831,7 +10171,11 @@ DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars, doc: /* If not nil, Emacs uses toolkit scroll bars. */); +#ifdef USE_TOOLKIT_SCROLL_BARS Vx_toolkit_scroll_bars = Qt; +#else + Vx_toolkit_scroll_bars = Qnil; +#endif DEFVAR_BOOL ("x-use-underline-position-properties", &x_use_underline_position_properties,