aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.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/window.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/window.c')
-rw-r--r--src/window.c224
1 files changed, 97 insertions, 127 deletions
diff --git a/src/window.c b/src/window.c
index 086cd858c2e..a2a0c793111 100644
--- a/src/window.c
+++ b/src/window.c
@@ -755,32 +755,26 @@ display margins, fringes, header line, and/or mode line. */)
755 - WINDOW_MODE_LINE_HEIGHT (w) + add_y)); 755 - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
756} 756}
757 757
758/* Test if the character at column *X, row *Y is within window W. 758/* Test if the character at column X, row Y is within window W.
759 If it is not, return ON_NOTHING; 759 If it is not, return ON_NOTHING;
760 if it is in the window's text area, 760 if it is in the window's text area, return ON_TEXT;
761 set *x and *y to its location relative to the upper left corner
762 of the window, and
763 return ON_TEXT;
764 if it is on the window's modeline, return ON_MODE_LINE; 761 if it is on the window's modeline, return ON_MODE_LINE;
765 if it is on the border between the window and its right sibling, 762 if it is on the border between the window and its right sibling,
766 return ON_VERTICAL_BORDER. 763 return ON_VERTICAL_BORDER.
767 if it is on a scroll bar, 764 if it is on a scroll bar, return ON_SCROLL_BAR.
768 return ON_SCROLL_BAR.
769 if it is on the window's top line, return ON_HEADER_LINE; 765 if it is on the window's top line, return ON_HEADER_LINE;
770 if it is in left or right fringe of the window, 766 if it is in left or right fringe of the window,
771 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE, and convert *X and *Y 767 return ON_LEFT_FRINGE or ON_RIGHT_FRINGE;
772 to window-relative coordinates;
773 if it is in the marginal area to the left/right of the window, 768 if it is in the marginal area to the left/right of the window,
774 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN, and convert *X and *Y 769 return ON_LEFT_MARGIN or ON_RIGHT_MARGIN.
775 to window-relative coordinates.
776 770
777 X and Y are frame relative pixel coordinates. */ 771 X and Y are frame relative pixel coordinates. */
778 772
779static enum window_part 773static enum window_part
780coordinates_in_window (register struct window *w, register int *x, register int *y) 774coordinates_in_window (register struct window *w, int x, int y)
781{ 775{
782 struct frame *f = XFRAME (WINDOW_FRAME (w)); 776 struct frame *f = XFRAME (WINDOW_FRAME (w));
783 int left_x, right_x, top_y, bottom_y; 777 int left_x, right_x;
784 enum window_part part; 778 enum window_part part;
785 int ux = FRAME_COLUMN_WIDTH (f); 779 int ux = FRAME_COLUMN_WIDTH (f);
786 int x0 = WINDOW_LEFT_EDGE_X (w); 780 int x0 = WINDOW_LEFT_EDGE_X (w);
@@ -789,6 +783,12 @@ coordinates_in_window (register struct window *w, register int *x, register int
789 (Between mode lines for instance. */ 783 (Between mode lines for instance. */
790 int grabbable_width = ux; 784 int grabbable_width = ux;
791 int lmargin_width, rmargin_width, text_left, text_right; 785 int lmargin_width, rmargin_width, text_left, text_right;
786 int top_y = WINDOW_TOP_EDGE_Y (w);
787 int bottom_y = WINDOW_BOTTOM_EDGE_Y (w);
788
789 /* Outside any interesting row? */
790 if (y < top_y || y >= bottom_y)
791 return ON_NOTHING;
792 792
793 /* In what's below, we subtract 1 when computing right_x because we 793 /* In what's below, we subtract 1 when computing right_x because we
794 want the rightmost pixel, which is given by left_pixel+width-1. */ 794 want the rightmost pixel, which is given by left_pixel+width-1. */
@@ -796,21 +796,13 @@ coordinates_in_window (register struct window *w, register int *x, register int
796 { 796 {
797 left_x = 0; 797 left_x = 0;
798 right_x = WINDOW_TOTAL_WIDTH (w) - 1; 798 right_x = WINDOW_TOTAL_WIDTH (w) - 1;
799 top_y = WINDOW_TOP_EDGE_Y (w);
800 bottom_y = WINDOW_BOTTOM_EDGE_Y (w);
801 } 799 }
802 else 800 else
803 { 801 {
804 left_x = WINDOW_BOX_LEFT_EDGE_X (w); 802 left_x = WINDOW_BOX_LEFT_EDGE_X (w);
805 right_x = WINDOW_BOX_RIGHT_EDGE_X (w) - 1; 803 right_x = WINDOW_BOX_RIGHT_EDGE_X (w) - 1;
806 top_y = WINDOW_TOP_EDGE_Y (w);
807 bottom_y = WINDOW_BOTTOM_EDGE_Y (w);
808 } 804 }
809 805
810 /* Outside any interesting row? */
811 if (*y < top_y || *y >= bottom_y)
812 return ON_NOTHING;
813
814 /* On the mode line or header line? If it's near the start of 806 /* On the mode line or header line? If it's near the start of
815 the mode or header line of window that's has a horizontal 807 the mode or header line of window that's has a horizontal
816 sibling, say it's on the vertical line. That's to be able 808 sibling, say it's on the vertical line. That's to be able
@@ -818,7 +810,7 @@ coordinates_in_window (register struct window *w, register int *x, register int
818 scroll bars. */ 810 scroll bars. */
819 811
820 if (WINDOW_WANTS_MODELINE_P (w) 812 if (WINDOW_WANTS_MODELINE_P (w)
821 && *y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w)) 813 && y >= bottom_y - CURRENT_MODE_LINE_HEIGHT (w))
822 { 814 {
823 part = ON_MODE_LINE; 815 part = ON_MODE_LINE;
824 816
@@ -827,60 +819,37 @@ coordinates_in_window (register struct window *w, register int *x, register int
827 between mode lines of horizontally adjacent mode lines 819 between mode lines of horizontally adjacent mode lines
828 as the vertical border. If scroll bars on the left, 820 as the vertical border. If scroll bars on the left,
829 return the right window. */ 821 return the right window. */
830 if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w) 822 if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
831 || WINDOW_RIGHTMOST_P (w)) 823 || WINDOW_RIGHTMOST_P (w))
832 { 824 && !WINDOW_LEFTMOST_P (w)
833 if (!WINDOW_LEFTMOST_P (w) && eabs (*x - x0) < grabbable_width) 825 && eabs (x - x0) < grabbable_width)
834 { 826 return ON_VERTICAL_BORDER;
835 /* Convert X and Y to window relative coordinates. 827
836 Vertical border is at the left edge of window. */ 828 /* Make sure we're not at the rightmost position of a
837 *x = max (0, *x - x0); 829 mode-/header-line and there's yet another window on the
838 *y -= top_y; 830 right. (Bug#1372) */
839 return ON_VERTICAL_BORDER; 831 else if ((WINDOW_RIGHTMOST_P (w) || x < x1)
840 } 832 && eabs (x - x1) < grabbable_width)
841 } 833 return ON_VERTICAL_BORDER;
842 else 834
843 { 835 if (x < x0 || x >= x1)
844 /* Make sure we're not at the rightmost position of a
845 mode-/header-line and there's yet another window on
846 the right. (Bug#1372) */
847 if ((WINDOW_RIGHTMOST_P (w) || *x < x1)
848 && eabs (*x - x1) < grabbable_width)
849 {
850 /* Convert X and Y to window relative coordinates.
851 Vertical border is at the right edge of window. */
852 *x = min (x1, *x) - x0;
853 *y -= top_y;
854 return ON_VERTICAL_BORDER;
855 }
856 }
857
858 if (*x < x0 || *x >= x1)
859 return ON_NOTHING; 836 return ON_NOTHING;
860 837
861 /* Convert X and Y to window relative coordinates.
862 Mode line starts at left edge of window. */
863 *x -= x0;
864 *y -= top_y;
865 return part; 838 return part;
866 } 839 }
867 840
868 if (WINDOW_WANTS_HEADER_LINE_P (w) 841 if (WINDOW_WANTS_HEADER_LINE_P (w)
869 && *y < top_y + CURRENT_HEADER_LINE_HEIGHT (w)) 842 && y < top_y + CURRENT_HEADER_LINE_HEIGHT (w))
870 { 843 {
871 part = ON_HEADER_LINE; 844 part = ON_HEADER_LINE;
872 goto header_vertical_border_check; 845 goto header_vertical_border_check;
873 } 846 }
874 847
875 if (*x < x0 || *x >= x1) 848 if (x < x0 || x >= x1) return ON_NOTHING;
876 return ON_NOTHING;
877 849
878 /* Outside any interesting column? */ 850 /* Outside any interesting column? */
879 if (*x < left_x || *x > right_x) 851 if (x < left_x || x > right_x)
880 { 852 return ON_SCROLL_BAR;
881 *y -= top_y;
882 return ON_SCROLL_BAR;
883 }
884 853
885 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA); 854 lmargin_width = window_box_width (w, LEFT_MARGIN_AREA);
886 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA); 855 rmargin_width = window_box_width (w, RIGHT_MARGIN_AREA);
@@ -893,77 +862,79 @@ coordinates_in_window (register struct window *w, register int *x, register int
893 if (!w->pseudo_window_p 862 if (!w->pseudo_window_p
894 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w) 863 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
895 && !WINDOW_RIGHTMOST_P (w) 864 && !WINDOW_RIGHTMOST_P (w)
896 && (eabs (*x - right_x) < grabbable_width)) 865 && (eabs (x - right_x) < grabbable_width))
897 { 866 return ON_VERTICAL_BORDER;
898 /* Convert X and Y to window relative coordinates.
899 Vertical border is at the right edge of window. */
900 *x = min (right_x, *x) - left_x;
901 *y -= top_y;
902 return ON_VERTICAL_BORDER;
903 }
904 }
905 else
906 {
907 /* Need to say "*x > right_x" rather than >=, since on character
908 terminals, the vertical line's x coordinate is right_x. */
909 if (!w->pseudo_window_p
910 && !WINDOW_RIGHTMOST_P (w)
911 && *x > right_x - ux)
912 {
913 /* On the border on the right side of the window? Assume that
914 this area begins at RIGHT_X minus a canonical char width. */
915 *x = min (right_x, *x) - left_x;
916 *y -= top_y;
917 return ON_VERTICAL_BORDER;
918 }
919 } 867 }
868 /* Need to say "x > right_x" rather than >=, since on character
869 terminals, the vertical line's x coordinate is right_x. */
870 else if (!w->pseudo_window_p
871 && !WINDOW_RIGHTMOST_P (w)
872 && x > right_x - ux)
873 return ON_VERTICAL_BORDER;
920 874
921 if (*x < text_left) 875 if (x < text_left)
922 { 876 {
923 if (lmargin_width > 0 877 if (lmargin_width > 0
924 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 878 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
925 ? (*x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w)) 879 ? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
926 : (*x < left_x + lmargin_width))) 880 : (x < left_x + lmargin_width)))
927 { 881 return ON_LEFT_MARGIN;
928 *x -= left_x;
929 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
930 *x -= WINDOW_LEFT_FRINGE_WIDTH (w);
931 *y -= top_y;
932 return ON_LEFT_MARGIN;
933 }
934 882
935 /* Convert X and Y to window-relative pixel coordinates. */
936 *x -= left_x;
937 *y -= top_y;
938 return ON_LEFT_FRINGE; 883 return ON_LEFT_FRINGE;
939 } 884 }
940 885
941 if (*x >= text_right) 886 if (x >= text_right)
942 { 887 {
943 if (rmargin_width > 0 888 if (rmargin_width > 0
944 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) 889 && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
945 ? (*x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w)) 890 ? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
946 : (*x >= right_x - rmargin_width))) 891 : (x >= right_x - rmargin_width)))
947 { 892 return ON_RIGHT_MARGIN;
948 *x -= right_x - rmargin_width;
949 if (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
950 *x += WINDOW_RIGHT_FRINGE_WIDTH (w);
951 *y -= top_y;
952 return ON_RIGHT_MARGIN;
953 }
954 893
955 /* Convert X and Y to window-relative pixel coordinates. */
956 *x -= left_x + WINDOW_LEFT_FRINGE_WIDTH (w);
957 *y -= top_y;
958 return ON_RIGHT_FRINGE; 894 return ON_RIGHT_FRINGE;
959 } 895 }
960 896
961 /* Everything special ruled out - must be on text area */ 897 /* Everything special ruled out - must be on text area */
962 *x -= text_left;
963 *y -= top_y;
964 return ON_TEXT; 898 return ON_TEXT;
965} 899}
966 900
901/* Take X is the frame-relative pixel x-coordinate, and return the
902 x-coordinate relative to part PART of window W. */
903int
904window_relative_x_coord (struct window *w, enum window_part part, int x)
905{
906 int left_x = (w->pseudo_window_p) ? 0 : WINDOW_BOX_LEFT_EDGE_X (w);
907
908 switch (part)
909 {
910 case ON_TEXT:
911 return x - window_box_left (w, TEXT_AREA);
912
913 case ON_LEFT_FRINGE:
914 return x - left_x;
915
916 case ON_RIGHT_FRINGE:
917 return x - left_x - WINDOW_LEFT_FRINGE_WIDTH (w);
918
919 case ON_LEFT_MARGIN:
920 return (x - left_x
921 - ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
922 ? WINDOW_LEFT_FRINGE_WIDTH (w) : 0));
923
924 case ON_RIGHT_MARGIN:
925 return (x + 1
926 - ((w->pseudo_window_p)
927 ? WINDOW_TOTAL_WIDTH (w)
928 : WINDOW_BOX_RIGHT_EDGE_X (w))
929 + window_box_width (w, RIGHT_MARGIN_AREA)
930 + ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
931 ? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0));
932 }
933
934 /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */
935 return 0;
936}
937
967 938
968DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, 939DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
969 Scoordinates_in_window_p, 2, 2, 0, 940 Scoordinates_in_window_p, 2, 2, 0,
@@ -1000,14 +971,16 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1000 x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f); 971 x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f);
1001 y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f); 972 y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f);
1002 973
1003 switch (coordinates_in_window (w, &x, &y)) 974 switch (coordinates_in_window (w, x, y))
1004 { 975 {
1005 case ON_NOTHING: 976 case ON_NOTHING:
1006 return Qnil; 977 return Qnil;
1007 978
1008 case ON_TEXT: 979 case ON_TEXT:
1009 /* X and Y are now window relative pixel coordinates. Convert 980 /* Convert X and Y to window relative pixel coordinates, and
1010 them to canonical char units before returning them. */ 981 return the canonical char units. */
982 x -= window_box_left (w, TEXT_AREA);
983 y -= WINDOW_TOP_EDGE_Y (w);
1011 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f, x), 984 return Fcons (FRAME_CANON_X_FROM_PIXEL_X (f, x),
1012 FRAME_CANON_Y_FROM_PIXEL_Y (f, y)); 985 FRAME_CANON_Y_FROM_PIXEL_Y (f, y));
1013 986
@@ -1054,7 +1027,7 @@ If they are in the windows's left or right marginal areas, `left-margin'\n\
1054struct check_window_data 1027struct check_window_data
1055{ 1028{
1056 Lisp_Object *window; 1029 Lisp_Object *window;
1057 int *x, *y; 1030 int x, y;
1058 enum window_part *part; 1031 enum window_part *part;
1059}; 1032};
1060 1033
@@ -1081,8 +1054,7 @@ check_window_containing (struct window *w, void *user_data)
1081 return it as a Lisp_Object. 1054 return it as a Lisp_Object.
1082 1055
1083 If X, Y is on one of the window's special `window_part' elements, 1056 If X, Y is on one of the window's special `window_part' elements,
1084 set *PART to the id of that element, and return X and Y converted 1057 set *PART to the id of that element.
1085 to window relative coordinates in WX and WY.
1086 1058
1087 If there is no window under X, Y return nil and leave *PART 1059 If there is no window under X, Y return nil and leave *PART
1088 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows. 1060 unmodified. TOOL_BAR_P non-zero means detect tool-bar windows.
@@ -1097,7 +1069,8 @@ check_window_containing (struct window *w, void *user_data)
1097 case. */ 1069 case. */
1098 1070
1099Lisp_Object 1071Lisp_Object
1100window_from_coordinates (struct frame *f, int x, int y, enum window_part *part, int *wx, int *wy, int tool_bar_p) 1072window_from_coordinates (struct frame *f, int x, int y,
1073 enum window_part *part, int tool_bar_p)
1101{ 1074{
1102 Lisp_Object window; 1075 Lisp_Object window;
1103 struct check_window_data cw; 1076 struct check_window_data cw;
@@ -1107,7 +1080,7 @@ window_from_coordinates (struct frame *f, int x, int y, enum window_part *part,
1107 part = &dummy; 1080 part = &dummy;
1108 1081
1109 window = Qnil; 1082 window = Qnil;
1110 cw.window = &window, cw.x = &x, cw.y = &y; cw.part = part; 1083 cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
1111 foreach_window (f, check_window_containing, &cw); 1084 foreach_window (f, check_window_containing, &cw);
1112 1085
1113 /* If not found above, see if it's in the tool bar window, if a tool 1086 /* If not found above, see if it's in the tool bar window, if a tool
@@ -1116,16 +1089,13 @@ window_from_coordinates (struct frame *f, int x, int y, enum window_part *part,
1116 && tool_bar_p 1089 && tool_bar_p
1117 && WINDOWP (f->tool_bar_window) 1090 && WINDOWP (f->tool_bar_window)
1118 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0 1091 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0
1119 && (coordinates_in_window (XWINDOW (f->tool_bar_window), &x, &y) 1092 && (coordinates_in_window (XWINDOW (f->tool_bar_window), x, y)
1120 != ON_NOTHING)) 1093 != ON_NOTHING))
1121 { 1094 {
1122 *part = ON_TEXT; 1095 *part = ON_TEXT;
1123 window = f->tool_bar_window; 1096 window = f->tool_bar_window;
1124 } 1097 }
1125 1098
1126 if (wx) *wx = x;
1127 if (wy) *wy = y;
1128
1129 return window; 1099 return window;
1130} 1100}
1131 1101
@@ -1152,7 +1122,7 @@ column 0. */)
1152 + FRAME_INTERNAL_BORDER_WIDTH (f)), 1122 + FRAME_INTERNAL_BORDER_WIDTH (f)),
1153 (FRAME_PIXEL_Y_FROM_CANON_Y (f, y) 1123 (FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
1154 + FRAME_INTERNAL_BORDER_WIDTH (f)), 1124 + FRAME_INTERNAL_BORDER_WIDTH (f)),
1155 0, 0, 0, 0); 1125 0, 0);
1156} 1126}
1157 1127
1158DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0, 1128DEFUN ("window-point", Fwindow_point, Swindow_point, 0, 1, 0,