diff options
| author | Eli Zaretskii | 2025-02-03 18:36:11 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2025-02-03 18:36:11 +0200 |
| commit | a22e971a119dfd1385fe38d6f594bccfe8911152 (patch) | |
| tree | 3758c4be0c110b17950bf3b2be3f394703ac6867 | |
| parent | 1639ad2814ae100c9f878a1388eb9ffc9d208b07 (diff) | |
| download | emacs-a22e971a119dfd1385fe38d6f594bccfe8911152.tar.gz emacs-a22e971a119dfd1385fe38d6f594bccfe8911152.zip | |
Fix -nw sessions on MS-Windows
* src/w32console.c (w32con_clear_end_of_line): Set the space
glyphs' frame to NULL.
(w32con_write_glyphs): Handle face_id_frame == NULL, when called
from 'w32con_clear_end_of_line'.
(tty_draw_row_with_mouse_face): Adjust to changes in term.c.
| -rw-r--r-- | src/w32console.c | 104 |
1 files changed, 80 insertions, 24 deletions
diff --git a/src/w32console.c b/src/w32console.c index 9cfedde3b3f..b18eda437ad 100644 --- a/src/w32console.c +++ b/src/w32console.c | |||
| @@ -167,7 +167,7 @@ w32con_clear_end_of_line (struct frame *f, int end) | |||
| 167 | for (i = 0; i < glyphs_len; i++) | 167 | for (i = 0; i < glyphs_len; i++) |
| 168 | { | 168 | { |
| 169 | memcpy (&glyphs[i], &space_glyph, sizeof (struct glyph)); | 169 | memcpy (&glyphs[i], &space_glyph, sizeof (struct glyph)); |
| 170 | glyphs[i].frame = f; | 170 | glyphs[i].frame = NULL; |
| 171 | } | 171 | } |
| 172 | ceol_initialized = TRUE; | 172 | ceol_initialized = TRUE; |
| 173 | } | 173 | } |
| @@ -339,8 +339,10 @@ w32con_write_glyphs (struct frame *f, register struct glyph *string, | |||
| 339 | && string[n].frame == face_id_frame)) | 339 | && string[n].frame == face_id_frame)) |
| 340 | break; | 340 | break; |
| 341 | 341 | ||
| 342 | /* w32con_clear_end_of_line sets frame of glyphs to NULL. */ | ||
| 343 | struct frame *attr_frame = face_id_frame ? face_id_frame : f; | ||
| 342 | /* Turn appearance modes of the face of the run on. */ | 344 | /* Turn appearance modes of the face of the run on. */ |
| 343 | char_attr = w32_face_attributes (face_id_frame, face_id); | 345 | char_attr = w32_face_attributes (attr_frame, face_id); |
| 344 | 346 | ||
| 345 | if (n == len) | 347 | if (n == len) |
| 346 | /* This is the last run. */ | 348 | /* This is the last run. */ |
| @@ -425,34 +427,88 @@ w32con_write_glyphs_with_face (struct frame *f, register int x, register int y, | |||
| 425 | 427 | ||
| 426 | /* Implementation of draw_row_with_mouse_face for W32 console. */ | 428 | /* Implementation of draw_row_with_mouse_face for W32 console. */ |
| 427 | void | 429 | void |
| 428 | tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, | 430 | tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *window_row, |
| 429 | int start_hpos, int end_hpos, | 431 | int window_start_x, int window_end_x, |
| 430 | enum draw_glyphs_face draw) | 432 | enum draw_glyphs_face draw) |
| 431 | { | 433 | { |
| 432 | int nglyphs = end_hpos - start_hpos; | ||
| 433 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | 434 | struct frame *f = XFRAME (WINDOW_FRAME (w)); |
| 434 | struct tty_display_info *tty = FRAME_TTY (f); | 435 | struct frame *root = root_frame (f); |
| 435 | int face_id = tty->mouse_highlight.mouse_face_face_id; | 436 | |
| 436 | int pos_x, pos_y; | 437 | /* Window coordinates are relative to the text area. Make |
| 437 | 438 | them relative to the window's left edge, */ | |
| 438 | if (end_hpos >= row->used[TEXT_AREA]) | 439 | window_end_x = min (window_end_x, window_row->used[TEXT_AREA]); |
| 439 | nglyphs = row->used[TEXT_AREA] - start_hpos; | 440 | window_start_x += window_row->used[LEFT_MARGIN_AREA]; |
| 440 | 441 | window_end_x += window_row->used[LEFT_MARGIN_AREA]; | |
| 441 | pos_y = row->y + WINDOW_TOP_EDGE_Y (w); | 442 | |
| 442 | pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); | 443 | /* Translate from window to window's frame. */ |
| 443 | 444 | int frame_start_x = WINDOW_LEFT_EDGE_X (w) + window_start_x; | |
| 444 | if (draw == DRAW_MOUSE_FACE) | 445 | int frame_end_x = WINDOW_LEFT_EDGE_X (w) + window_end_x; |
| 445 | w32con_write_glyphs_with_face (f, pos_x, pos_y, | 446 | int frame_y = window_row->y + WINDOW_TOP_EDGE_Y (w); |
| 446 | row->glyphs[TEXT_AREA] + start_hpos, | 447 | |
| 447 | nglyphs, face_id); | 448 | /* Translate from (possible) child frame to root frame. */ |
| 448 | else if (draw == DRAW_NORMAL_TEXT) | 449 | int root_start_x, root_end_x, root_y; |
| 450 | root_xy (f, frame_start_x, frame_y, &root_start_x, &root_y); | ||
| 451 | root_xy (f, frame_end_x, frame_y, &root_end_x, &root_y); | ||
| 452 | struct glyph_row *root_row = MATRIX_ROW (root->current_matrix, root_y); | ||
| 453 | |||
| 454 | /* Remember current cursor coordinates so that we can restore | ||
| 455 | them at the end. */ | ||
| 456 | COORD save_coords = cursor_coords; | ||
| 457 | |||
| 458 | /* If the root frame displays child frames, we cannot naively | ||
| 459 | write to the terminal what the window thinks should be drawn. | ||
| 460 | Instead, write only those parts that are not obscured by | ||
| 461 | other frames. */ | ||
| 462 | for (int root_x = root_start_x; root_x < root_end_x; ) | ||
| 449 | { | 463 | { |
| 450 | COORD save_coords = cursor_coords; | 464 | /* Find the start of a run of glyphs from frame F. */ |
| 465 | struct glyph *root_start = root_row->glyphs[TEXT_AREA] + root_x; | ||
| 466 | while (root_x < root_end_x && root_start->frame != f) | ||
| 467 | ++root_x, ++root_start; | ||
| 468 | |||
| 469 | /* If start of a run of glyphs from F found. */ | ||
| 470 | int root_run_start_x = root_x; | ||
| 471 | if (root_run_start_x < root_end_x) | ||
| 472 | { | ||
| 473 | /* Find the end of the run of glyphs from frame F. */ | ||
| 474 | struct glyph *root_end = root_start; | ||
| 475 | while (root_x < root_end_x && root_end->frame == f) | ||
| 476 | ++root_x, ++root_end; | ||
| 451 | 477 | ||
| 452 | w32con_move_cursor (f, pos_y, pos_x); | 478 | /* If we have a run glyphs to output, do it. */ |
| 453 | write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); | 479 | if (root_end > root_start) |
| 454 | w32con_move_cursor (f, save_coords.Y, save_coords.X); | 480 | { |
| 481 | w32con_move_cursor (root, root_y, root_run_start_x); | ||
| 482 | |||
| 483 | ptrdiff_t nglyphs = root_end - root_start; | ||
| 484 | switch (draw) | ||
| 485 | { | ||
| 486 | case DRAW_NORMAL_TEXT: | ||
| 487 | write_glyphs (f, root_start, nglyphs); | ||
| 488 | break; | ||
| 489 | |||
| 490 | case DRAW_MOUSE_FACE: | ||
| 491 | { | ||
| 492 | struct tty_display_info *tty = FRAME_TTY (f); | ||
| 493 | int face_id = tty->mouse_highlight.mouse_face_face_id; | ||
| 494 | w32con_write_glyphs_with_face (f, root_run_start_x, root_y, | ||
| 495 | root_start, nglyphs, | ||
| 496 | face_id); | ||
| 497 | } | ||
| 498 | break; | ||
| 499 | |||
| 500 | case DRAW_INVERSE_VIDEO: | ||
| 501 | case DRAW_CURSOR: | ||
| 502 | case DRAW_IMAGE_RAISED: | ||
| 503 | case DRAW_IMAGE_SUNKEN: | ||
| 504 | emacs_abort (); | ||
| 505 | } | ||
| 506 | } | ||
| 507 | } | ||
| 455 | } | 508 | } |
| 509 | |||
| 510 | /* Restore cursor where it was before. */ | ||
| 511 | w32con_move_cursor (f, save_coords.Y, save_coords.X); | ||
| 456 | } | 512 | } |
| 457 | 513 | ||
| 458 | static void | 514 | static void |