# HG changeset patch # User Chong Yidong # Date 1289937564 18000 # Node ID 22fafcf25a54314d6ae4928b06321609301396d0 # Parent 7ac0fe73f41de3ea1869c3a946c630a1d94aec22 Cleanup of window coordinate positioning code. Now, text area click input events measure Y from the top of the text area, excluding the header line if any. * src/dispnew.c (buffer_posn_from_coords): Assume that X counts from the start of the text area. * src/keyboard.c (make_lispy_position): For text area clicks, record Y pixel position relative to the text area, excluding header line. Also change X and Y to Lisp_Objects, not pointers; don't return coordinate values via pointers. Pass ON_TEXT_AREA coordinate to buffer_posn_from_coords counting from the start of the text area. (Fposn_at_x_y, make_lispy_event): Callers changed. * src/w32term.c (w32_read_socket): * src/msdos.c (dos_rawgetc): * src/xterm.c (handle_one_xevent): Likewise. * src/window.c (coordinates_in_window): Change X and Y to ints rather than pointers; don't return coordinates via pointers. (struct check_window_data): Change X and Y from pointers to ints. (window_from_coordinates): Remove args WX and WY; don't return coordinates via pointers. (Fcoordinates_in_window_p, window_from_coordinates): (check_window_containing, Fwindow_at): Callers changed. (window_relative_x_coord): New function. * src/window.h (window_from_coordinates, window_relative_x_coord): Update prototypes. * src/xdisp.c (remember_mouse_glyph): Change window_from_coordinates call. Use window_relative_x_coord. (note_mouse_highlight): Change window_from_coordinates call. diff -r 7ac0fe73f41d -r 22fafcf25a54 etc/NEWS --- a/etc/NEWS Tue Nov 16 14:46:12 2010 +0100 +++ b/etc/NEWS Tue Nov 16 14:59:24 2010 -0500 @@ -559,6 +559,11 @@ * Incompatible Lisp Changes in Emacs 24.1 +** For mouse click input events in the text area, the Y pixel +coordinate in the POSITION list now counts from the top of the text +area, excluding any header line. Previously, it counted from the top +of the header line. + ** Remove obsolete name `e' (use `float-e' instead). ** A backquote not followed by a space is now always treated as new-style. diff -r 7ac0fe73f41d -r 22fafcf25a54 src/ChangeLog --- a/src/ChangeLog Tue Nov 16 14:46:12 2010 +0100 +++ b/src/ChangeLog Tue Nov 16 14:59:24 2010 -0500 @@ -1,3 +1,35 @@ +2010-11-16 Chong Yidong + + * keyboard.c (make_lispy_position): For text area clicks, record Y + pixel position relative to the text area, excluding header line. + Also change X and Y to Lisp_Objects, not pointers; don't return + coordinate values via pointers. Pass ON_TEXT_AREA coordinate to + buffer_posn_from_coords counting from the start of the text area. + (Fposn_at_x_y, make_lispy_event): Callers changed. + + * window.c (coordinates_in_window): Change X and Y to ints rather + than pointers; don't return coordinates via pointers. + (struct check_window_data): Change X and Y from pointers to ints. + (window_from_coordinates): Remove args WX and WY; don't return + coordinates via pointers. + (Fcoordinates_in_window_p, window_from_coordinates): + (check_window_containing, Fwindow_at): Callers changed. + (window_relative_x_coord): New function. + + * window.h (window_from_coordinates, window_relative_x_coord): + Update prototypes. + + * dispnew.c (buffer_posn_from_coords): Assume that X counts from + the start of the text area. + + * xdisp.c (remember_mouse_glyph): Change window_from_coordinates + call. Use window_relative_x_coord. + (note_mouse_highlight): Change window_from_coordinates call. + + * w32term.c (w32_read_socket): + * msdos.c (dos_rawgetc): + * xterm.c (handle_one_xevent): Likewise. + 2010-11-16 Dan Nicolaescu * strftime.c (LOCALE_PARAM_DECL): Update for standard C. diff -r 7ac0fe73f41d -r 22fafcf25a54 src/dispnew.c --- a/src/dispnew.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/dispnew.c Tue Nov 16 14:59:24 2010 -0500 @@ -5393,7 +5393,7 @@ BYTEPOS (startp) = min (ZV_BYTE, max (BEGV_BYTE, BYTEPOS (startp))); start_display (&it, w, startp); - x0 = *x - WINDOW_LEFT_MARGIN_WIDTH (w); + x0 = *x; /* First, move to the beginning of the row corresponding to *Y. We need to be in that row to get the correct value of base paragraph diff -r 7ac0fe73f41d -r 22fafcf25a54 src/keyboard.c --- a/src/keyboard.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/keyboard.c Tue Nov 16 14:59:24 2010 -0500 @@ -5243,24 +5243,22 @@ int double_click_count; -/* Return position of a mouse click or wheel event */ +/* X and Y are frame-relative coordinates for a click or wheel event. + Return a Lisp-style event list. */ static Lisp_Object -make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y, +make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y, unsigned long time) { - Lisp_Object window; enum window_part part; Lisp_Object posn = Qnil; Lisp_Object extra_info = Qnil; - int wx, wy; - - /* Set `window' to the window under frame pixel coordinates (x,y) */ - if (f) - window = window_from_coordinates (f, XINT (*x), XINT (*y), - &part, &wx, &wy, 0); - else - window = Qnil; + /* Coordinate pixel positions to return. */ + int xret = 0, yret = 0; + /* The window under frame pixel coordinates (x,y) */ + Lisp_Object window = f + ? window_from_coordinates (f, XINT (x), XINT (y), &part, 0) + : Qnil; if (WINDOWP (window)) { @@ -5268,102 +5266,113 @@ struct window *w = XWINDOW (window); Lisp_Object string_info = Qnil; EMACS_INT textpos = -1; - int rx = -1, ry = -1; - int dx = -1, dy = -1; + int col = -1, row = -1; + int dx = -1, dy = -1; int width = -1, height = -1; Lisp_Object object = Qnil; - /* Set event coordinates to window-relative coordinates - for constructing the Lisp event below. */ - XSETINT (*x, wx); - XSETINT (*y, wy); - + /* Pixel coordinates relative to the window corner. */ + int wx = XINT (x) - WINDOW_LEFT_EDGE_X (w); + int wy = XINT (y) - WINDOW_TOP_EDGE_Y (w); + + /* For text area clicks, return X, Y relative to the corner of + this text area. Note that dX, dY etc are set below, by + buffer_posn_from_coords. */ if (part == ON_TEXT) { - wx += WINDOW_LEFT_MARGIN_WIDTH (w); - } + xret = wx - window_box_left (w, TEXT_AREA); + yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); + } + /* For mode line and header line clicks, return X relative to + the left window edge; ignore Y. Use mode_line_string to look + for a string on the click position. */ else if (part == ON_MODE_LINE || part == ON_HEADER_LINE) { - /* Mode line or header line. Look for a string under - the mouse that may have a `local-map' property. */ Lisp_Object string; EMACS_INT charpos; - posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line; - rx = wx, ry = wy; - string = mode_line_string (w, part, &rx, &ry, &charpos, + posn = (part == ON_MODE_LINE) ? Qmode_line : Qheader_line; + /* Note that mode_line_string takes COL, ROW as pixels and + converts them to characters. */ + col = wx; + row = wy; + string = mode_line_string (w, part, &col, &row, &charpos, &object, &dx, &dy, &width, &height); if (STRINGP (string)) string_info = Fcons (string, make_number (charpos)); - if (w == XWINDOW (selected_window) - && current_buffer == XBUFFER (w->buffer)) - textpos = PT; - else - textpos = XMARKER (w->pointm)->charpos; - } - else if (part == ON_VERTICAL_BORDER) - { - posn = Qvertical_line; - wx = -1; - dx = 0; - width = 1; - } + textpos = (w == XWINDOW (selected_window) + && current_buffer == XBUFFER (w->buffer)) + ? PT : XMARKER (w->pointm)->charpos; + + xret = wx; + } + /* For fringes and margins, Y is relative to the area's (and the + window's) top edge, while X is meaningless. */ else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN) { Lisp_Object string; EMACS_INT charpos; posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin; - rx = wx, ry = wy; - string = marginal_area_string (w, part, &rx, &ry, &charpos, + col = wx; + row = wy; + string = marginal_area_string (w, part, &col, &row, &charpos, &object, &dx, &dy, &width, &height); if (STRINGP (string)) string_info = Fcons (string, make_number (charpos)); - if (part == ON_LEFT_MARGIN) - wx = 0; - else - wx = window_box_right_offset (w, TEXT_AREA) - 1; + yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); } else if (part == ON_LEFT_FRINGE) { posn = Qleft_fringe; - rx = 0; - dx = wx; - wx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - ? 0 - : window_box_width (w, LEFT_MARGIN_AREA)); - dx -= wx; + col = 0; + dx = wx + - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) + ? 0 : window_box_width (w, LEFT_MARGIN_AREA)); + dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); } else if (part == ON_RIGHT_FRINGE) { posn = Qright_fringe; - rx = 0; - dx = wx; - wx = (window_box_width (w, LEFT_MARGIN_AREA) - + window_box_width (w, TEXT_AREA) - + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - ? window_box_width (w, RIGHT_MARGIN_AREA) - : 0)); - dx -= wx; - } - else - { - /* Note: We have no special posn for part == ON_SCROLL_BAR. */ - wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx); - } - + col = 0; + dx = wx + - window_box_width (w, LEFT_MARGIN_AREA) + - window_box_width (w, TEXT_AREA) + - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) + ? window_box_width (w, RIGHT_MARGIN_AREA) + : 0); + dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w); + } + else if (part == ON_VERTICAL_BORDER) + { + posn = Qvertical_line; + width = 1; + dx = 0; + dy = yret = wy; + } + /* Nothing special for part == ON_SCROLL_BAR. */ + + /* For clicks in the text area, fringes, or margins, call + buffer_posn_from_coords to extract TEXTPOS, the buffer + position nearest to the click. */ if (textpos < 0) { Lisp_Object string2, object2 = Qnil; struct display_pos p; int dx2, dy2; int width2, height2; - string2 = buffer_posn_from_coords (w, &wx, &wy, &p, + /* The pixel X coordinate passed to buffer_posn_from_coords + is the X coordinate relative to the text area for + text-area clicks, zero otherwise. */ + int x2 = (part == ON_TEXT) ? xret : 0; + int y2 = wy; + + string2 = buffer_posn_from_coords (w, &x2, &y2, &p, &object2, &dx2, &dy2, &width2, &height2); textpos = CHARPOS (p.pos); - if (rx < 0) rx = wx; - if (ry < 0) ry = wy; + if (col < 0) col = x2; + if (row < 0) row = y2; if (dx < 0) dx = dx2; if (dy < 0) dy = dy2; if (width < 0) width = width2; @@ -5394,34 +5403,27 @@ #endif /* Object info */ - extra_info = Fcons (object, - Fcons (Fcons (make_number (dx), - make_number (dy)), - Fcons (Fcons (make_number (width), - make_number (height)), - Qnil))); + extra_info + = list3 (object, + Fcons (make_number (dx), make_number (dy)), + Fcons (make_number (width), make_number (height))); /* String info */ extra_info = Fcons (string_info, Fcons (make_number (textpos), - Fcons (Fcons (make_number (rx), - make_number (ry)), + Fcons (Fcons (make_number (col), + make_number (row)), extra_info))); } else if (f != 0) - { - XSETFRAME (window, f); - } + XSETFRAME (window, f); else - { - window = Qnil; - XSETFASTINT (*x, 0); - XSETFASTINT (*y, 0); - } + window = Qnil; return Fcons (window, Fcons (posn, - Fcons (Fcons (*x, *y), + Fcons (Fcons (make_number (xret), + make_number (yret)), Fcons (make_number (time), extra_info)))); } @@ -5610,14 +5612,6 @@ int hpos; int i; -#if 0 - /* Activate the menu bar on the down event. If the - up event comes in before the menu code can deal with it, - just ignore it. */ - if (! (event->modifiers & down_modifier)) - return Qnil; -#endif - /* Find the menu bar item under `column'. */ item = Qnil; items = FRAME_MENU_BAR_ITEMS (f); @@ -5649,7 +5643,7 @@ } #endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */ - position = make_lispy_position (f, &event->x, &event->y, + position = make_lispy_position (f, event->x, event->y, event->timestamp); } #ifndef USE_TOOLKIT_SCROLL_BARS @@ -5749,23 +5743,21 @@ return Qnil; event->modifiers &= ~up_modifier; -#if 0 /* Formerly we treated an up with no down as a click event. */ - if (!CONSP (start_pos)) - event->modifiers |= click_modifier; - else -#endif + { - Lisp_Object down; + Lisp_Object new_down, down; EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz; /* The third element of every position should be the (x,y) pair. */ down = Fcar (Fcdr (Fcdr (start_pos))); + new_down = Fcar (Fcdr (Fcdr (position))); + if (CONSP (down) && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down))) { - xdiff = XINT (event->x) - XINT (XCAR (down)); - ydiff = XINT (event->y) - XINT (XCDR (down)); + xdiff = XINT (XCAR (new_down)) - XINT (XCAR (down)); + ydiff = XINT (XCDR (new_down)) - XINT (XCDR (down)); } if (ignore_mouse_drag_p) @@ -5848,7 +5840,7 @@ if (! FRAME_LIVE_P (f)) return Qnil; - position = make_lispy_position (f, &event->x, &event->y, + position = make_lispy_position (f, event->x, event->y, event->timestamp); /* Set double or triple modifiers to indicate the wheel speed. */ @@ -5868,10 +5860,8 @@ else abort (); - if (FRAME_WINDOW_P (f)) - fuzz = double_click_fuzz; - else - fuzz = double_click_fuzz / 8; + fuzz = FRAME_WINDOW_P (f) + ? double_click_fuzz : double_click_fuzz / 8; if (event->modifiers & up_modifier) { @@ -6009,7 +5999,7 @@ if (! FRAME_LIVE_P (f)) return Qnil; - position = make_lispy_position (f, &event->x, &event->y, + position = make_lispy_position (f, event->x, event->y, event->timestamp); head = modify_event_symbol (0, event->modifiers, @@ -6092,8 +6082,8 @@ start_pos_ptr = &AREF (button_down_location, button); start_pos = *start_pos_ptr; - position = make_lispy_position (f, &event->x, &event->y, - event->timestamp); + position = make_lispy_position (f, event->x, event->y, + event->timestamp); if (event->modifiers & down_modifier) *start_pos_ptr = Fcopy_alist (position); @@ -6152,25 +6142,19 @@ part_sym = *scroll_bar_parts[(int) part]; return Fcons (Qscroll_bar_movement, - (Fcons (Fcons (bar_window, - Fcons (Qvertical_scroll_bar, - Fcons (Fcons (x, y), - Fcons (make_number (time), - Fcons (part_sym, - Qnil))))), - Qnil))); - } - + Fcons (list5 (bar_window, + Qvertical_scroll_bar, + Fcons (x, y), + make_number (time), + part_sym), + Qnil)); + } /* Or is it an ordinary mouse movement? */ else { Lisp_Object position; - - position = make_lispy_position (frame, &x, &y, time); - - return Fcons (Qmouse_movement, - Fcons (position, - Qnil)); + position = make_lispy_position (frame, x, y, time); + return list2 (Qmouse_movement, position); } } @@ -11327,7 +11311,7 @@ CHECK_LIVE_FRAME (frame_or_window); - return make_lispy_position (XFRAME (frame_or_window), &x, &y, 0); + return make_lispy_position (XFRAME (frame_or_window), x, y, 0); } DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0, diff -r 7ac0fe73f41d -r 22fafcf25a54 src/msdos.c --- a/src/msdos.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/msdos.c Tue Nov 16 14:59:24 2010 -0500 @@ -2698,7 +2698,7 @@ mouse_window = window_from_coordinates (SELECTED_FRAME(), mouse_last_x, mouse_last_y, - 0, 0, 0, 0); + 0, 0); /* A window will be selected only when it is not selected now, and the last mouse movement event was not in it. A minibuffer window will be selected iff diff -r 7ac0fe73f41d -r 22fafcf25a54 src/w32term.c --- a/src/w32term.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/w32term.c Tue Nov 16 14:59:24 2010 -0500 @@ -4317,7 +4317,7 @@ int x = LOWORD (msg.msg.lParam); int y = HIWORD (msg.msg.lParam); - window = window_from_coordinates (f, x, y, 0, 0, 0, 0); + window = window_from_coordinates (f, x, y, 0, 0); /* Window will be selected only when it is not selected now and last mouse movement event was @@ -4396,7 +4396,7 @@ int x = XFASTINT (inev.x); int y = XFASTINT (inev.y); - window = window_from_coordinates (f, x, y, 0, 0, 0, 1); + window = window_from_coordinates (f, x, y, 0, 1); if (EQ (window, f->tool_bar_window)) { diff -r 7ac0fe73f41d -r 22fafcf25a54 src/window.c --- a/src/window.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/window.c Tue Nov 16 14:59:24 2010 -0500 @@ -755,32 +755,26 @@ - WINDOW_MODE_LINE_HEIGHT (w) + add_y)); } -/* Test if the character at column *X, row *Y is within window W. +/* Test if the character at column X, row Y is within window W. If it is not, return ON_NOTHING; - if it is in the window's text area, - set *x and *y to its location relative to the upper left corner - of the window, and - return ON_TEXT; + if it is in the window's text area, return ON_TEXT; if it is on the window's modeline, return ON_MODE_LINE; if it is on the border between the window and its right sibling, return ON_VERTICAL_BORDER. - if it is on a scroll bar, - return ON_SCROLL_BAR. + if it is on a scroll bar, return ON_SCROLL_BAR. if it is on the window's top line, return ON_HEADER_LINE; if it is in left or right fringe of the window, - return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y - to window-relative coordinates; + return ON_LEFT_FRINGE or ON_RIGHT_FRINGE; if it is in the marginal area to the left/right of the window, - return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y - to window-relative coordinates. + return ON_LEFT_MARGIN or ON_RIGHT_MARGIN. X and Y are frame relative pixel coordinates. */ static enum window_part -coordinates_in_window (register struct window *w, register int *x, register int *y) +coordinates_in_window (register struct window *w, int x, int y) { struct frame *f = XFRAME (WINDOW_FRAME (w)); - int left_x, right_x, top_y, bottom_y; + int left_x, right_x; enum window_part part; int ux = FRAME_COLUMN_WIDTH (f); int x0 = WINDOW_LEFT_EDGE_X (w); @@ -789,6 +783,12 @@ (Between mode lines for instance. */ int grabbable_width = ux; int lmargin_width, rmargin_width, text_left, text_right; + int top_y = WINDOW_TOP_EDGE_Y (w); + int bottom_y = WINDOW_BOTTOM_EDGE_Y (w); + + /* Outside any interesting row? */ + if (y < top_y || y >= bottom_y) + return ON_NOTHING; /* In what's below, we subtract 1 when computing right_x because we want the rightmost pixel, which is given by left_pixel+width-1. */ @@ -796,21 +796,13 @@ { left_x = 0; right_x = WINDOW_TOTAL_WIDTH (w) - 1; - top_y = WINDOW_TOP_EDGE_Y (w); - bottom_y = WINDOW_BOTTOM_EDGE_Y (w); } else { left_x = WINDOW_BOX_LEFT_EDGE_X (w); right_x = WINDOW_BOX_RIGHT_EDGE_X (w) - 1; - top_y = WINDOW_TOP_EDGE_Y (w); - bottom_y = WINDOW_BOTTOM_EDGE_Y (w); } - /* Outside any interesting row? */ - if (*y < top_y || *y >= bottom_y) - return ON_NOTHING; - /* On the mode line or header line? If it's near the start of the mode or header line of window that's has a horizontal sibling, say it's on the vertical line. That's to be able @@ -818,7 +810,7 @@ scroll bars. */ if (WINDOW_WANTS_MODELINE_P (w) - && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w)) + && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w)) { part = ON_MODE_LINE; @@ -827,60 +819,37 @@ between mode lines of horizontally adjacent mode lines as the vertical border. If scroll bars on the left, return the right window. */ - if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) - || WINDOW_RIGHTMOST_P (w)) - { - if (!WINDOW_LEFTMOST_P (w) && eabs (*x - x0) < grabbable_width) - { - /* Convert X and Y to window relative coordinates. - Vertical border is at the left edge of window. */ - *x = max (0, *x - x0); - *y -= top_y; - return ON_VERTICAL_BORDER; - } - } - else - { - /* Make sure we're not at the rightmost position of a - mode-/header-line and there's yet another window on - the right. (Bug#1372) */ - if ((WINDOW_RIGHTMOST_P (w) || *x < x1) - && eabs (*x - x1) < grabbable_width) - { - /* Convert X and Y to window relative coordinates. - Vertical border is at the right edge of window. */ - *x = min (x1, *x) - x0; - *y -= top_y; - return ON_VERTICAL_BORDER; - } - } - - if (*x < x0 || *x >= x1) + if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) + || WINDOW_RIGHTMOST_P (w)) + && !WINDOW_LEFTMOST_P (w) + && eabs (x - x0) < grabbable_width) + return ON_VERTICAL_BORDER; + + /* Make sure we're not at the rightmost position of a + mode-/header-line and there's yet another window on the + right. (Bug#1372) */ + else if ((WINDOW_RIGHTMOST_P (w) || x < x1) + && eabs (x - x1) < grabbable_width) + return ON_VERTICAL_BORDER; + + if (x < x0 || x >= x1) return ON_NOTHING; - /* Convert X and Y to window relative coordinates. - Mode line starts at left edge of window. */ - *x -= x0; - *y -= top_y; return part; } if (WINDOW_WANTS_HEADER_LINE_P (w) - && *y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)) + && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)) { part = ON_HEADER_LINE; goto header_vertical_border_check; } - if (*x < x0 || *x >= x1) - return ON_NOTHING; + if (x < x0 || x >= x1) return ON_NOTHING; /* Outside any interesting column? */ - if (*x < left_x || *x > right_x) - { - *y -= top_y; - return ON_SCROLL_BAR; - } + if (x < left_x || x > right_x) + return ON_SCROLL_BAR; lmargin_width = window_box_width (w, LEFT_MARGIN_AREA); rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA); @@ -893,77 +862,79 @@ if (!w->pseudo_window_p && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w) && !WINDOW_RIGHTMOST_P (w) - && (eabs (*x - right_x) < grabbable_width)) - { - /* Convert X and Y to window relative coordinates. - Vertical border is at the right edge of window. */ - *x = min (right_x, *x) - left_x; - *y -= top_y; - return ON_VERTICAL_BORDER; - } + && (eabs (x - right_x) < grabbable_width)) + return ON_VERTICAL_BORDER; } - else - { - /* Need to say "*x > right_x" rather than >=, since on character - terminals, the vertical line's x coordinate is right_x. */ - if (!w->pseudo_window_p - && !WINDOW_RIGHTMOST_P (w) - && *x > right_x - ux) - { - /* On the border on the right side of the window? Assume that - this area begins at RIGHT_X minus a canonical char width. */ - *x = min (right_x, *x) - left_x; - *y -= top_y; - return ON_VERTICAL_BORDER; - } - } - - if (*x < text_left) + /* Need to say "x > right_x" rather than >=, since on character + terminals, the vertical line's x coordinate is right_x. */ + else if (!w->pseudo_window_p + && !WINDOW_RIGHTMOST_P (w) + && x > right_x - ux) + return ON_VERTICAL_BORDER; + + if (x < text_left) { if (lmargin_width > 0 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - ? (*x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w)) - : (*x < left_x + lmargin_width))) - { - *x -= left_x; - if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) - *x -= WINDOW_LEFT_FRINGE_WIDTH (w); - *y -= top_y; - return ON_LEFT_MARGIN; - } - - /* Convert X and Y to window-relative pixel coordinates. */ - *x -= left_x; - *y -= top_y; + ? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w)) + : (x < left_x + lmargin_width))) + return ON_LEFT_MARGIN; + return ON_LEFT_FRINGE; } - if (*x >= text_right) + if (x >= text_right) { if (rmargin_width > 0 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - ? (*x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w)) - : (*x >= right_x - rmargin_width))) - { - *x -= right_x - rmargin_width; - if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) - *x += WINDOW_RIGHT_FRINGE_WIDTH (w); - *y -= top_y; - return ON_RIGHT_MARGIN; - } - - /* Convert X and Y to window-relative pixel coordinates. */ - *x -= left_x + WINDOW_LEFT_FRINGE_WIDTH (w); - *y -= top_y; + ? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w)) + : (x >= right_x - rmargin_width))) + return ON_RIGHT_MARGIN; + return ON_RIGHT_FRINGE; } /* Everything special ruled out - must be on text area */ - *x -= text_left; - *y -= top_y; return ON_TEXT; } +/* Take X is the frame-relative pixel x-coordinate, and return the + x-coordinate relative to part PART of window W. */ +int +window_relative_x_coord (struct window *w, enum window_part part, int x) +{ + int left_x = (w->pseudo_window_p) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w); + + switch (part) + { + case ON_TEXT: + return x - window_box_left (w, TEXT_AREA); + + case ON_LEFT_FRINGE: + return x - left_x; + + case ON_RIGHT_FRINGE: + return x - left_x - WINDOW_LEFT_FRINGE_WIDTH (w); + + case ON_LEFT_MARGIN: + return (x - left_x + - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) + ? WINDOW_LEFT_FRINGE_WIDTH (w) : 0)); + + case ON_RIGHT_MARGIN: + return (x + 1 + - ((w->pseudo_window_p) + ? WINDOW_TOTAL_WIDTH (w) + : WINDOW_BOX_RIGHT_EDGE_X (w)) + + window_box_width (w, RIGHT_MARGIN_AREA) + + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) + ? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0)); + } + + /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */ + return 0; +} + DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, Scoordinates_in_window_p, 2, 2, 0, @@ -1000,14 +971,16 @@ x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f); y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f); - switch (coordinates_in_window (w, &x, &y)) + switch (coordinates_in_window (w, x, y)) { case ON_NOTHING: return Qnil; case ON_TEXT: - /* X and Y are now window relative pixel coordinates. Convert - them to canonical char units before returning them. */ + /* Convert X and Y to window relative pixel coordinates, and + return the canonical char units. */ + x -= window_box_left (w, TEXT_AREA); + y -= WINDOW_TOP_EDGE_Y (w); return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f, x), FRAME_CANON_Y_FROM_PIXEL_Y (f, y)); @@ -1054,7 +1027,7 @@ struct check_window_data { Lisp_Object *window; - int *x, *y; + int x, y; enum window_part *part; }; @@ -1081,8 +1054,7 @@ return it as a Lisp_Object. If X, Y is on one of the window's special `window_part' elements, - set *PART to the id of that element, and return X and Y converted - to window relative coordinates in WX and WY. + set *PART to the id of that element. If there is no window under X, Y return nil and leave *PART unmodified. TOOL_BAR_P non-zero means detect tool-bar windows. @@ -1097,7 +1069,8 @@ case. */ Lisp_Object -window_from_coordinates (struct frame *f, int x, int y, enum window_part *part, int *wx, int *wy, int tool_bar_p) +window_from_coordinates (struct frame *f, int x, int y, + enum window_part *part, int tool_bar_p) { Lisp_Object window; struct check_window_data cw; @@ -1107,7 +1080,7 @@ part = &dummy; window = Qnil; - cw.window = &window, cw.x = &x, cw.y = &y; cw.part = part; + cw.window = &window, cw.x = x, cw.y = y; cw.part = part; foreach_window (f, check_window_containing, &cw); /* If not found above, see if it's in the tool bar window, if a tool @@ -1116,16 +1089,13 @@ && tool_bar_p && WINDOWP (f->tool_bar_window) && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0 - && (coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y) + && (coordinates_in_window (XWINDOW (f->tool_bar_window), x, y) != ON_NOTHING)) { *part = ON_TEXT; window = f->tool_bar_window; } - if (wx) *wx = x; - if (wy) *wy = y; - return window; } @@ -1152,7 +1122,7 @@ + FRAME_INTERNAL_BORDER_WIDTH (f)), (FRAME_PIXEL_Y_FROM_CANON_Y (f, y) + FRAME_INTERNAL_BORDER_WIDTH (f)), - 0, 0, 0, 0); + 0, 0); } DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, diff -r 7ac0fe73f41d -r 22fafcf25a54 src/window.h --- a/src/window.h Tue Nov 16 14:46:12 2010 +0100 +++ b/src/window.h Tue Nov 16 14:59:24 2010 -0500 @@ -788,8 +788,7 @@ extern Lisp_Object make_window (void); extern void delete_window (Lisp_Object); extern Lisp_Object window_from_coordinates (struct frame *, int, int, - enum window_part *, - int *, int*, int); + enum window_part *, int); EXFUN (Fwindow_dedicated_p, 1); extern int window_height (Lisp_Object); extern int window_width (Lisp_Object); @@ -804,6 +803,7 @@ void *); extern void grow_mini_window (struct window *, int); extern void shrink_mini_window (struct window *); +extern int window_relative_x_coord (struct window *, enum window_part, int); void run_window_configuration_change_hook (struct frame *f); diff -r 7ac0fe73f41d -r 22fafcf25a54 src/xdisp.c --- a/src/xdisp.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/xdisp.c Tue Nov 16 14:59:24 2010 -0500 @@ -2218,7 +2218,7 @@ frame pixel coordinates X/Y on frame F. */ if (!f->glyphs_initialized_p - || (window = window_from_coordinates (f, gx, gy, &part, &x, &y, 0), + || (window = window_from_coordinates (f, gx, gy, &part, 0), NILP (window))) { width = FRAME_SMALLEST_CHAR_WIDTH (f); @@ -2230,6 +2230,9 @@ width = WINDOW_FRAME_COLUMN_WIDTH (w); height = WINDOW_FRAME_LINE_HEIGHT (w); + x = window_relative_x_coord (w, part, gx); + y = gy - WINDOW_TOP_EDGE_Y (w); + r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w); @@ -25383,7 +25386,7 @@ } /* Which window is that in? */ - window = window_from_coordinates (f, x, y, &part, 0, 0, 1); + window = window_from_coordinates (f, x, y, &part, 1); /* If we were displaying active text in another window, clear that. Also clear if we move out of text area in same window. */ diff -r 7ac0fe73f41d -r 22fafcf25a54 src/xterm.c --- a/src/xterm.c Tue Nov 16 14:46:12 2010 +0100 +++ b/src/xterm.c Tue Nov 16 14:59:24 2010 -0500 @@ -6658,7 +6658,7 @@ window = window_from_coordinates (f, event.xmotion.x, event.xmotion.y, - 0, 0, 0, 0); + 0, 0); /* Window will be selected only when it is not selected now and last mouse movement event was not in it. Minibuffer window @@ -6797,7 +6797,7 @@ int x = event.xbutton.x; int y = event.xbutton.y; - window = window_from_coordinates (f, x, y, 0, 0, 0, 1); + window = window_from_coordinates (f, x, y, 0, 1); tool_bar_p = EQ (window, f->tool_bar_window); if (tool_bar_p && event.xbutton.button < 4)