aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorChong Yidong2010-11-16 21:37:45 -0500
committerChong Yidong2010-11-16 21:37:45 -0500
commit9173a8fbd77df7db68247a331df1c84f8ff074ec (patch)
tree551f2115d72059c703f73206bcc23a859a996b83 /src/keyboard.c
parent809fde057f0f7c2d04825c910e3f323e38a9d342 (diff)
downloademacs-9173a8fbd77df7db68247a331df1c84f8ff074ec.tar.gz
emacs-9173a8fbd77df7db68247a331df1c84f8ff074ec.zip
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.
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c220
1 files changed, 102 insertions, 118 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 017a4981b98..d048404e856 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5243,24 +5243,22 @@ EMACS_INT double_click_fuzz;
5243 5243
5244int double_click_count; 5244int double_click_count;
5245 5245
5246/* Return position of a mouse click or wheel event */ 5246/* X and Y are frame-relative coordinates for a click or wheel event.
5247 Return a Lisp-style event list. */
5247 5248
5248static Lisp_Object 5249static Lisp_Object
5249make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y, 5250make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
5250 unsigned long time) 5251 unsigned long time)
5251{ 5252{
5252 Lisp_Object window;
5253 enum window_part part; 5253 enum window_part part;
5254 Lisp_Object posn = Qnil; 5254 Lisp_Object posn = Qnil;
5255 Lisp_Object extra_info = Qnil; 5255 Lisp_Object extra_info = Qnil;
5256 int wx, wy; 5256 /* Coordinate pixel positions to return. */
5257 5257 int xret = 0, yret = 0;
5258 /* Set `window' to the window under frame pixel coordinates (x,y) */ 5258 /* The window under frame pixel coordinates (x,y) */
5259 if (f) 5259 Lisp_Object window = f
5260 window = window_from_coordinates (f, XINT (*x), XINT (*y), 5260 ? window_from_coordinates (f, XINT (x), XINT (y), &part, 0)
5261 &part, &wx, &wy, 0); 5261 : Qnil;
5262 else
5263 window = Qnil;
5264 5262
5265 if (WINDOWP (window)) 5263 if (WINDOWP (window))
5266 { 5264 {
@@ -5268,102 +5266,113 @@ make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y,
5268 struct window *w = XWINDOW (window); 5266 struct window *w = XWINDOW (window);
5269 Lisp_Object string_info = Qnil; 5267 Lisp_Object string_info = Qnil;
5270 EMACS_INT textpos = -1; 5268 EMACS_INT textpos = -1;
5271 int rx = -1, ry = -1; 5269 int col = -1, row = -1;
5272 int dx = -1, dy = -1; 5270 int dx = -1, dy = -1;
5273 int width = -1, height = -1; 5271 int width = -1, height = -1;
5274 Lisp_Object object = Qnil; 5272 Lisp_Object object = Qnil;
5275 5273
5276 /* Set event coordinates to window-relative coordinates 5274 /* Pixel coordinates relative to the window corner. */
5277 for constructing the Lisp event below. */ 5275 int wx = XINT (x) - WINDOW_LEFT_EDGE_X (w);
5278 XSETINT (*x, wx); 5276 int wy = XINT (y) - WINDOW_TOP_EDGE_Y (w);
5279 XSETINT (*y, wy);
5280 5277
5278 /* For text area clicks, return X, Y relative to the corner of
5279 this text area. Note that dX, dY etc are set below, by
5280 buffer_posn_from_coords. */
5281 if (part == ON_TEXT) 5281 if (part == ON_TEXT)
5282 { 5282 {
5283 wx += WINDOW_LEFT_MARGIN_WIDTH (w); 5283 xret = XINT (x) - window_box_left (w, TEXT_AREA);
5284 yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
5284 } 5285 }
5286 /* For mode line and header line clicks, return X relative to
5287 the left window edge; ignore Y. Use mode_line_string to look
5288 for a string on the click position. */
5285 else if (part == ON_MODE_LINE || part == ON_HEADER_LINE) 5289 else if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
5286 { 5290 {
5287 /* Mode line or header line. Look for a string under
5288 the mouse that may have a `local-map' property. */
5289 Lisp_Object string; 5291 Lisp_Object string;
5290 EMACS_INT charpos; 5292 EMACS_INT charpos;
5291 5293
5292 posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line; 5294 posn = (part == ON_MODE_LINE) ? Qmode_line : Qheader_line;
5293 rx = wx, ry = wy; 5295 /* Note that mode_line_string takes COL, ROW as pixels and
5294 string = mode_line_string (w, part, &rx, &ry, &charpos, 5296 converts them to characters. */
5297 col = wx;
5298 row = wy;
5299 string = mode_line_string (w, part, &col, &row, &charpos,
5295 &object, &dx, &dy, &width, &height); 5300 &object, &dx, &dy, &width, &height);
5296 if (STRINGP (string)) 5301 if (STRINGP (string))
5297 string_info = Fcons (string, make_number (charpos)); 5302 string_info = Fcons (string, make_number (charpos));
5298 if (w == XWINDOW (selected_window) 5303 textpos = (w == XWINDOW (selected_window)
5299 && current_buffer == XBUFFER (w->buffer)) 5304 && current_buffer == XBUFFER (w->buffer))
5300 textpos = PT; 5305 ? PT : XMARKER (w->pointm)->charpos;
5301 else 5306
5302 textpos = XMARKER (w->pointm)->charpos; 5307 xret = wx;
5303 }
5304 else if (part == ON_VERTICAL_BORDER)
5305 {
5306 posn = Qvertical_line;
5307 wx = -1;
5308 dx = 0;
5309 width = 1;
5310 } 5308 }
5309 /* For fringes and margins, Y is relative to the area's (and the
5310 window's) top edge, while X is meaningless. */
5311 else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN) 5311 else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
5312 { 5312 {
5313 Lisp_Object string; 5313 Lisp_Object string;
5314 EMACS_INT charpos; 5314 EMACS_INT charpos;
5315 5315
5316 posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin; 5316 posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
5317 rx = wx, ry = wy; 5317 col = wx;
5318 string = marginal_area_string (w, part, &rx, &ry, &charpos, 5318 row = wy;
5319 string = marginal_area_string (w, part, &col, &row, &charpos,
5319 &object, &dx, &dy, &width, &height); 5320 &object, &dx, &dy, &width, &height);
5320 if (STRINGP (string)) 5321 if (STRINGP (string))
5321 string_info = Fcons (string, make_number (charpos)); 5322 string_info = Fcons (string, make_number (charpos));
5322 if (part == ON_LEFT_MARGIN) 5323 yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
5323 wx = 0;
5324 else
5325 wx = window_box_right_offset (w, TEXT_AREA) - 1;
5326 } 5324 }
5327 else if (part == ON_LEFT_FRINGE) 5325 else if (part == ON_LEFT_FRINGE)
5328 { 5326 {
5329 posn = Qleft_fringe; 5327 posn = Qleft_fringe;
5330 rx = 0; 5328 col = 0;
5331 dx = wx; 5329 dx = wx
5332 wx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5330 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5333 ? 0 5331 ? 0 : window_box_width (w, LEFT_MARGIN_AREA));
5334 : window_box_width (w, LEFT_MARGIN_AREA)); 5332 dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
5335 dx -= wx;
5336 } 5333 }
5337 else if (part == ON_RIGHT_FRINGE) 5334 else if (part == ON_RIGHT_FRINGE)
5338 { 5335 {
5339 posn = Qright_fringe; 5336 posn = Qright_fringe;
5340 rx = 0; 5337 col = 0;
5341 dx = wx; 5338 dx = wx
5342 wx = (window_box_width (w, LEFT_MARGIN_AREA) 5339 - window_box_width (w, LEFT_MARGIN_AREA)
5343 + window_box_width (w, TEXT_AREA) 5340 - window_box_width (w, TEXT_AREA)
5344 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 5341 - (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
5345 ? window_box_width (w, RIGHT_MARGIN_AREA) 5342 ? window_box_width (w, RIGHT_MARGIN_AREA)
5346 : 0)); 5343 : 0);
5347 dx -= wx; 5344 dy = yret = wy - WINDOW_HEADER_LINE_HEIGHT (w);
5348 } 5345 }
5349 else 5346 else if (part == ON_VERTICAL_BORDER)
5350 { 5347 {
5351 /* Note: We have no special posn for part == ON_SCROLL_BAR. */ 5348 posn = Qvertical_line;
5352 wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx); 5349 width = 1;
5350 dx = 0;
5351 dy = yret = wy;
5353 } 5352 }
5353 /* Nothing special for part == ON_SCROLL_BAR. */
5354 5354
5355 /* For clicks in the text area, fringes, or margins, call
5356 buffer_posn_from_coords to extract TEXTPOS, the buffer
5357 position nearest to the click. */
5355 if (textpos < 0) 5358 if (textpos < 0)
5356 { 5359 {
5357 Lisp_Object string2, object2 = Qnil; 5360 Lisp_Object string2, object2 = Qnil;
5358 struct display_pos p; 5361 struct display_pos p;
5359 int dx2, dy2; 5362 int dx2, dy2;
5360 int width2, height2; 5363 int width2, height2;
5361 string2 = buffer_posn_from_coords (w, &wx, &wy, &p, 5364 /* The pixel X coordinate passed to buffer_posn_from_coords
5365 is the X coordinate relative to the text area for
5366 text-area clicks, zero otherwise. */
5367 int x2 = (part == ON_TEXT) ? xret : 0;
5368 int y2 = wy;
5369
5370 string2 = buffer_posn_from_coords (w, &x2, &y2, &p,
5362 &object2, &dx2, &dy2, 5371 &object2, &dx2, &dy2,
5363 &width2, &height2); 5372 &width2, &height2);
5364 textpos = CHARPOS (p.pos); 5373 textpos = CHARPOS (p.pos);
5365 if (rx < 0) rx = wx; 5374 if (col < 0) col = x2;
5366 if (ry < 0) ry = wy; 5375 if (row < 0) row = y2;
5367 if (dx < 0) dx = dx2; 5376 if (dx < 0) dx = dx2;
5368 if (dy < 0) dy = dy2; 5377 if (dy < 0) dy = dy2;
5369 if (width < 0) width = width2; 5378 if (width < 0) width = width2;
@@ -5394,34 +5403,27 @@ make_lispy_position (struct frame *f, Lisp_Object *x, Lisp_Object *y,
5394#endif 5403#endif
5395 5404
5396 /* Object info */ 5405 /* Object info */
5397 extra_info = Fcons (object, 5406 extra_info
5398 Fcons (Fcons (make_number (dx), 5407 = list3 (object,
5399 make_number (dy)), 5408 Fcons (make_number (dx), make_number (dy)),
5400 Fcons (Fcons (make_number (width), 5409 Fcons (make_number (width), make_number (height)));
5401 make_number (height)),
5402 Qnil)));
5403 5410
5404 /* String info */ 5411 /* String info */
5405 extra_info = Fcons (string_info, 5412 extra_info = Fcons (string_info,
5406 Fcons (make_number (textpos), 5413 Fcons (make_number (textpos),
5407 Fcons (Fcons (make_number (rx), 5414 Fcons (Fcons (make_number (col),
5408 make_number (ry)), 5415 make_number (row)),
5409 extra_info))); 5416 extra_info)));
5410 } 5417 }
5411 else if (f != 0) 5418 else if (f != 0)
5412 { 5419 XSETFRAME (window, f);
5413 XSETFRAME (window, f);
5414 }
5415 else 5420 else
5416 { 5421 window = Qnil;
5417 window = Qnil;
5418 XSETFASTINT (*x, 0);
5419 XSETFASTINT (*y, 0);
5420 }
5421 5422
5422 return Fcons (window, 5423 return Fcons (window,
5423 Fcons (posn, 5424 Fcons (posn,
5424 Fcons (Fcons (*x, *y), 5425 Fcons (Fcons (make_number (xret),
5426 make_number (yret)),
5425 Fcons (make_number (time), 5427 Fcons (make_number (time),
5426 extra_info)))); 5428 extra_info))));
5427} 5429}
@@ -5610,14 +5612,6 @@ make_lispy_event (struct input_event *event)
5610 int hpos; 5612 int hpos;
5611 int i; 5613 int i;
5612 5614
5613#if 0
5614 /* Activate the menu bar on the down event. If the
5615 up event comes in before the menu code can deal with it,
5616 just ignore it. */
5617 if (! (event->modifiers & down_modifier))
5618 return Qnil;
5619#endif
5620
5621 /* Find the menu bar item under `column'. */ 5615 /* Find the menu bar item under `column'. */
5622 item = Qnil; 5616 item = Qnil;
5623 items = FRAME_MENU_BAR_ITEMS (f); 5617 items = FRAME_MENU_BAR_ITEMS (f);
@@ -5649,7 +5643,7 @@ make_lispy_event (struct input_event *event)
5649 } 5643 }
5650#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */ 5644#endif /* not USE_X_TOOLKIT && not USE_GTK && not HAVE_NS */
5651 5645
5652 position = make_lispy_position (f, &event->x, &event->y, 5646 position = make_lispy_position (f, event->x, event->y,
5653 event->timestamp); 5647 event->timestamp);
5654 } 5648 }
5655#ifndef USE_TOOLKIT_SCROLL_BARS 5649#ifndef USE_TOOLKIT_SCROLL_BARS
@@ -5749,23 +5743,21 @@ make_lispy_event (struct input_event *event)
5749 return Qnil; 5743 return Qnil;
5750 5744
5751 event->modifiers &= ~up_modifier; 5745 event->modifiers &= ~up_modifier;
5752#if 0 /* Formerly we treated an up with no down as a click event. */ 5746
5753 if (!CONSP (start_pos))
5754 event->modifiers |= click_modifier;
5755 else
5756#endif
5757 { 5747 {
5758 Lisp_Object down; 5748 Lisp_Object new_down, down;
5759 EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz; 5749 EMACS_INT xdiff = double_click_fuzz, ydiff = double_click_fuzz;
5760 5750
5761 /* The third element of every position 5751 /* The third element of every position
5762 should be the (x,y) pair. */ 5752 should be the (x,y) pair. */
5763 down = Fcar (Fcdr (Fcdr (start_pos))); 5753 down = Fcar (Fcdr (Fcdr (start_pos)));
5754 new_down = Fcar (Fcdr (Fcdr (position)));
5755
5764 if (CONSP (down) 5756 if (CONSP (down)
5765 && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down))) 5757 && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down)))
5766 { 5758 {
5767 xdiff = XINT (event->x) - XINT (XCAR (down)); 5759 xdiff = XINT (XCAR (new_down)) - XINT (XCAR (down));
5768 ydiff = XINT (event->y) - XINT (XCDR (down)); 5760 ydiff = XINT (XCDR (new_down)) - XINT (XCDR (down));
5769 } 5761 }
5770 5762
5771 if (ignore_mouse_drag_p) 5763 if (ignore_mouse_drag_p)
@@ -5848,7 +5840,7 @@ make_lispy_event (struct input_event *event)
5848 if (! FRAME_LIVE_P (f)) 5840 if (! FRAME_LIVE_P (f))
5849 return Qnil; 5841 return Qnil;
5850 5842
5851 position = make_lispy_position (f, &event->x, &event->y, 5843 position = make_lispy_position (f, event->x, event->y,
5852 event->timestamp); 5844 event->timestamp);
5853 5845
5854 /* Set double or triple modifiers to indicate the wheel speed. */ 5846 /* Set double or triple modifiers to indicate the wheel speed. */
@@ -5868,10 +5860,8 @@ make_lispy_event (struct input_event *event)
5868 else 5860 else
5869 abort (); 5861 abort ();
5870 5862
5871 if (FRAME_WINDOW_P (f)) 5863 fuzz = FRAME_WINDOW_P (f)
5872 fuzz = double_click_fuzz; 5864 ? double_click_fuzz : double_click_fuzz / 8;
5873 else
5874 fuzz = double_click_fuzz / 8;
5875 5865
5876 if (event->modifiers & up_modifier) 5866 if (event->modifiers & up_modifier)
5877 { 5867 {
@@ -6009,7 +5999,7 @@ make_lispy_event (struct input_event *event)
6009 if (! FRAME_LIVE_P (f)) 5999 if (! FRAME_LIVE_P (f))
6010 return Qnil; 6000 return Qnil;
6011 6001
6012 position = make_lispy_position (f, &event->x, &event->y, 6002 position = make_lispy_position (f, event->x, event->y,
6013 event->timestamp); 6003 event->timestamp);
6014 6004
6015 head = modify_event_symbol (0, event->modifiers, 6005 head = modify_event_symbol (0, event->modifiers,
@@ -6092,8 +6082,8 @@ make_lispy_event (struct input_event *event)
6092 start_pos_ptr = &AREF (button_down_location, button); 6082 start_pos_ptr = &AREF (button_down_location, button);
6093 start_pos = *start_pos_ptr; 6083 start_pos = *start_pos_ptr;
6094 6084
6095 position = make_lispy_position (f, &event->x, &event->y, 6085 position = make_lispy_position (f, event->x, event->y,
6096 event->timestamp); 6086 event->timestamp);
6097 6087
6098 if (event->modifiers & down_modifier) 6088 if (event->modifiers & down_modifier)
6099 *start_pos_ptr = Fcopy_alist (position); 6089 *start_pos_ptr = Fcopy_alist (position);
@@ -6152,25 +6142,19 @@ make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_pa
6152 6142
6153 part_sym = *scroll_bar_parts[(int) part]; 6143 part_sym = *scroll_bar_parts[(int) part];
6154 return Fcons (Qscroll_bar_movement, 6144 return Fcons (Qscroll_bar_movement,
6155 (Fcons (Fcons (bar_window, 6145 Fcons (list5 (bar_window,
6156 Fcons (Qvertical_scroll_bar, 6146 Qvertical_scroll_bar,
6157 Fcons (Fcons (x, y), 6147 Fcons (x, y),
6158 Fcons (make_number (time), 6148 make_number (time),
6159 Fcons (part_sym, 6149 part_sym),
6160 Qnil))))), 6150 Qnil));
6161 Qnil)));
6162 } 6151 }
6163
6164 /* Or is it an ordinary mouse movement? */ 6152 /* Or is it an ordinary mouse movement? */
6165 else 6153 else
6166 { 6154 {
6167 Lisp_Object position; 6155 Lisp_Object position;
6168 6156 position = make_lispy_position (frame, x, y, time);
6169 position = make_lispy_position (frame, &x, &y, time); 6157 return list2 (Qmouse_movement, position);
6170
6171 return Fcons (Qmouse_movement,
6172 Fcons (position,
6173 Qnil));
6174 } 6158 }
6175} 6159}
6176 6160
@@ -11327,7 +11311,7 @@ The `posn-' functions access elements of such lists. */)
11327 11311
11328 CHECK_LIVE_FRAME (frame_or_window); 11312 CHECK_LIVE_FRAME (frame_or_window);
11329 11313
11330 return make_lispy_position (XFRAME (frame_or_window), &x, &y, 0); 11314 return make_lispy_position (XFRAME (frame_or_window), x, y, 0);
11331} 11315}
11332 11316
11333DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0, 11317DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,