aboutsummaryrefslogtreecommitdiffstats
path: root/src/msdos.c
diff options
context:
space:
mode:
authorStefan Monnier2010-12-10 19:13:08 -0500
committerStefan Monnier2010-12-10 19:13:08 -0500
commit2c302df3a13236bfbf8ea1b771d13618fcda8d71 (patch)
treef26dc9f22861dc37610de319d05255de058c221b /src/msdos.c
parent0c747cb143fa227e78f350ac353d703f489209df (diff)
parent175069efeb080517afefdd44a06f7a779ea8c25c (diff)
downloademacs-2c302df3a13236bfbf8ea1b771d13618fcda8d71.tar.gz
emacs-2c302df3a13236bfbf8ea1b771d13618fcda8d71.zip
Merge from trunk
Diffstat (limited to 'src/msdos.c')
-rw-r--r--src/msdos.c699
1 files changed, 109 insertions, 590 deletions
diff --git a/src/msdos.c b/src/msdos.c
index 0957221f597..0f9a2ff29e5 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -584,14 +584,14 @@ dos_set_window_size (int *rows, int *cols)
584 if (current_rows != *rows || current_cols != *cols) 584 if (current_rows != *rows || current_cols != *cols)
585 { 585 {
586 struct frame *f = SELECTED_FRAME(); 586 struct frame *f = SELECTED_FRAME();
587 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 587 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
588 Lisp_Object window = dpyinfo->mouse_face_window; 588 Lisp_Object window = hlinfo->mouse_face_window;
589 589
590 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f) 590 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
591 { 591 {
592 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; 592 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
593 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; 593 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
594 dpyinfo->mouse_face_window = Qnil; 594 hlinfo->mouse_face_window = Qnil;
595 } 595 }
596 } 596 }
597 597
@@ -941,551 +941,79 @@ static Lisp_Object last_mouse_window;
941 941
942static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */ 942static int mouse_preempted = 0; /* non-zero when XMenu gobbles mouse events */
943 943
944/* Set the mouse pointer shape according to whether it is in the 944int
945 area where the mouse highlight is in effect. */ 945popup_activated (void)
946static void
947IT_set_mouse_pointer (int mode)
948{ 946{
949 /* A no-op for now. DOS text-mode mouse pointer doesn't offer too 947 return mouse_preempted;
950 many possibilities to change its shape, and the available
951 functionality pretty much sucks (e.g., almost every reasonable
952 shape will conceal the character it is on). Since the color of
953 the pointer changes in the highlighted area, it is not clear to
954 me whether anything else is required, anyway. */
955} 948}
956 949
957/* Display the active region described by mouse_face_* 950/* Draw TEXT_AREA glyphs between START and END of glyph row ROW on
958 in its mouse-face if HL > 0, in its normal face if HL = 0. */ 951 window W. X is relative to TEXT_AREA in W. HL is a face override
959static void 952 for drawing the glyphs. */
960show_mouse_face (struct tty_display_info *dpyinfo, int hl) 953void
954tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
955 int start_hpos, int end_hpos,
956 enum draw_glyphs_face hl)
961{ 957{
962 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
963 struct frame *f = XFRAME (WINDOW_FRAME (w)); 958 struct frame *f = XFRAME (WINDOW_FRAME (w));
964 int i;
965 struct face *fp;
966 struct tty_display_info *tty = FRAME_TTY (f); 959 struct tty_display_info *tty = FRAME_TTY (f);
960 Mouse_HLInfo *hlinfo = &tty->mouse_highlight;
967 961
968 962 if (hl == DRAW_MOUSE_FACE)
969 /* If window is in the process of being destroyed, don't bother
970 doing anything. */
971 if (w->current_matrix == NULL)
972 goto set_cursor_shape;
973
974 /* Recognize when we are called to operate on rows that don't exist
975 anymore. This can happen when a window is split. */
976 if (dpyinfo->mouse_face_end_row >= w->current_matrix->nrows)
977 goto set_cursor_shape;
978
979 /* There's no sense to do anything if the mouse face isn't realized. */
980 if (hl > 0)
981 {
982 if (dpyinfo->mouse_face_hidden)
983 goto set_cursor_shape;
984
985 fp = FACE_FROM_ID (SELECTED_FRAME(), dpyinfo->mouse_face_face_id);
986 if (!fp)
987 goto set_cursor_shape;
988 }
989
990 /* Note that mouse_face_beg_row etc. are window relative. */
991 for (i = dpyinfo->mouse_face_beg_row;
992 i <= dpyinfo->mouse_face_end_row;
993 i++)
994 {
995 int start_hpos, end_hpos;
996 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
997
998 /* Don't do anything if row doesn't have valid contents. */
999 if (!row->enabled_p)
1000 continue;
1001
1002 /* For all but the first row, the highlight starts at column 0. */
1003 if (i == dpyinfo->mouse_face_beg_row)
1004 start_hpos = dpyinfo->mouse_face_beg_col;
1005 else
1006 start_hpos = 0;
1007
1008 if (i == dpyinfo->mouse_face_end_row)
1009 end_hpos = dpyinfo->mouse_face_end_col;
1010 else
1011 end_hpos = row->used[TEXT_AREA];
1012
1013 if (end_hpos <= start_hpos)
1014 continue;
1015 /* Record that some glyphs of this row are displayed in
1016 mouse-face. */
1017 row->mouse_face_p = hl > 0;
1018 if (hl > 0)
1019 {
1020 int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
1021 int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
1022 int nglyphs = end_hpos - start_hpos;
1023 int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
1024 int start_offset = offset;
1025
1026 if (tty->termscript)
1027 fprintf (tty->termscript, "\n<MH+ %d-%d:%d>",
1028 kstart, kstart + nglyphs - 1, vpos);
1029
1030 mouse_off ();
1031 IT_set_face (dpyinfo->mouse_face_face_id);
1032 /* Since we are going to change only the _colors_ of the
1033 displayed text, there's no need to go through all the
1034 pain of generating and encoding the text from the glyphs.
1035 Instead, we simply poke the attribute byte of each
1036 affected position in video memory with the colors
1037 computed by IT_set_face! */
1038 _farsetsel (_dos_ds);
1039 while (nglyphs--)
1040 {
1041 _farnspokeb (offset, ScreenAttrib);
1042 offset += 2;
1043 }
1044 if (screen_virtual_segment)
1045 dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
1046 mouse_on ();
1047 }
1048 else
1049 {
1050 /* We are removing a previously-drawn mouse highlight. The
1051 safest way to do so is to redraw the glyphs anew, since
1052 all kinds of faces and display tables could have changed
1053 behind our back. */
1054 int nglyphs = end_hpos - start_hpos;
1055 int save_x = new_pos_X, save_y = new_pos_Y;
1056
1057 if (end_hpos >= row->used[TEXT_AREA])
1058 nglyphs = row->used[TEXT_AREA] - start_hpos;
1059
1060 /* IT_write_glyphs writes at cursor position, so we need to
1061 temporarily move cursor coordinates to the beginning of
1062 the highlight region. */
1063 new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
1064 new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
1065
1066 if (tty->termscript)
1067 fprintf (tty->termscript, "<MH- %d-%d:%d>",
1068 new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
1069 IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
1070 if (tty->termscript)
1071 fputs ("\n", tty->termscript);
1072 new_pos_X = save_x;
1073 new_pos_Y = save_y;
1074 }
1075 }
1076
1077 set_cursor_shape:
1078 /* Change the mouse pointer shape. */
1079 IT_set_mouse_pointer (hl);
1080}
1081
1082/* Clear out the mouse-highlighted active region.
1083 Redraw it un-highlighted first. */
1084static void
1085clear_mouse_face (struct tty_display_info *dpyinfo)
1086{
1087 if (!dpyinfo->mouse_face_hidden && ! NILP (dpyinfo->mouse_face_window))
1088 show_mouse_face (dpyinfo, 0);
1089
1090 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
1091 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
1092 dpyinfo->mouse_face_window = Qnil;
1093}
1094
1095/* Find the glyph matrix position of buffer position POS in window W.
1096 *HPOS and *VPOS are set to the positions found. W's current glyphs
1097 must be up to date. If POS is above window start return (0, 0).
1098 If POS is after end of W, return end of last line in W. */
1099static int
1100fast_find_position (struct window *w, int pos, int *hpos, int *vpos)
1101{
1102 int i, lastcol, line_start_position, maybe_next_line_p = 0;
1103 int yb = window_text_bottom_y (w);
1104 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
1105
1106 while (row->y < yb)
1107 {
1108 if (row->used[TEXT_AREA])
1109 line_start_position = row->glyphs[TEXT_AREA]->charpos;
1110 else
1111 line_start_position = 0;
1112
1113 if (line_start_position > pos)
1114 break;
1115 /* If the position sought is the end of the buffer,
1116 don't include the blank lines at the bottom of the window. */
1117 else if (line_start_position == pos
1118 && pos == BUF_ZV (XBUFFER (w->buffer)))
1119 {
1120 maybe_next_line_p = 1;
1121 break;
1122 }
1123 else if (line_start_position > 0)
1124 best_row = row;
1125
1126 /* Don't overstep the last matrix row, lest we get into the
1127 never-never land... */
1128 if (row->y + 1 >= yb)
1129 break;
1130
1131 ++row;
1132 }
1133
1134 /* Find the right column within BEST_ROW. */
1135 lastcol = 0;
1136 row = best_row;
1137 for (i = 0; i < row->used[TEXT_AREA]; i++)
1138 { 963 {
1139 struct glyph *glyph = row->glyphs[TEXT_AREA] + i; 964 int vpos = row->y + WINDOW_TOP_EDGE_Y (w);
1140 int charpos; 965 int kstart = start_hpos + WINDOW_LEFT_EDGE_X (w);
966 int nglyphs = end_hpos - start_hpos;
967 int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
968 int start_offset = offset;
1141 969
1142 charpos = glyph->charpos; 970 if (tty->termscript)
1143 if (charpos == pos) 971 fprintf (tty->termscript, "\n<MH+ %d-%d:%d>",
1144 { 972 kstart, kstart + nglyphs - 1, vpos);
1145 *hpos = i;
1146 *vpos = row->y;
1147 return 1;
1148 }
1149 else if (charpos > pos)
1150 break;
1151 else if (charpos > 0)
1152 lastcol = i;
1153 }
1154
1155 /* If we're looking for the end of the buffer,
1156 and we didn't find it in the line we scanned,
1157 use the start of the following line. */
1158 if (maybe_next_line_p)
1159 {
1160 ++row;
1161 lastcol = 0;
1162 }
1163
1164 *vpos = row->y;
1165 *hpos = lastcol + 1;
1166 return 0;
1167}
1168
1169/* Take proper action when mouse has moved to the mode or top line of
1170 window W, x-position X. MODE_LINE_P non-zero means mouse is on the
1171 mode line. X is relative to the start of the text display area of
1172 W, so the width of fringes and scroll bars must be subtracted
1173 to get a position relative to the start of the mode line. */
1174static void
1175IT_note_mode_line_highlight (struct window *w, int x, int mode_line_p)
1176{
1177 struct glyph_row *row;
1178
1179 if (mode_line_p)
1180 row = MATRIX_MODE_LINE_ROW (w->current_matrix);
1181 else
1182 row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
1183 973
1184 if (row->enabled_p) 974 mouse_off ();
1185 { 975 IT_set_face (hlinfo->mouse_face_face_id);
1186 struct glyph *glyph, *end; 976 /* Since we are going to change only the _colors_ of already
1187 Lisp_Object help; 977 displayed text, there's no need to go through all the pain of
1188 978 generating and encoding the text from the glyphs. Instead,
1189 /* Find the glyph under X. */ 979 we simply poke the attribute byte of each affected position
1190 glyph = (row->glyphs[TEXT_AREA] 980 in video memory with the colors computed by IT_set_face! */
1191 + x 981 _farsetsel (_dos_ds);
1192 /* in case someone implements scroll bars some day... */ 982 while (nglyphs--)
1193 - WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w));
1194 end = glyph + row->used[TEXT_AREA];
1195 if (glyph < end
1196 && STRINGP (glyph->object)
1197 && STRING_INTERVALS (glyph->object)
1198 && glyph->charpos >= 0
1199 && glyph->charpos < SCHARS (glyph->object))
1200 { 983 {
1201 /* If we're on a string with `help-echo' text property, 984 _farnspokeb (offset, ScreenAttrib);
1202 arrange for the help to be displayed. This is done by 985 offset += 2;
1203 setting the global variable help_echo to the help string. */
1204 help = Fget_text_property (make_number (glyph->charpos),
1205 Qhelp_echo, glyph->object);
1206 if (!NILP (help))
1207 {
1208 help_echo_string = help;
1209 XSETWINDOW (help_echo_window, w);
1210 help_echo_object = glyph->object;
1211 help_echo_pos = glyph->charpos;
1212 }
1213 } 986 }
987 if (screen_virtual_segment)
988 dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
989 mouse_on ();
1214 } 990 }
1215} 991 else if (hl == DRAW_NORMAL_TEXT)
1216
1217/* Take proper action when the mouse has moved to position X, Y on
1218 frame F as regards highlighting characters that have mouse-face
1219 properties. Also de-highlighting chars where the mouse was before.
1220 X and Y can be negative or out of range. */
1221static void
1222IT_note_mouse_highlight (struct frame *f, int x, int y)
1223{
1224 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
1225 enum window_part part = ON_NOTHING;
1226 Lisp_Object window;
1227 struct window *w;
1228
1229 /* When a menu is active, don't highlight because this looks odd. */
1230 if (mouse_preempted)
1231 return;
1232
1233 if (NILP (Vmouse_highlight)
1234 || !f->glyphs_initialized_p)
1235 return;
1236
1237 dpyinfo->mouse_face_mouse_x = x;
1238 dpyinfo->mouse_face_mouse_y = y;
1239 dpyinfo->mouse_face_mouse_frame = f;
1240
1241 if (dpyinfo->mouse_face_defer)
1242 return;
1243
1244 if (gc_in_progress)
1245 {
1246 dpyinfo->mouse_face_deferred_gc = 1;
1247 return;
1248 }
1249
1250 /* Which window is that in? */
1251 window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
1252
1253 /* If we were displaying active text in another window, clear that. */
1254 if (! EQ (window, dpyinfo->mouse_face_window))
1255 clear_mouse_face (dpyinfo);
1256
1257 /* Not on a window -> return. */
1258 if (!WINDOWP (window))
1259 return;
1260
1261 /* Convert to window-relative coordinates. */
1262 w = XWINDOW (window);
1263
1264 if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
1265 {
1266 /* Mouse is on the mode or top line. */
1267 IT_note_mode_line_highlight (w, x, part == ON_MODE_LINE);
1268 return;
1269 }
1270
1271 IT_set_mouse_pointer (0);
1272
1273 /* Are we in a window whose display is up to date?
1274 And verify the buffer's text has not changed. */
1275 if (part == ON_TEXT
1276 && EQ (w->window_end_valid, w->buffer)
1277 && XFASTINT (w->last_modified) == BUF_MODIFF (XBUFFER (w->buffer))
1278 && (XFASTINT (w->last_overlay_modified)
1279 == BUF_OVERLAY_MODIFF (XBUFFER (w->buffer))))
1280 { 992 {
1281 int pos, i, nrows = w->current_matrix->nrows; 993 /* We are removing a previously-drawn mouse highlight. The
1282 struct glyph_row *row; 994 safest way to do so is to redraw the glyphs anew, since all
1283 struct glyph *glyph; 995 kinds of faces and display tables could have changed behind
1284 996 our back. */
1285 /* Find the glyph under X/Y. */ 997 int nglyphs = end_hpos - start_hpos;
1286 glyph = NULL; 998 int save_x = new_pos_X, save_y = new_pos_Y;
1287 if (y >= 0 && y < nrows) 999
1288 { 1000 if (end_hpos >= row->used[TEXT_AREA])
1289 row = MATRIX_ROW (w->current_matrix, y); 1001 nglyphs = row->used[TEXT_AREA] - start_hpos;
1290 /* Give up if some row before the one we are looking for is 1002
1291 not enabled. */ 1003 /* IT_write_glyphs writes at cursor position, so we need to
1292 for (i = 0; i <= y; i++) 1004 temporarily move cursor coordinates to the beginning of
1293 if (!MATRIX_ROW (w->current_matrix, i)->enabled_p) 1005 the highlight region. */
1294 break; 1006 new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
1295 if (i > y /* all rows upto and including the one at Y are enabled */ 1007 new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
1296 && row->displays_text_p
1297 && x < window_box_width (w, TEXT_AREA))
1298 {
1299 glyph = row->glyphs[TEXT_AREA];
1300 if (x >= row->used[TEXT_AREA])
1301 glyph = NULL;
1302 else
1303 {
1304 glyph += x;
1305 if (!BUFFERP (glyph->object))
1306 glyph = NULL;
1307 }
1308 }
1309 }
1310 1008
1311 /* Clear mouse face if X/Y not over text. */ 1009 if (tty->termscript)
1312 if (glyph == NULL) 1010 fprintf (tty->termscript, "<MH- %d-%d:%d>",
1313 { 1011 new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y);
1314 clear_mouse_face (dpyinfo); 1012 IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
1315 return; 1013 if (tty->termscript)
1316 } 1014 fputs ("\n", tty->termscript);
1317 1015 new_pos_X = save_x;
1318 if (!BUFFERP (glyph->object)) 1016 new_pos_Y = save_y;
1319 abort ();
1320 pos = glyph->charpos;
1321
1322 /* Check for mouse-face and help-echo. */
1323 {
1324 Lisp_Object mouse_face, overlay, position, *overlay_vec;
1325 int noverlays, obegv, ozv;
1326 struct buffer *obuf;
1327
1328 /* If we get an out-of-range value, return now; avoid an error. */
1329 if (pos > BUF_Z (XBUFFER (w->buffer)))
1330 return;
1331
1332 /* Make the window's buffer temporarily current for
1333 overlays_at and compute_char_face. */
1334 obuf = current_buffer;
1335 current_buffer = XBUFFER (w->buffer);
1336 obegv = BEGV;
1337 ozv = ZV;
1338 BEGV = BEG;
1339 ZV = Z;
1340
1341 /* Is this char mouse-active or does it have help-echo? */
1342 XSETINT (position, pos);
1343
1344 /* Put all the overlays we want in a vector in overlay_vec. */
1345 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
1346 /* Sort overlays into increasing priority order. */
1347 noverlays = sort_overlays (overlay_vec, noverlays, w);
1348
1349 /* Check mouse-face highlighting. */
1350 if (! (EQ (window, dpyinfo->mouse_face_window)
1351 && y >= dpyinfo->mouse_face_beg_row
1352 && y <= dpyinfo->mouse_face_end_row
1353 && (y > dpyinfo->mouse_face_beg_row
1354 || x >= dpyinfo->mouse_face_beg_col)
1355 && (y < dpyinfo->mouse_face_end_row
1356 || x < dpyinfo->mouse_face_end_col
1357 || dpyinfo->mouse_face_past_end)))
1358 {
1359 /* Clear the display of the old active region, if any. */
1360 clear_mouse_face (dpyinfo);
1361
1362 /* Find highest priority overlay that has a mouse-face prop. */
1363 overlay = Qnil;
1364 for (i = noverlays - 1; i >= 0; --i)
1365 {
1366 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
1367 if (!NILP (mouse_face))
1368 {
1369 overlay = overlay_vec[i];
1370 break;
1371 }
1372 }
1373
1374 /* If no overlay applies, get a text property. */
1375 if (NILP (overlay))
1376 mouse_face = Fget_text_property (position, Qmouse_face,
1377 w->buffer);
1378
1379 /* Handle the overlay case. */
1380 if (! NILP (overlay))
1381 {
1382 /* Find the range of text around this char that
1383 should be active. */
1384 Lisp_Object before, after;
1385 EMACS_INT ignore;
1386
1387 before = Foverlay_start (overlay);
1388 after = Foverlay_end (overlay);
1389 /* Record this as the current active region. */
1390 fast_find_position (w, XFASTINT (before),
1391 &dpyinfo->mouse_face_beg_col,
1392 &dpyinfo->mouse_face_beg_row);
1393 dpyinfo->mouse_face_past_end
1394 = !fast_find_position (w, XFASTINT (after),
1395 &dpyinfo->mouse_face_end_col,
1396 &dpyinfo->mouse_face_end_row);
1397 dpyinfo->mouse_face_window = window;
1398 dpyinfo->mouse_face_face_id
1399 = face_at_buffer_position (w, pos, 0, 0,
1400 &ignore, pos + 1,
1401 !dpyinfo->mouse_face_hidden,
1402 -1);
1403
1404 /* Display it as active. */
1405 show_mouse_face (dpyinfo, 1);
1406 }
1407 /* Handle the text property case. */
1408 else if (! NILP (mouse_face))
1409 {
1410 /* Find the range of text around this char that
1411 should be active. */
1412 Lisp_Object before, after, beginning, end;
1413 EMACS_INT ignore;
1414
1415 beginning = Fmarker_position (w->start);
1416 XSETINT (end, (BUF_Z (XBUFFER (w->buffer))
1417 - XFASTINT (w->window_end_pos)));
1418 before
1419 = Fprevious_single_property_change (make_number (pos + 1),
1420 Qmouse_face,
1421 w->buffer, beginning);
1422 after
1423 = Fnext_single_property_change (position, Qmouse_face,
1424 w->buffer, end);
1425 /* Record this as the current active region. */
1426 fast_find_position (w, XFASTINT (before),
1427 &dpyinfo->mouse_face_beg_col,
1428 &dpyinfo->mouse_face_beg_row);
1429 dpyinfo->mouse_face_past_end
1430 = !fast_find_position (w, XFASTINT (after),
1431 &dpyinfo->mouse_face_end_col,
1432 &dpyinfo->mouse_face_end_row);
1433 dpyinfo->mouse_face_window = window;
1434 dpyinfo->mouse_face_face_id
1435 = face_at_buffer_position (w, pos, 0, 0,
1436 &ignore, pos + 1,
1437 !dpyinfo->mouse_face_hidden,
1438 -1);
1439
1440 /* Display it as active. */
1441 show_mouse_face (dpyinfo, 1);
1442 }
1443 }
1444
1445 /* Look for a `help-echo' property. */
1446 {
1447 Lisp_Object help;
1448
1449 /* Check overlays first. */
1450 help = Qnil;
1451 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
1452 {
1453 overlay = overlay_vec[i];
1454 help = Foverlay_get (overlay, Qhelp_echo);
1455 }
1456
1457 if (!NILP (help))
1458 {
1459 help_echo_string = help;
1460 help_echo_window = window;
1461 help_echo_object = overlay;
1462 help_echo_pos = pos;
1463 }
1464 /* Try text properties. */
1465 else if (NILP (help)
1466 && ((STRINGP (glyph->object)
1467 && glyph->charpos >= 0
1468 && glyph->charpos < SCHARS (glyph->object))
1469 || (BUFFERP (glyph->object)
1470 && glyph->charpos >= BEGV
1471 && glyph->charpos < ZV)))
1472 {
1473 help = Fget_text_property (make_number (glyph->charpos),
1474 Qhelp_echo, glyph->object);
1475 if (!NILP (help))
1476 {
1477 help_echo_string = help;
1478 help_echo_window = window;
1479 help_echo_object = glyph->object;
1480 help_echo_pos = glyph->charpos;
1481 }
1482 }
1483 }
1484
1485 BEGV = obegv;
1486 ZV = ozv;
1487 current_buffer = obuf;
1488 }
1489 } 1017 }
1490} 1018}
1491 1019
@@ -1689,7 +1217,8 @@ static void
1689IT_update_begin (struct frame *f) 1217IT_update_begin (struct frame *f)
1690{ 1218{
1691 struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f); 1219 struct tty_display_info *display_info = FRAME_X_DISPLAY_INFO (f);
1692 struct frame *mouse_face_frame = display_info->mouse_face_mouse_frame; 1220 Mouse_HLInfo *hlinfo = &display_info->mouse_highlight;
1221 struct frame *mouse_face_frame = hlinfo->mouse_face_mouse_frame;
1693 1222
1694 if (display_info->termscript) 1223 if (display_info->termscript)
1695 fprintf (display_info->termscript, "\n\n<UPDATE_BEGIN"); 1224 fprintf (display_info->termscript, "\n\n<UPDATE_BEGIN");
@@ -1699,28 +1228,28 @@ IT_update_begin (struct frame *f)
1699 if (f && f == mouse_face_frame) 1228 if (f && f == mouse_face_frame)
1700 { 1229 {
1701 /* Don't do highlighting for mouse motion during the update. */ 1230 /* Don't do highlighting for mouse motion during the update. */
1702 display_info->mouse_face_defer = 1; 1231 hlinfo->mouse_face_defer = 1;
1703 1232
1704 /* If F needs to be redrawn, simply forget about any prior mouse 1233 /* If F needs to be redrawn, simply forget about any prior mouse
1705 highlighting. */ 1234 highlighting. */
1706 if (FRAME_GARBAGED_P (f)) 1235 if (FRAME_GARBAGED_P (f))
1707 display_info->mouse_face_window = Qnil; 1236 hlinfo->mouse_face_window = Qnil;
1708 1237
1709 /* Can we tell that this update does not affect the window 1238 /* Can we tell that this update does not affect the window
1710 where the mouse highlight is? If so, no need to turn off. 1239 where the mouse highlight is? If so, no need to turn off.
1711 Likewise, don't do anything if none of the enabled rows 1240 Likewise, don't do anything if none of the enabled rows
1712 contains glyphs highlighted in mouse face. */ 1241 contains glyphs highlighted in mouse face. */
1713 if (!NILP (display_info->mouse_face_window) 1242 if (!NILP (hlinfo->mouse_face_window)
1714 && WINDOWP (display_info->mouse_face_window)) 1243 && WINDOWP (hlinfo->mouse_face_window))
1715 { 1244 {
1716 struct window *w = XWINDOW (display_info->mouse_face_window); 1245 struct window *w = XWINDOW (hlinfo->mouse_face_window);
1717 int i; 1246 int i;
1718 1247
1719 /* If the mouse highlight is in the window that was deleted 1248 /* If the mouse highlight is in the window that was deleted
1720 (e.g., if it was popped by completion), clear highlight 1249 (e.g., if it was popped by completion), clear highlight
1721 unconditionally. */ 1250 unconditionally. */
1722 if (NILP (w->buffer)) 1251 if (NILP (w->buffer))
1723 display_info->mouse_face_window = Qnil; 1252 hlinfo->mouse_face_window = Qnil;
1724 else 1253 else
1725 { 1254 {
1726 for (i = 0; i < w->desired_matrix->nrows; ++i) 1255 for (i = 0; i < w->desired_matrix->nrows; ++i)
@@ -1730,18 +1259,18 @@ IT_update_begin (struct frame *f)
1730 } 1259 }
1731 1260
1732 if (NILP (w->buffer) || i < w->desired_matrix->nrows) 1261 if (NILP (w->buffer) || i < w->desired_matrix->nrows)
1733 clear_mouse_face (display_info); 1262 clear_mouse_face (hlinfo);
1734 } 1263 }
1735 } 1264 }
1736 else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame)) 1265 else if (mouse_face_frame && !FRAME_LIVE_P (mouse_face_frame))
1737 { 1266 {
1738 /* If the frame with mouse highlight was deleted, invalidate the 1267 /* If the frame with mouse highlight was deleted, invalidate the
1739 highlight info. */ 1268 highlight info. */
1740 display_info->mouse_face_beg_row = display_info->mouse_face_beg_col = -1; 1269 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
1741 display_info->mouse_face_end_row = display_info->mouse_face_end_col = -1; 1270 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
1742 display_info->mouse_face_window = Qnil; 1271 hlinfo->mouse_face_window = Qnil;
1743 display_info->mouse_face_deferred_gc = 0; 1272 hlinfo->mouse_face_deferred_gc = 0;
1744 display_info->mouse_face_mouse_frame = NULL; 1273 hlinfo->mouse_face_mouse_frame = NULL;
1745 } 1274 }
1746 1275
1747 UNBLOCK_INPUT; 1276 UNBLOCK_INPUT;
@@ -1754,25 +1283,25 @@ IT_update_end (struct frame *f)
1754 1283
1755 if (dpyinfo->termscript) 1284 if (dpyinfo->termscript)
1756 fprintf (dpyinfo->termscript, "\n<UPDATE_END\n"); 1285 fprintf (dpyinfo->termscript, "\n<UPDATE_END\n");
1757 dpyinfo->mouse_face_defer = 0; 1286 dpyinfo->mouse_highlight.mouse_face_defer = 0;
1758} 1287}
1759 1288
1760static void 1289static void
1761IT_frame_up_to_date (struct frame *f) 1290IT_frame_up_to_date (struct frame *f)
1762{ 1291{
1763 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); 1292 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
1764 Lisp_Object new_cursor, frame_desired_cursor; 1293 Lisp_Object new_cursor, frame_desired_cursor;
1765 struct window *sw; 1294 struct window *sw;
1766 1295
1767 if (dpyinfo->mouse_face_deferred_gc 1296 if (hlinfo->mouse_face_deferred_gc
1768 || (f && f == dpyinfo->mouse_face_mouse_frame)) 1297 || (f && f == hlinfo->mouse_face_mouse_frame))
1769 { 1298 {
1770 BLOCK_INPUT; 1299 BLOCK_INPUT;
1771 if (dpyinfo->mouse_face_mouse_frame) 1300 if (hlinfo->mouse_face_mouse_frame)
1772 IT_note_mouse_highlight (dpyinfo->mouse_face_mouse_frame, 1301 note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
1773 dpyinfo->mouse_face_mouse_x, 1302 hlinfo->mouse_face_mouse_x,
1774 dpyinfo->mouse_face_mouse_y); 1303 hlinfo->mouse_face_mouse_y);
1775 dpyinfo->mouse_face_deferred_gc = 0; 1304 hlinfo->mouse_face_deferred_gc = 0;
1776 UNBLOCK_INPUT; 1305 UNBLOCK_INPUT;
1777 } 1306 }
1778 1307
@@ -2317,18 +1846,18 @@ internal_terminal_init (void)
2317 if (colors[1] >= 0 && colors[1] < 16) 1846 if (colors[1] >= 0 && colors[1] < 16)
2318 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1]; 1847 FRAME_BACKGROUND_PIXEL (SELECTED_FRAME ()) = colors[1];
2319 } 1848 }
2320 the_only_display_info.mouse_face_mouse_frame = NULL; 1849 the_only_display_info.mouse_highlight.mouse_face_mouse_frame = NULL;
2321 the_only_display_info.mouse_face_deferred_gc = 0; 1850 the_only_display_info.mouse_highlight.mouse_face_deferred_gc = 0;
2322 the_only_display_info.mouse_face_beg_row = 1851 the_only_display_info.mouse_highlight.mouse_face_beg_row =
2323 the_only_display_info.mouse_face_beg_col = -1; 1852 the_only_display_info.mouse_highlight.mouse_face_beg_col = -1;
2324 the_only_display_info.mouse_face_end_row = 1853 the_only_display_info.mouse_highlight.mouse_face_end_row =
2325 the_only_display_info.mouse_face_end_col = -1; 1854 the_only_display_info.mouse_highlight.mouse_face_end_col = -1;
2326 the_only_display_info.mouse_face_face_id = DEFAULT_FACE_ID; 1855 the_only_display_info.mouse_highlight.mouse_face_face_id = DEFAULT_FACE_ID;
2327 the_only_display_info.mouse_face_window = Qnil; 1856 the_only_display_info.mouse_highlight.mouse_face_window = Qnil;
2328 the_only_display_info.mouse_face_mouse_x = 1857 the_only_display_info.mouse_highlight.mouse_face_mouse_x =
2329 the_only_display_info.mouse_face_mouse_y = 0; 1858 the_only_display_info.mouse_highlight.mouse_face_mouse_y = 0;
2330 the_only_display_info.mouse_face_defer = 0; 1859 the_only_display_info.mouse_highlight.mouse_face_defer = 0;
2331 the_only_display_info.mouse_face_hidden = 0; 1860 the_only_display_info.mouse_highlight.mouse_face_hidden = 0;
2332 1861
2333 if (have_mouse) /* detected in dos_ttraw, which see */ 1862 if (have_mouse) /* detected in dos_ttraw, which see */
2334 { 1863 {
@@ -2916,7 +2445,7 @@ dos_rawgetc (void)
2916{ 2445{
2917 struct input_event event; 2446 struct input_event event;
2918 union REGS regs; 2447 union REGS regs;
2919 struct tty_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (SELECTED_FRAME()); 2448 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (SELECTED_FRAME());
2920 EVENT_INIT (event); 2449 EVENT_INIT (event);
2921 2450
2922#ifndef HAVE_X_WINDOWS 2451#ifndef HAVE_X_WINDOWS
@@ -3126,10 +2655,10 @@ dos_rawgetc (void)
3126 if (code == 0) 2655 if (code == 0)
3127 continue; 2656 continue;
3128 2657
3129 if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) 2658 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
3130 { 2659 {
3131 clear_mouse_face (dpyinfo); 2660 clear_mouse_face (hlinfo);
3132 dpyinfo->mouse_face_hidden = 1; 2661 hlinfo->mouse_face_hidden = 1;
3133 } 2662 }
3134 2663
3135 if (code >= 0x100) 2664 if (code >= 0x100)
@@ -3157,10 +2686,10 @@ dos_rawgetc (void)
3157 might need to update mouse highlight. */ 2686 might need to update mouse highlight. */
3158 if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y) 2687 if (mouse_last_x != mouse_prev_x || mouse_last_y != mouse_prev_y)
3159 { 2688 {
3160 if (dpyinfo->mouse_face_hidden) 2689 if (hlinfo->mouse_face_hidden)
3161 { 2690 {
3162 dpyinfo->mouse_face_hidden = 0; 2691 hlinfo->mouse_face_hidden = 0;
3163 clear_mouse_face (dpyinfo); 2692 clear_mouse_face (hlinfo);
3164 } 2693 }
3165 2694
3166 /* Generate SELECT_WINDOW_EVENTs when needed. */ 2695 /* Generate SELECT_WINDOW_EVENTs when needed. */
@@ -3169,7 +2698,7 @@ dos_rawgetc (void)
3169 mouse_window = window_from_coordinates (SELECTED_FRAME(), 2698 mouse_window = window_from_coordinates (SELECTED_FRAME(),
3170 mouse_last_x, 2699 mouse_last_x,
3171 mouse_last_y, 2700 mouse_last_y,
3172 0, 0, 0, 0); 2701 0, 0);
3173 /* A window will be selected only when it is not 2702 /* A window will be selected only when it is not
3174 selected now, and the last mouse movement event was 2703 selected now, and the last mouse movement event was
3175 not in it. A minibuffer window will be selected iff 2704 not in it. A minibuffer window will be selected iff
@@ -3192,22 +2721,12 @@ dos_rawgetc (void)
3192 previous_help_echo_string = help_echo_string; 2721 previous_help_echo_string = help_echo_string;
3193 help_echo_string = help_echo_object = help_echo_window = Qnil; 2722 help_echo_string = help_echo_object = help_echo_window = Qnil;
3194 help_echo_pos = -1; 2723 help_echo_pos = -1;
3195 IT_note_mouse_highlight (SELECTED_FRAME(), 2724 note_mouse_highlight (SELECTED_FRAME(), mouse_last_x, mouse_last_y);
3196 mouse_last_x, mouse_last_y);
3197 /* If the contents of the global variable help_echo has 2725 /* If the contents of the global variable help_echo has
3198 changed, generate a HELP_EVENT. */ 2726 changed, generate a HELP_EVENT. */
3199 if (!NILP (help_echo_string) || !NILP (previous_help_echo_string)) 2727 if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
3200 { 2728 gen_help_event (help_echo_string, selected_frame, help_echo_window,
3201 event.kind = HELP_EVENT; 2729 help_echo_object, help_echo_pos);
3202 event.frame_or_window = selected_frame;
3203 event.arg = help_echo_object;
3204 event.x = WINDOWP (help_echo_window)
3205 ? help_echo_window : selected_frame;
3206 event.y = help_echo_string;
3207 event.timestamp = event_timestamp ();
3208 event.code = help_echo_pos;
3209 kbd_buffer_store_event (&event);
3210 }
3211 } 2730 }
3212 2731
3213 for (but = 0; but < NUM_MOUSE_BUTTONS; but++) 2732 for (but = 0; but < NUM_MOUSE_BUTTONS; but++)