Mercurial > emacs
comparison src/xterm.c @ 47942:080b4586492b
Fix typo in comment.
author | Juanma Barranquero <lekktu@gmail.com> |
---|---|
date | Fri, 18 Oct 2002 10:09:43 +0000 |
parents | 76b2ec66665d |
children | 5dcac67745dc |
comparison
equal
deleted
inserted
replaced
47941:df5fb1f2c113 | 47942:080b4586492b |
---|---|
236 | 236 |
237 Lisp_Object Vx_toolkit_scroll_bars; | 237 Lisp_Object Vx_toolkit_scroll_bars; |
238 | 238 |
239 /* If a string, XTread_socket generates an event to display that string. | 239 /* If a string, XTread_socket generates an event to display that string. |
240 (The display is done in read_char.) */ | 240 (The display is done in read_char.) */ |
241 | 241 |
242 static Lisp_Object help_echo; | 242 static Lisp_Object help_echo; |
243 static Lisp_Object help_echo_window; | 243 static Lisp_Object help_echo_window; |
244 static Lisp_Object help_echo_object; | 244 static Lisp_Object help_echo_object; |
245 static int help_echo_pos; | 245 static int help_echo_pos; |
246 | 246 |
297 /* The application context for Xt use. */ | 297 /* The application context for Xt use. */ |
298 XtAppContext Xt_app_con; | 298 XtAppContext Xt_app_con; |
299 static String Xt_default_resources[] = {0}; | 299 static String Xt_default_resources[] = {0}; |
300 #endif /* USE_X_TOOLKIT */ | 300 #endif /* USE_X_TOOLKIT */ |
301 | 301 |
302 /* Nominal cursor position -- where to draw output. | 302 /* Nominal cursor position -- where to draw output. |
303 HPOS and VPOS are window relative glyph matrix coordinates. | 303 HPOS and VPOS are window relative glyph matrix coordinates. |
304 X and Y are window relative pixel coordinates. */ | 304 X and Y are window relative pixel coordinates. */ |
305 | 305 |
306 struct cursor_pos output_cursor; | 306 struct cursor_pos output_cursor; |
307 | 307 |
494 XRectangle *)); | 494 XRectangle *)); |
495 static void x_update_cursor_in_window_tree P_ ((struct window *, int)); | 495 static void x_update_cursor_in_window_tree P_ ((struct window *, int)); |
496 static void x_update_window_cursor P_ ((struct window *, int)); | 496 static void x_update_window_cursor P_ ((struct window *, int)); |
497 static void x_erase_phys_cursor P_ ((struct window *)); | 497 static void x_erase_phys_cursor P_ ((struct window *)); |
498 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | 498 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); |
499 static void x_draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, | 499 static void x_draw_fringe_bitmap P_ ((struct window *, struct glyph_row *, |
500 enum fringe_bitmap_type, int left_p)); | 500 enum fringe_bitmap_type, int left_p)); |
501 | 501 |
502 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, | 502 static void x_clip_to_row P_ ((struct window *, struct glyph_row *, |
503 GC, int)); | 503 GC, int)); |
504 static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *)); | 504 static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *)); |
544 is flushed automatically as needed by calls to XPending, | 544 is flushed automatically as needed by calls to XPending, |
545 XNextEvent, or XWindowEvent according to the XFlush man page. | 545 XNextEvent, or XWindowEvent according to the XFlush man page. |
546 XTread_socket calls XPending. Removing XFlush improves | 546 XTread_socket calls XPending. Removing XFlush improves |
547 performance. */ | 547 performance. */ |
548 | 548 |
549 #define XFlush(DISPLAY) (void) 0 | 549 #define XFlush(DISPLAY) (void) 0 |
550 | 550 |
551 | 551 |
552 /*********************************************************************** | 552 /*********************************************************************** |
553 Debugging | 553 Debugging |
554 ***********************************************************************/ | 554 ***********************************************************************/ |
556 #if 0 | 556 #if 0 |
557 | 557 |
558 /* This is a function useful for recording debugging information about | 558 /* This is a function useful for recording debugging information about |
559 the sequence of occurrences in this file. */ | 559 the sequence of occurrences in this file. */ |
560 | 560 |
561 struct record | 561 struct record |
562 { | 562 { |
563 char *locus; | 563 char *locus; |
564 int type; | 564 int type; |
565 }; | 565 }; |
566 | 566 |
602 | 602 |
603 | 603 |
604 /*********************************************************************** | 604 /*********************************************************************** |
605 Starting and ending an update | 605 Starting and ending an update |
606 ***********************************************************************/ | 606 ***********************************************************************/ |
607 | 607 |
608 /* Start an update of frame F. This function is installed as a hook | 608 /* Start an update of frame F. This function is installed as a hook |
609 for update_begin, i.e. it is called when update_begin is called. | 609 for update_begin, i.e. it is called when update_begin is called. |
610 This function is called prior to calls to x_update_window_begin for | 610 This function is called prior to calls to x_update_window_begin for |
611 each window being updated. Currently, there is nothing to do here | 611 each window being updated. Currently, there is nothing to do here |
612 because all interesting stuff is done on a window basis. */ | 612 because all interesting stuff is done on a window basis. */ |
627 x_update_window_begin (w) | 627 x_update_window_begin (w) |
628 struct window *w; | 628 struct window *w; |
629 { | 629 { |
630 struct frame *f = XFRAME (WINDOW_FRAME (w)); | 630 struct frame *f = XFRAME (WINDOW_FRAME (w)); |
631 struct x_display_info *display_info = FRAME_X_DISPLAY_INFO (f); | 631 struct x_display_info *display_info = FRAME_X_DISPLAY_INFO (f); |
632 | 632 |
633 updated_window = w; | 633 updated_window = w; |
634 set_output_cursor (&w->cursor); | 634 set_output_cursor (&w->cursor); |
635 | 635 |
636 BLOCK_INPUT; | 636 BLOCK_INPUT; |
637 | 637 |
649 their mouse_face_p flag set, which means that they are always | 649 their mouse_face_p flag set, which means that they are always |
650 unequal to rows in a desired matrix which never have that | 650 unequal to rows in a desired matrix which never have that |
651 flag set. So, rows containing mouse-face glyphs are never | 651 flag set. So, rows containing mouse-face glyphs are never |
652 scrolled, and we don't have to switch the mouse highlight off | 652 scrolled, and we don't have to switch the mouse highlight off |
653 here to prevent it from being scrolled. */ | 653 here to prevent it from being scrolled. */ |
654 | 654 |
655 /* Can we tell that this update does not affect the window | 655 /* Can we tell that this update does not affect the window |
656 where the mouse highlight is? If so, no need to turn off. | 656 where the mouse highlight is? If so, no need to turn off. |
657 Likewise, don't do anything if the frame is garbaged; | 657 Likewise, don't do anything if the frame is garbaged; |
658 in that case, the frame's current matrix that we would use | 658 in that case, the frame's current matrix that we would use |
659 is all wrong, and we will redisplay that line anyway. */ | 659 is all wrong, and we will redisplay that line anyway. */ |
682 static void | 682 static void |
683 x_draw_vertical_border (w) | 683 x_draw_vertical_border (w) |
684 struct window *w; | 684 struct window *w; |
685 { | 685 { |
686 struct frame *f = XFRAME (WINDOW_FRAME (w)); | 686 struct frame *f = XFRAME (WINDOW_FRAME (w)); |
687 | 687 |
688 /* Redraw borders between horizontally adjacent windows. Don't | 688 /* Redraw borders between horizontally adjacent windows. Don't |
689 do it for frames with vertical scroll bars because either the | 689 do it for frames with vertical scroll bars because either the |
690 right scroll bar of a window, or the left scroll bar of its | 690 right scroll bar of a window, or the left scroll bar of its |
691 neighbor will suffice as a border. */ | 691 neighbor will suffice as a border. */ |
692 if (!WINDOW_RIGHTMOST_P (w) | 692 if (!WINDOW_RIGHTMOST_P (w) |
695 int x0, x1, y0, y1; | 695 int x0, x1, y0, y1; |
696 | 696 |
697 window_box_edges (w, -1, &x0, &y0, &x1, &y1); | 697 window_box_edges (w, -1, &x0, &y0, &x1, &y1); |
698 x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f); | 698 x1 += FRAME_X_RIGHT_FRINGE_WIDTH (f); |
699 y1 -= 1; | 699 y1 -= 1; |
700 | 700 |
701 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 701 XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
702 f->output_data.x->normal_gc, x1, y0, x1, y1); | 702 f->output_data.x->normal_gc, x1, y0, x1, y1); |
703 } | 703 } |
704 } | 704 } |
705 | 705 |
706 | 706 |
707 /* End update of window W (which is equal to updated_window). | 707 /* End update of window W (which is equal to updated_window). |
708 | 708 |
709 Draw vertical borders between horizontally adjacent windows, and | 709 Draw vertical borders between horizontally adjacent windows, and |
710 display W's cursor if CURSOR_ON_P is non-zero. | 710 display W's cursor if CURSOR_ON_P is non-zero. |
711 | 711 |
721 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p) | 721 x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p) |
722 struct window *w; | 722 struct window *w; |
723 int cursor_on_p, mouse_face_overwritten_p; | 723 int cursor_on_p, mouse_face_overwritten_p; |
724 { | 724 { |
725 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); | 725 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); |
726 | 726 |
727 if (!w->pseudo_window_p) | 727 if (!w->pseudo_window_p) |
728 { | 728 { |
729 BLOCK_INPUT; | 729 BLOCK_INPUT; |
730 | 730 |
731 if (cursor_on_p) | 731 if (cursor_on_p) |
732 x_display_and_set_cursor (w, 1, output_cursor.hpos, | 732 x_display_and_set_cursor (w, 1, output_cursor.hpos, |
733 output_cursor.vpos, | 733 output_cursor.vpos, |
734 output_cursor.x, output_cursor.y); | 734 output_cursor.x, output_cursor.y); |
735 | 735 |
736 x_draw_vertical_border (w); | 736 x_draw_vertical_border (w); |
737 UNBLOCK_INPUT; | 737 UNBLOCK_INPUT; |
738 } | 738 } |
739 | 739 |
740 /* If a row with mouse-face was overwritten, arrange for | 740 /* If a row with mouse-face was overwritten, arrange for |
741 XTframe_up_to_date to redisplay the mouse highlight. */ | 741 XTframe_up_to_date to redisplay the mouse highlight. */ |
742 if (mouse_face_overwritten_p) | 742 if (mouse_face_overwritten_p) |
743 { | 743 { |
744 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; | 744 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; |
745 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; | 745 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; |
746 dpyinfo->mouse_face_window = Qnil; | 746 dpyinfo->mouse_face_window = Qnil; |
747 } | 747 } |
748 | 748 |
749 updated_window = NULL; | 749 updated_window = NULL; |
750 } | 750 } |
751 | 751 |
752 | 752 |
753 /* End update of frame F. This function is installed as a hook in | 753 /* End update of frame F. This function is installed as a hook in |
805 struct glyph_row *desired_row; | 805 struct glyph_row *desired_row; |
806 { | 806 { |
807 struct window *w = updated_window; | 807 struct window *w = updated_window; |
808 struct frame *f; | 808 struct frame *f; |
809 int width, height; | 809 int width, height; |
810 | 810 |
811 xassert (w); | 811 xassert (w); |
812 | 812 |
813 if (!desired_row->mode_line_p && !w->pseudo_window_p) | 813 if (!desired_row->mode_line_p && !w->pseudo_window_p) |
814 { | 814 { |
815 BLOCK_INPUT; | 815 BLOCK_INPUT; |
816 x_draw_row_fringe_bitmaps (w, desired_row); | 816 x_draw_row_fringe_bitmaps (w, desired_row); |
817 UNBLOCK_INPUT; | 817 UNBLOCK_INPUT; |
818 } | 818 } |
819 | 819 |
820 /* When a window has disappeared, make sure that no rest of | 820 /* When a window has disappeared, make sure that no rest of |
821 full-width rows stays visible in the internal border. Could | 821 full-width rows stays visible in the internal border. Could |
822 check here if updated_window is the leftmost/rightmost window, | 822 check here if updated_window is the leftmost/rightmost window, |
823 but I guess it's not worth doing since vertically split windows | 823 but I guess it's not worth doing since vertically split windows |
824 are almost never used, internal border is rarely set, and the | 824 are almost never used, internal border is rarely set, and the |
835 | 835 |
836 /* Internal border is drawn below the tool bar. */ | 836 /* Internal border is drawn below the tool bar. */ |
837 if (WINDOWP (f->tool_bar_window) | 837 if (WINDOWP (f->tool_bar_window) |
838 && w == XWINDOW (f->tool_bar_window)) | 838 && w == XWINDOW (f->tool_bar_window)) |
839 y -= width; | 839 y -= width; |
840 | 840 |
841 BLOCK_INPUT; | 841 BLOCK_INPUT; |
842 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 842 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
843 0, y, width, height, False); | 843 0, y, width, height, False); |
844 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 844 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
845 f->output_data.x->pixel_width - width, | 845 f->output_data.x->pixel_width - width, |
888 case LEFT_TRUNCATION_BITMAP: | 888 case LEFT_TRUNCATION_BITMAP: |
889 wd = left_width; | 889 wd = left_width; |
890 h = left_height; | 890 h = left_height; |
891 bits = left_bits; | 891 bits = left_bits; |
892 break; | 892 break; |
893 | 893 |
894 case OVERLAY_ARROW_BITMAP: | 894 case OVERLAY_ARROW_BITMAP: |
895 wd = ov_width; | 895 wd = ov_width; |
896 h = ov_height; | 896 h = ov_height; |
897 bits = ov_bits; | 897 bits = ov_bits; |
898 break; | 898 break; |
899 | 899 |
900 case RIGHT_TRUNCATION_BITMAP: | 900 case RIGHT_TRUNCATION_BITMAP: |
901 wd = right_width; | 901 wd = right_width; |
902 h = right_height; | 902 h = right_height; |
903 bits = right_bits; | 903 bits = right_bits; |
904 break; | 904 break; |
906 case CONTINUED_LINE_BITMAP: | 906 case CONTINUED_LINE_BITMAP: |
907 wd = continued_width; | 907 wd = continued_width; |
908 h = continued_height; | 908 h = continued_height; |
909 bits = continued_bits; | 909 bits = continued_bits; |
910 break; | 910 break; |
911 | 911 |
912 case CONTINUATION_LINE_BITMAP: | 912 case CONTINUATION_LINE_BITMAP: |
913 wd = continuation_width; | 913 wd = continuation_width; |
914 h = continuation_height; | 914 h = continuation_height; |
915 bits = continuation_bits; | 915 bits = continuation_bits; |
916 break; | 916 break; |
973 } | 973 } |
974 | 974 |
975 if (b1 >= 0) | 975 if (b1 >= 0) |
976 { | 976 { |
977 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); | 977 int header_line_height = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); |
978 | 978 |
979 /* In case the same realized face is used for fringes and | 979 /* In case the same realized face is used for fringes and |
980 for something displayed in the text (e.g. face `region' on | 980 for something displayed in the text (e.g. face `region' on |
981 mono-displays, the fill style may have been changed to | 981 mono-displays, the fill style may have been changed to |
982 FillSolid in x_draw_glyph_string_background. */ | 982 FillSolid in x_draw_glyph_string_background. */ |
983 if (face->stipple) | 983 if (face->stipple) |
984 XSetFillStyle (display, face->gc, FillOpaqueStippled); | 984 XSetFillStyle (display, face->gc, FillOpaqueStippled); |
985 else | 985 else |
986 XSetForeground (display, face->gc, face->background); | 986 XSetForeground (display, face->gc, face->background); |
987 | 987 |
988 XFillRectangle (display, window, face->gc, | 988 XFillRectangle (display, window, face->gc, |
989 b1, | 989 b1, |
990 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, | 990 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, |
991 row->y)), | 991 row->y)), |
992 b2, | 992 b2, |
1003 face->foreground, | 1003 face->foreground, |
1004 face->background, depth); | 1004 face->background, depth); |
1005 XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy); | 1005 XCopyArea (display, pixmap, window, gc, 0, 0, wd, h, x, y + dy); |
1006 XFreePixmap (display, pixmap); | 1006 XFreePixmap (display, pixmap); |
1007 } | 1007 } |
1008 | 1008 |
1009 XSetClipMask (display, gc, None); | 1009 XSetClipMask (display, gc, None); |
1010 } | 1010 } |
1011 | 1011 |
1012 | 1012 |
1013 /* Draw fringe bitmaps for glyph row ROW on window W. Call this | 1013 /* Draw fringe bitmaps for glyph row ROW on window W. Call this |
1103 | 1103 |
1104 /* Set a nominal cursor position. | 1104 /* Set a nominal cursor position. |
1105 | 1105 |
1106 HPOS and VPOS are column/row positions in a window glyph matrix. X | 1106 HPOS and VPOS are column/row positions in a window glyph matrix. X |
1107 and Y are window text area relative pixel positions. | 1107 and Y are window text area relative pixel positions. |
1108 | 1108 |
1109 If this is done during an update, updated_window will contain the | 1109 If this is done during an update, updated_window will contain the |
1110 window that is being updated and the position is the future output | 1110 window that is being updated and the position is the future output |
1111 cursor position for that window. If updated_window is null, use | 1111 cursor position for that window. If updated_window is null, use |
1112 selected_window and display the cursor at the given position. */ | 1112 selected_window and display the cursor at the given position. */ |
1113 | 1113 |
1266 { | 1266 { |
1267 ccl->reg[0] = charset; | 1267 ccl->reg[0] = charset; |
1268 ccl->reg[1] = char2b->byte1; | 1268 ccl->reg[1] = char2b->byte1; |
1269 ccl->reg[2] = char2b->byte2; | 1269 ccl->reg[2] = char2b->byte2; |
1270 } | 1270 } |
1271 | 1271 |
1272 ccl_driver (ccl, NULL, NULL, 0, 0, NULL); | 1272 ccl_driver (ccl, NULL, NULL, 0, 0, NULL); |
1273 | 1273 |
1274 /* We assume that MSBs are appropriately set/reset by CCL | 1274 /* We assume that MSBs are appropriately set/reset by CCL |
1275 program. */ | 1275 program. */ |
1276 if (font->max_byte1 == 0) /* 1-byte font */ | 1276 if (font->max_byte1 == 0) /* 1-byte font */ |
1277 char2b->byte1 = 0, char2b->byte2 = ccl->reg[1]; | 1277 char2b->byte1 = 0, char2b->byte2 = ccl->reg[1]; |
1278 else | 1278 else |
1281 else if (font_info->encoding[charset]) | 1281 else if (font_info->encoding[charset]) |
1282 { | 1282 { |
1283 /* Fixed encoding scheme. See fontset.h for the meaning of the | 1283 /* Fixed encoding scheme. See fontset.h for the meaning of the |
1284 encoding numbers. */ | 1284 encoding numbers. */ |
1285 int enc = font_info->encoding[charset]; | 1285 int enc = font_info->encoding[charset]; |
1286 | 1286 |
1287 if ((enc == 1 || enc == 2) | 1287 if ((enc == 1 || enc == 2) |
1288 && CHARSET_DIMENSION (charset) == 2) | 1288 && CHARSET_DIMENSION (charset) == 2) |
1289 char2b->byte1 |= 0x80; | 1289 char2b->byte1 |= 0x80; |
1290 | 1290 |
1291 if (enc == 1 || enc == 3) | 1291 if (enc == 1 || enc == 3) |
1292 char2b->byte2 |= 0x80; | 1292 char2b->byte2 |= 0x80; |
1293 } | 1293 } |
1294 } | 1294 } |
1295 | 1295 |
1326 char2b->byte2 = c; | 1326 char2b->byte2 = c; |
1327 } | 1327 } |
1328 else | 1328 else |
1329 { | 1329 { |
1330 int c1, c2, charset; | 1330 int c1, c2, charset; |
1331 | 1331 |
1332 /* Split characters into bytes. If c2 is -1 afterwards, C is | 1332 /* Split characters into bytes. If c2 is -1 afterwards, C is |
1333 really a one-byte character so that byte1 is zero. */ | 1333 really a one-byte character so that byte1 is zero. */ |
1334 SPLIT_CHAR (c, charset, c1, c2); | 1334 SPLIT_CHAR (c, charset, c1, c2); |
1335 if (c2 > 0) | 1335 if (c2 > 0) |
1336 char2b->byte1 = c1, char2b->byte2 = c2; | 1336 char2b->byte1 = c1, char2b->byte2 = c2; |
1351 if (display_p) | 1351 if (display_p) |
1352 { | 1352 { |
1353 xassert (face != NULL); | 1353 xassert (face != NULL); |
1354 PREPARE_FACE_FOR_DISPLAY (f, face); | 1354 PREPARE_FACE_FOR_DISPLAY (f, face); |
1355 } | 1355 } |
1356 | 1356 |
1357 return face; | 1357 return face; |
1358 } | 1358 } |
1359 | 1359 |
1360 | 1360 |
1361 /* Get face and two-byte form of character glyph GLYPH on frame F. | 1361 /* Get face and two-byte form of character glyph GLYPH on frame F. |
1392 char2b->byte2 = glyph->u.ch; | 1392 char2b->byte2 = glyph->u.ch; |
1393 } | 1393 } |
1394 else | 1394 else |
1395 { | 1395 { |
1396 int c1, c2, charset; | 1396 int c1, c2, charset; |
1397 | 1397 |
1398 /* Split characters into bytes. If c2 is -1 afterwards, C is | 1398 /* Split characters into bytes. If c2 is -1 afterwards, C is |
1399 really a one-byte character so that byte1 is zero. */ | 1399 really a one-byte character so that byte1 is zero. */ |
1400 SPLIT_CHAR (glyph->u.ch, charset, c1, c2); | 1400 SPLIT_CHAR (glyph->u.ch, charset, c1, c2); |
1401 if (c2 > 0) | 1401 if (c2 > 0) |
1402 char2b->byte1 = c1, char2b->byte2 = c2; | 1402 char2b->byte1 = c1, char2b->byte2 = c2; |
1423 PREPARE_FACE_FOR_DISPLAY (f, face); | 1423 PREPARE_FACE_FOR_DISPLAY (f, face); |
1424 return face; | 1424 return face; |
1425 } | 1425 } |
1426 | 1426 |
1427 | 1427 |
1428 /* Store one glyph for IT->char_to_display in IT->glyph_row. | 1428 /* Store one glyph for IT->char_to_display in IT->glyph_row. |
1429 Called from x_produce_glyphs when IT->glyph_row is non-null. */ | 1429 Called from x_produce_glyphs when IT->glyph_row is non-null. */ |
1430 | 1430 |
1431 static INLINE void | 1431 static INLINE void |
1432 x_append_glyph (it) | 1432 x_append_glyph (it) |
1433 struct it *it; | 1433 struct it *it; |
1434 { | 1434 { |
1435 struct glyph *glyph; | 1435 struct glyph *glyph; |
1436 enum glyph_row_area area = it->area; | 1436 enum glyph_row_area area = it->area; |
1437 | 1437 |
1438 xassert (it->glyph_row); | 1438 xassert (it->glyph_row); |
1439 xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); | 1439 xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); |
1440 | 1440 |
1441 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 1441 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
1442 if (glyph < it->glyph_row->glyphs[area + 1]) | 1442 if (glyph < it->glyph_row->glyphs[area + 1]) |
1443 { | 1443 { |
1444 glyph->charpos = CHARPOS (it->position); | 1444 glyph->charpos = CHARPOS (it->position); |
1445 glyph->object = it->object; | 1445 glyph->object = it->object; |
1457 glyph->u.ch = it->char_to_display; | 1457 glyph->u.ch = it->char_to_display; |
1458 ++it->glyph_row->used[area]; | 1458 ++it->glyph_row->used[area]; |
1459 } | 1459 } |
1460 } | 1460 } |
1461 | 1461 |
1462 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. | 1462 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. |
1463 Called from x_produce_glyphs when IT->glyph_row is non-null. */ | 1463 Called from x_produce_glyphs when IT->glyph_row is non-null. */ |
1464 | 1464 |
1465 static INLINE void | 1465 static INLINE void |
1466 x_append_composite_glyph (it) | 1466 x_append_composite_glyph (it) |
1467 struct it *it; | 1467 struct it *it; |
1468 { | 1468 { |
1469 struct glyph *glyph; | 1469 struct glyph *glyph; |
1470 enum glyph_row_area area = it->area; | 1470 enum glyph_row_area area = it->area; |
1471 | 1471 |
1472 xassert (it->glyph_row); | 1472 xassert (it->glyph_row); |
1473 | 1473 |
1474 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 1474 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
1475 if (glyph < it->glyph_row->glyphs[area + 1]) | 1475 if (glyph < it->glyph_row->glyphs[area + 1]) |
1476 { | 1476 { |
1477 glyph->charpos = CHARPOS (it->position); | 1477 glyph->charpos = CHARPOS (it->position); |
1478 glyph->object = it->object; | 1478 glyph->object = it->object; |
1538 it->ascent = it->phys_ascent = image_ascent (img, face); | 1538 it->ascent = it->phys_ascent = image_ascent (img, face); |
1539 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; | 1539 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; |
1540 it->pixel_width = img->width + 2 * img->hmargin; | 1540 it->pixel_width = img->width + 2 * img->hmargin; |
1541 | 1541 |
1542 it->nglyphs = 1; | 1542 it->nglyphs = 1; |
1543 | 1543 |
1544 if (face->box != FACE_NO_BOX) | 1544 if (face->box != FACE_NO_BOX) |
1545 { | 1545 { |
1546 if (face->box_line_width > 0) | 1546 if (face->box_line_width > 0) |
1547 { | 1547 { |
1548 it->ascent += face->box_line_width; | 1548 it->ascent += face->box_line_width; |
1549 it->descent += face->box_line_width; | 1549 it->descent += face->box_line_width; |
1550 } | 1550 } |
1551 | 1551 |
1552 if (it->start_of_box_run_p) | 1552 if (it->start_of_box_run_p) |
1553 it->pixel_width += abs (face->box_line_width); | 1553 it->pixel_width += abs (face->box_line_width); |
1554 if (it->end_of_box_run_p) | 1554 if (it->end_of_box_run_p) |
1555 it->pixel_width += abs (face->box_line_width); | 1555 it->pixel_width += abs (face->box_line_width); |
1556 } | 1556 } |
1557 | 1557 |
1558 take_vertical_position_into_account (it); | 1558 take_vertical_position_into_account (it); |
1559 | 1559 |
1560 if (it->glyph_row) | 1560 if (it->glyph_row) |
1561 { | 1561 { |
1562 struct glyph *glyph; | 1562 struct glyph *glyph; |
1563 enum glyph_row_area area = it->area; | 1563 enum glyph_row_area area = it->area; |
1564 | 1564 |
1565 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 1565 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
1566 if (glyph < it->glyph_row->glyphs[area + 1]) | 1566 if (glyph < it->glyph_row->glyphs[area + 1]) |
1567 { | 1567 { |
1568 glyph->charpos = CHARPOS (it->position); | 1568 glyph->charpos = CHARPOS (it->position); |
1569 glyph->object = it->object; | 1569 glyph->object = it->object; |
1583 } | 1583 } |
1584 } | 1584 } |
1585 | 1585 |
1586 | 1586 |
1587 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | 1587 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source |
1588 of the glyph, WIDTH and HEIGHT are the width and height of the | 1588 of the glyph, WIDTH and HEIGHT are the width and height of the |
1589 stretch. ASCENT is the percentage/100 of HEIGHT to use for the | 1589 stretch. ASCENT is the percentage/100 of HEIGHT to use for the |
1590 ascent of the glyph (0 <= ASCENT <= 1). */ | 1590 ascent of the glyph (0 <= ASCENT <= 1). */ |
1591 | 1591 |
1592 static void | 1592 static void |
1593 x_append_stretch_glyph (it, object, width, height, ascent) | 1593 x_append_stretch_glyph (it, object, width, height, ascent) |
1594 struct it *it; | 1594 struct it *it; |
1595 Lisp_Object object; | 1595 Lisp_Object object; |
1596 int width, height; | 1596 int width, height; |
1598 { | 1598 { |
1599 struct glyph *glyph; | 1599 struct glyph *glyph; |
1600 enum glyph_row_area area = it->area; | 1600 enum glyph_row_area area = it->area; |
1601 | 1601 |
1602 xassert (ascent >= 0 && ascent <= 1); | 1602 xassert (ascent >= 0 && ascent <= 1); |
1603 | 1603 |
1604 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | 1604 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; |
1605 if (glyph < it->glyph_row->glyphs[area + 1]) | 1605 if (glyph < it->glyph_row->glyphs[area + 1]) |
1606 { | 1606 { |
1607 glyph->charpos = CHARPOS (it->position); | 1607 glyph->charpos = CHARPOS (it->position); |
1608 glyph->object = object; | 1608 glyph->object = object; |
1627 of the glyph property displayed. The value must be a list | 1627 of the glyph property displayed. The value must be a list |
1628 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs | 1628 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs |
1629 being recognized: | 1629 being recognized: |
1630 | 1630 |
1631 1. `:width WIDTH' specifies that the space should be WIDTH * | 1631 1. `:width WIDTH' specifies that the space should be WIDTH * |
1632 canonical char width wide. WIDTH may be an integer or floating | 1632 canonical char width wide. WIDTH may be an integer or floating |
1633 point number. | 1633 point number. |
1634 | 1634 |
1635 2. `:relative-width FACTOR' specifies that the width of the stretch | 1635 2. `:relative-width FACTOR' specifies that the width of the stretch |
1636 should be computed from the width of the first character having the | 1636 should be computed from the width of the first character having the |
1637 `glyph' property, and should be FACTOR times that width. | 1637 `glyph' property, and should be FACTOR times that width. |
1638 | 1638 |
1639 3. `:align-to HPOS' specifies that the space should be wide enough | 1639 3. `:align-to HPOS' specifies that the space should be wide enough |
1640 to reach HPOS, a value in canonical character units. | 1640 to reach HPOS, a value in canonical character units. |
1641 | 1641 |
1642 Exactly one of the above pairs must be present. | 1642 Exactly one of the above pairs must be present. |
1643 | 1643 |
1644 4. `:height HEIGHT' specifies that the height of the stretch produced | 1644 4. `:height HEIGHT' specifies that the height of the stretch produced |
1645 should be HEIGHT, measured in canonical character units. | 1645 should be HEIGHT, measured in canonical character units. |
1646 | 1646 |
1647 5. `:relative-height FACTOR' specifies that the height of the | 1647 5. `:relative-height FACTOR' specifies that the height of the |
1675 double width = 0, height = 0, ascent = 0; | 1675 double width = 0, height = 0, ascent = 0; |
1676 struct face *face = FACE_FROM_ID (it->f, it->face_id); | 1676 struct face *face = FACE_FROM_ID (it->f, it->face_id); |
1677 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); | 1677 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); |
1678 | 1678 |
1679 PREPARE_FACE_FOR_DISPLAY (it->f, face); | 1679 PREPARE_FACE_FOR_DISPLAY (it->f, face); |
1680 | 1680 |
1681 /* List should start with `space'. */ | 1681 /* List should start with `space'. */ |
1682 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); | 1682 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); |
1683 plist = XCDR (it->object); | 1683 plist = XCDR (it->object); |
1684 | 1684 |
1685 /* Compute the width of the stretch. */ | 1685 /* Compute the width of the stretch. */ |
1693 /* Relative width `:relative-width FACTOR' specified and valid. | 1693 /* Relative width `:relative-width FACTOR' specified and valid. |
1694 Compute the width of the characters having the `glyph' | 1694 Compute the width of the characters having the `glyph' |
1695 property. */ | 1695 property. */ |
1696 struct it it2; | 1696 struct it it2; |
1697 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | 1697 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); |
1698 | 1698 |
1699 it2 = *it; | 1699 it2 = *it; |
1700 if (it->multibyte_p) | 1700 if (it->multibyte_p) |
1701 { | 1701 { |
1702 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | 1702 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) |
1703 - IT_BYTEPOS (*it)); | 1703 - IT_BYTEPOS (*it)); |
1715 NUMVAL (prop) > 0) | 1715 NUMVAL (prop) > 0) |
1716 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; | 1716 width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; |
1717 else | 1717 else |
1718 /* Nothing specified -> width defaults to canonical char width. */ | 1718 /* Nothing specified -> width defaults to canonical char width. */ |
1719 width = CANON_X_UNIT (it->f); | 1719 width = CANON_X_UNIT (it->f); |
1720 | 1720 |
1721 /* Compute height. */ | 1721 /* Compute height. */ |
1722 if (prop = Fplist_get (plist, QCheight), | 1722 if (prop = Fplist_get (plist, QCheight), |
1723 NUMVAL (prop) > 0) | 1723 NUMVAL (prop) > 0) |
1724 height = NUMVAL (prop) * CANON_Y_UNIT (it->f); | 1724 height = NUMVAL (prop) * CANON_Y_UNIT (it->f); |
1725 else if (prop = Fplist_get (plist, QCrelative_height), | 1725 else if (prop = Fplist_get (plist, QCrelative_height), |
1726 NUMVAL (prop) > 0) | 1726 NUMVAL (prop) > 0) |
1727 height = FONT_HEIGHT (font) * NUMVAL (prop); | 1727 height = FONT_HEIGHT (font) * NUMVAL (prop); |
1728 else | 1728 else |
1729 height = FONT_HEIGHT (font); | 1729 height = FONT_HEIGHT (font); |
1730 | 1730 |
1731 /* Compute percentage of height used for ascent. If | 1731 /* Compute percentage of height used for ascent. If |
1732 `:ascent ASCENT' is present and valid, use that. Otherwise, | 1732 `:ascent ASCENT' is present and valid, use that. Otherwise, |
1733 derive the ascent from the font in use. */ | 1733 derive the ascent from the font in use. */ |
1734 if (prop = Fplist_get (plist, QCascent), | 1734 if (prop = Fplist_get (plist, QCascent), |
1735 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) | 1735 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) |
1736 ascent = NUMVAL (prop) / 100.0; | 1736 ascent = NUMVAL (prop) / 100.0; |
1760 if (face->box_line_width > 0) | 1760 if (face->box_line_width > 0) |
1761 { | 1761 { |
1762 it->ascent += face->box_line_width; | 1762 it->ascent += face->box_line_width; |
1763 it->descent += face->box_line_width; | 1763 it->descent += face->box_line_width; |
1764 } | 1764 } |
1765 | 1765 |
1766 if (it->start_of_box_run_p) | 1766 if (it->start_of_box_run_p) |
1767 it->pixel_width += abs (face->box_line_width); | 1767 it->pixel_width += abs (face->box_line_width); |
1768 if (it->end_of_box_run_p) | 1768 if (it->end_of_box_run_p) |
1769 it->pixel_width += abs (face->box_line_width); | 1769 it->pixel_width += abs (face->box_line_width); |
1770 } | 1770 } |
1771 | 1771 |
1772 take_vertical_position_into_account (it); | 1772 take_vertical_position_into_account (it); |
1773 } | 1773 } |
1774 | 1774 |
1775 /* Return proper value to be used as baseline offset of font that has | 1775 /* Return proper value to be used as baseline offset of font that has |
1776 ASCENT and DESCENT to draw characters by the font at the vertical | 1776 ASCENT and DESCENT to draw characters by the font at the vertical |
1857 it->multibyte_p = 1; | 1857 it->multibyte_p = 1; |
1858 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | 1858 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
1859 face = FACE_FROM_ID (it->f, it->face_id); | 1859 face = FACE_FROM_ID (it->f, it->face_id); |
1860 } | 1860 } |
1861 } | 1861 } |
1862 | 1862 |
1863 /* Get font to use. Encode IT->char_to_display. */ | 1863 /* Get font to use. Encode IT->char_to_display. */ |
1864 x_get_char_face_and_encoding (it->f, it->char_to_display, | 1864 x_get_char_face_and_encoding (it->f, it->char_to_display, |
1865 it->face_id, &char2b, | 1865 it->face_id, &char2b, |
1866 it->multibyte_p, 0); | 1866 it->multibyte_p, 0); |
1867 font = face->font; | 1867 font = face->font; |
1918 height. If character has a box line to the left and/or | 1918 height. If character has a box line to the left and/or |
1919 right, add the box line width to the character's width. */ | 1919 right, add the box line width to the character's width. */ |
1920 if (face->box != FACE_NO_BOX) | 1920 if (face->box != FACE_NO_BOX) |
1921 { | 1921 { |
1922 int thick = face->box_line_width; | 1922 int thick = face->box_line_width; |
1923 | 1923 |
1924 if (thick > 0) | 1924 if (thick > 0) |
1925 { | 1925 { |
1926 it->ascent += thick; | 1926 it->ascent += thick; |
1927 it->descent += thick; | 1927 it->descent += thick; |
1928 } | 1928 } |
1939 (1 pixel) and a 1 pixel margin to the character height. */ | 1939 (1 pixel) and a 1 pixel margin to the character height. */ |
1940 if (face->overline_p) | 1940 if (face->overline_p) |
1941 it->ascent += 2; | 1941 it->ascent += 2; |
1942 | 1942 |
1943 take_vertical_position_into_account (it); | 1943 take_vertical_position_into_account (it); |
1944 | 1944 |
1945 /* If we have to actually produce glyphs, do it. */ | 1945 /* If we have to actually produce glyphs, do it. */ |
1946 if (it->glyph_row) | 1946 if (it->glyph_row) |
1947 { | 1947 { |
1948 if (stretched_p) | 1948 if (stretched_p) |
1949 { | 1949 { |
1950 /* Translate a space with a `space-width' property | 1950 /* Translate a space with a `space-width' property |
1951 into a stretch glyph. */ | 1951 into a stretch glyph. */ |
1952 double ascent = (double) font->ascent / FONT_HEIGHT (font); | 1952 double ascent = (double) font->ascent / FONT_HEIGHT (font); |
1953 x_append_stretch_glyph (it, it->object, it->pixel_width, | 1953 x_append_stretch_glyph (it, it->object, it->pixel_width, |
1954 it->ascent + it->descent, ascent); | 1954 it->ascent + it->descent, ascent); |
1955 } | 1955 } |
1956 else | 1956 else |
1957 x_append_glyph (it); | 1957 x_append_glyph (it); |
1958 | 1958 |
1968 /* A newline has no width but we need the height of the line. */ | 1968 /* A newline has no width but we need the height of the line. */ |
1969 it->pixel_width = 0; | 1969 it->pixel_width = 0; |
1970 it->nglyphs = 0; | 1970 it->nglyphs = 0; |
1971 it->ascent = it->phys_ascent = font->ascent + boff; | 1971 it->ascent = it->phys_ascent = font->ascent + boff; |
1972 it->descent = it->phys_descent = font->descent - boff; | 1972 it->descent = it->phys_descent = font->descent - boff; |
1973 | 1973 |
1974 if (face->box != FACE_NO_BOX | 1974 if (face->box != FACE_NO_BOX |
1975 && face->box_line_width > 0) | 1975 && face->box_line_width > 0) |
1976 { | 1976 { |
1977 it->ascent += face->box_line_width; | 1977 it->ascent += face->box_line_width; |
1978 it->descent += face->box_line_width; | 1978 it->descent += face->box_line_width; |
1987 /* If the distance from the current position to the next tab | 1987 /* If the distance from the current position to the next tab |
1988 stop is less than a canonical character width, use the | 1988 stop is less than a canonical character width, use the |
1989 tab stop after that. */ | 1989 tab stop after that. */ |
1990 if (next_tab_x - x < CANON_X_UNIT (it->f)) | 1990 if (next_tab_x - x < CANON_X_UNIT (it->f)) |
1991 next_tab_x += tab_width; | 1991 next_tab_x += tab_width; |
1992 | 1992 |
1993 it->pixel_width = next_tab_x - x; | 1993 it->pixel_width = next_tab_x - x; |
1994 it->nglyphs = 1; | 1994 it->nglyphs = 1; |
1995 it->ascent = it->phys_ascent = font->ascent + boff; | 1995 it->ascent = it->phys_ascent = font->ascent + boff; |
1996 it->descent = it->phys_descent = font->descent - boff; | 1996 it->descent = it->phys_descent = font->descent - boff; |
1997 | 1997 |
1998 if (it->glyph_row) | 1998 if (it->glyph_row) |
1999 { | 1999 { |
2000 double ascent = (double) it->ascent / (it->ascent + it->descent); | 2000 double ascent = (double) it->ascent / (it->ascent + it->descent); |
2001 x_append_stretch_glyph (it, it->object, it->pixel_width, | 2001 x_append_stretch_glyph (it, it->object, it->pixel_width, |
2002 it->ascent + it->descent, ascent); | 2002 it->ascent + it->descent, ascent); |
2003 } | 2003 } |
2004 } | 2004 } |
2005 else | 2005 else |
2006 { | 2006 { |
2007 /* A multi-byte character. Assume that the display width of the | 2007 /* A multi-byte character. Assume that the display width of the |
2008 character is the width of the character multiplied by the | 2008 character is the width of the character multiplied by the |
2009 width of the font. */ | 2009 width of the font. */ |
2010 | 2010 |
2046 it->ascent += thick; | 2046 it->ascent += thick; |
2047 it->descent += thick; | 2047 it->descent += thick; |
2048 } | 2048 } |
2049 else | 2049 else |
2050 thick = - thick; | 2050 thick = - thick; |
2051 | 2051 |
2052 if (it->start_of_box_run_p) | 2052 if (it->start_of_box_run_p) |
2053 it->pixel_width += thick; | 2053 it->pixel_width += thick; |
2054 if (it->end_of_box_run_p) | 2054 if (it->end_of_box_run_p) |
2055 it->pixel_width += thick; | 2055 it->pixel_width += thick; |
2056 } | 2056 } |
2057 | 2057 |
2058 /* If face has an overline, add the height of the overline | 2058 /* If face has an overline, add the height of the overline |
2059 (1 pixel) and a 1 pixel margin to the character height. */ | 2059 (1 pixel) and a 1 pixel margin to the character height. */ |
2060 if (face->overline_p) | 2060 if (face->overline_p) |
2061 it->ascent += 2; | 2061 it->ascent += 2; |
2062 | 2062 |
2063 take_vertical_position_into_account (it); | 2063 take_vertical_position_into_account (it); |
2064 | 2064 |
2065 if (it->glyph_row) | 2065 if (it->glyph_row) |
2066 x_append_glyph (it); | 2066 x_append_glyph (it); |
2067 } | 2067 } |
2068 it->multibyte_p = saved_multibyte_p; | 2068 it->multibyte_p = saved_multibyte_p; |
2069 } | 2069 } |
2088 || (it->c >= 0200 | 2088 || (it->c >= 0200 |
2089 && !NILP (Vnonascii_translation_table)))) | 2089 && !NILP (Vnonascii_translation_table)))) |
2090 { | 2090 { |
2091 it->char_to_display = unibyte_char_to_multibyte (it->c); | 2091 it->char_to_display = unibyte_char_to_multibyte (it->c); |
2092 } | 2092 } |
2093 | 2093 |
2094 /* Get face and font to use. Encode IT->char_to_display. */ | 2094 /* Get face and font to use. Encode IT->char_to_display. */ |
2095 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | 2095 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
2096 face = FACE_FROM_ID (it->f, it->face_id); | 2096 face = FACE_FROM_ID (it->f, it->face_id); |
2097 x_get_char_face_and_encoding (it->f, it->char_to_display, | 2097 x_get_char_face_and_encoding (it->f, it->char_to_display, |
2098 it->face_id, &char2b, it->multibyte_p, 0); | 2098 it->face_id, &char2b, it->multibyte_p, 0); |
2153 { | 2153 { |
2154 width = FONT_WIDTH (font); | 2154 width = FONT_WIDTH (font); |
2155 ascent = font->ascent; | 2155 ascent = font->ascent; |
2156 descent = font->descent; | 2156 descent = font->descent; |
2157 } | 2157 } |
2158 | 2158 |
2159 rightmost = width; | 2159 rightmost = width; |
2160 lowest = - descent + boff; | 2160 lowest = - descent + boff; |
2161 highest = ascent + boff; | 2161 highest = ascent + boff; |
2162 leftmost = 0; | 2162 leftmost = 0; |
2163 | 2163 |
2164 if (font_info | 2164 if (font_info |
2165 && font_info->default_ascent | 2165 && font_info->default_ascent |
2166 && CHAR_TABLE_P (Vuse_default_ascent) | 2166 && CHAR_TABLE_P (Vuse_default_ascent) |
2167 && !NILP (Faref (Vuse_default_ascent, | 2167 && !NILP (Faref (Vuse_default_ascent, |
2168 make_number (it->char_to_display)))) | 2168 make_number (it->char_to_display)))) |
2178 for (i = 1; i < cmp->glyph_len; i++) | 2178 for (i = 1; i < cmp->glyph_len; i++) |
2179 { | 2179 { |
2180 int left, right, btm, top; | 2180 int left, right, btm, top; |
2181 int ch = COMPOSITION_GLYPH (cmp, i); | 2181 int ch = COMPOSITION_GLYPH (cmp, i); |
2182 int face_id = FACE_FOR_CHAR (it->f, face, ch); | 2182 int face_id = FACE_FOR_CHAR (it->f, face, ch); |
2183 | 2183 |
2184 face = FACE_FROM_ID (it->f, face_id); | 2184 face = FACE_FROM_ID (it->f, face_id); |
2185 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b, | 2185 x_get_char_face_and_encoding (it->f, ch, face->id, &char2b, |
2186 it->multibyte_p, 0); | 2186 it->multibyte_p, 0); |
2187 font = face->font; | 2187 font = face->font; |
2188 if (font == NULL) | 2188 if (font == NULL) |
2319 it->ascent += thick; | 2319 it->ascent += thick; |
2320 it->descent += thick; | 2320 it->descent += thick; |
2321 } | 2321 } |
2322 else | 2322 else |
2323 thick = - thick; | 2323 thick = - thick; |
2324 | 2324 |
2325 if (it->start_of_box_run_p) | 2325 if (it->start_of_box_run_p) |
2326 it->pixel_width += thick; | 2326 it->pixel_width += thick; |
2327 if (it->end_of_box_run_p) | 2327 if (it->end_of_box_run_p) |
2328 it->pixel_width += thick; | 2328 it->pixel_width += thick; |
2329 } | 2329 } |
2330 | 2330 |
2331 /* If face has an overline, add the height of the overline | 2331 /* If face has an overline, add the height of the overline |
2332 (1 pixel) and a 1 pixel margin to the character height. */ | 2332 (1 pixel) and a 1 pixel margin to the character height. */ |
2333 if (face->overline_p) | 2333 if (face->overline_p) |
2334 it->ascent += 2; | 2334 it->ascent += 2; |
2335 | 2335 |
2336 take_vertical_position_into_account (it); | 2336 take_vertical_position_into_account (it); |
2337 | 2337 |
2338 if (it->glyph_row) | 2338 if (it->glyph_row) |
2339 x_append_composite_glyph (it); | 2339 x_append_composite_glyph (it); |
2340 } | 2340 } |
2341 else if (it->what == IT_IMAGE) | 2341 else if (it->what == IT_IMAGE) |
2342 x_produce_image_glyph (it); | 2342 x_produce_image_glyph (it); |
2346 /* Accumulate dimensions. Note: can't assume that it->descent > 0 | 2346 /* Accumulate dimensions. Note: can't assume that it->descent > 0 |
2347 because this isn't true for images with `:ascent 100'. */ | 2347 because this isn't true for images with `:ascent 100'. */ |
2348 xassert (it->ascent >= 0 && it->descent >= 0); | 2348 xassert (it->ascent >= 0 && it->descent >= 0); |
2349 if (it->area == TEXT_AREA) | 2349 if (it->area == TEXT_AREA) |
2350 it->current_x += it->pixel_width; | 2350 it->current_x += it->pixel_width; |
2351 | 2351 |
2352 it->descent += it->extra_line_spacing; | 2352 it->descent += it->extra_line_spacing; |
2353 | 2353 |
2354 it->max_ascent = max (it->max_ascent, it->ascent); | 2354 it->max_ascent = max (it->max_ascent, it->ascent); |
2355 it->max_descent = max (it->max_descent, it->descent); | 2355 it->max_descent = max (it->max_descent, it->descent); |
2356 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | 2356 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); |
2357 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | 2357 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); |
2358 } | 2358 } |
2379 height = FONT_HEIGHT (face->font); | 2379 height = FONT_HEIGHT (face->font); |
2380 if (face->box_line_width > 0) | 2380 if (face->box_line_width > 0) |
2381 height += 2 * face->box_line_width; | 2381 height += 2 * face->box_line_width; |
2382 } | 2382 } |
2383 } | 2383 } |
2384 | 2384 |
2385 return height; | 2385 return height; |
2386 } | 2386 } |
2387 | 2387 |
2388 | 2388 |
2389 /*********************************************************************** | 2389 /*********************************************************************** |
2549 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int, | 2549 static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int, |
2550 int)); | 2550 int)); |
2551 static void x_init_glyph_string P_ ((struct glyph_string *, | 2551 static void x_init_glyph_string P_ ((struct glyph_string *, |
2552 XChar2b *, struct window *, | 2552 XChar2b *, struct window *, |
2553 struct glyph_row *, | 2553 struct glyph_row *, |
2554 enum glyph_row_area, int, | 2554 enum glyph_row_area, int, |
2555 enum draw_glyphs_face)); | 2555 enum draw_glyphs_face)); |
2556 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, | 2556 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, |
2557 enum glyph_row_area, int, int, | 2557 enum glyph_row_area, int, int, |
2558 enum draw_glyphs_face, int)); | 2558 enum draw_glyphs_face, int)); |
2559 static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); | 2559 static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); |
2705 } | 2705 } |
2706 } | 2706 } |
2707 | 2707 |
2708 | 2708 |
2709 /* Set up S->gc of glyph string S for drawing text in mouse face. */ | 2709 /* Set up S->gc of glyph string S for drawing text in mouse face. */ |
2710 | 2710 |
2711 static void | 2711 static void |
2712 x_set_mouse_face_gc (s) | 2712 x_set_mouse_face_gc (s) |
2713 struct glyph_string *s; | 2713 struct glyph_string *s; |
2714 { | 2714 { |
2715 int face_id; | 2715 int face_id; |
2716 struct face *face; | 2716 struct face *face; |
2717 | 2717 |
2718 /* What face has to be used last for the mouse face? */ | 2718 /* What face has to be used last for the mouse face? */ |
2719 face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id; | 2719 face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id; |
2720 face = FACE_FROM_ID (s->f, face_id); | 2720 face = FACE_FROM_ID (s->f, face_id); |
2721 if (face == NULL) | 2721 if (face == NULL) |
2722 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); | 2722 face = FACE_FROM_ID (s->f, MOUSE_FACE_ID); |
2723 | 2723 |
2724 if (s->first_glyph->type == CHAR_GLYPH) | 2724 if (s->first_glyph->type == CHAR_GLYPH) |
2725 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch); | 2725 face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch); |
2726 else | 2726 else |
2727 face_id = FACE_FOR_CHAR (s->f, face, 0); | 2727 face_id = FACE_FOR_CHAR (s->f, face, 0); |
2728 s->face = FACE_FROM_ID (s->f, face_id); | 2728 s->face = FACE_FROM_ID (s->f, face_id); |
2735 { | 2735 { |
2736 /* Otherwise construct scratch_cursor_gc with values from FACE | 2736 /* Otherwise construct scratch_cursor_gc with values from FACE |
2737 but font FONT. */ | 2737 but font FONT. */ |
2738 XGCValues xgcv; | 2738 XGCValues xgcv; |
2739 unsigned long mask; | 2739 unsigned long mask; |
2740 | 2740 |
2741 xgcv.background = s->face->background; | 2741 xgcv.background = s->face->background; |
2742 xgcv.foreground = s->face->foreground; | 2742 xgcv.foreground = s->face->foreground; |
2743 IF_DEBUG (x_check_font (s->f, s->font)); | 2743 IF_DEBUG (x_check_font (s->f, s->font)); |
2744 xgcv.font = s->font->fid; | 2744 xgcv.font = s->font->fid; |
2745 xgcv.graphics_exposures = False; | 2745 xgcv.graphics_exposures = False; |
2746 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; | 2746 mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; |
2747 | 2747 |
2748 if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc) | 2748 if (FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc) |
2749 XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc, | 2749 XChangeGC (s->display, FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc, |
2750 mask, &xgcv); | 2750 mask, &xgcv); |
2751 else | 2751 else |
2752 FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc | 2752 FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc |
2753 = XCreateGC (s->display, s->window, mask, &xgcv); | 2753 = XCreateGC (s->display, s->window, mask, &xgcv); |
2754 | 2754 |
2755 s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc; | 2755 s->gc = FRAME_X_DISPLAY_INFO (s->f)->scratch_cursor_gc; |
2756 } | 2756 } |
2757 | 2757 |
2758 xassert (s->gc != 0); | 2758 xassert (s->gc != 0); |
2759 } | 2759 } |
2764 matrix was built, so there isn't much to do, here. */ | 2764 matrix was built, so there isn't much to do, here. */ |
2765 | 2765 |
2766 static INLINE void | 2766 static INLINE void |
2767 x_set_mode_line_face_gc (s) | 2767 x_set_mode_line_face_gc (s) |
2768 struct glyph_string *s; | 2768 struct glyph_string *s; |
2769 { | 2769 { |
2770 s->gc = s->face->gc; | 2770 s->gc = s->face->gc; |
2771 } | 2771 } |
2772 | 2772 |
2773 | 2773 |
2774 /* Set S->gc of glyph string S for drawing that glyph string. Set | 2774 /* Set S->gc of glyph string S for drawing that glyph string. Set |
2778 static INLINE void | 2778 static INLINE void |
2779 x_set_glyph_string_gc (s) | 2779 x_set_glyph_string_gc (s) |
2780 struct glyph_string *s; | 2780 struct glyph_string *s; |
2781 { | 2781 { |
2782 PREPARE_FACE_FOR_DISPLAY (s->f, s->face); | 2782 PREPARE_FACE_FOR_DISPLAY (s->f, s->face); |
2783 | 2783 |
2784 if (s->hl == DRAW_NORMAL_TEXT) | 2784 if (s->hl == DRAW_NORMAL_TEXT) |
2785 { | 2785 { |
2786 s->gc = s->face->gc; | 2786 s->gc = s->face->gc; |
2787 s->stippled_p = s->face->stipple != 0; | 2787 s->stippled_p = s->face->stipple != 0; |
2788 } | 2788 } |
2827 { | 2827 { |
2828 if (s->row->full_width_p) | 2828 if (s->row->full_width_p) |
2829 { | 2829 { |
2830 /* Draw full-width. X coordinates are relative to S->w->left. */ | 2830 /* Draw full-width. X coordinates are relative to S->w->left. */ |
2831 int canon_x = CANON_X_UNIT (s->f); | 2831 int canon_x = CANON_X_UNIT (s->f); |
2832 | 2832 |
2833 r->x = WINDOW_LEFT_MARGIN (s->w) * canon_x; | 2833 r->x = WINDOW_LEFT_MARGIN (s->w) * canon_x; |
2834 r->width = XFASTINT (s->w->width) * canon_x; | 2834 r->width = XFASTINT (s->w->width) * canon_x; |
2835 | 2835 |
2836 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f)) | 2836 if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f)) |
2837 { | 2837 { |
2838 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x; | 2838 int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x; |
2839 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f)) | 2839 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f)) |
2840 r->x -= width; | 2840 r->x -= width; |
2841 } | 2841 } |
2842 | 2842 |
2843 r->x += FRAME_INTERNAL_BORDER_WIDTH (s->f); | 2843 r->x += FRAME_INTERNAL_BORDER_WIDTH (s->f); |
2844 | 2844 |
2845 /* Unless displaying a mode or menu bar line, which are always | 2845 /* Unless displaying a mode or menu bar line, which are always |
2846 fully visible, clip to the visible part of the row. */ | 2846 fully visible, clip to the visible part of the row. */ |
2847 if (s->w->pseudo_window_p) | 2847 if (s->w->pseudo_window_p) |
2848 r->height = s->row->visible_height; | 2848 r->height = s->row->visible_height; |
2849 else | 2849 else |
2920 | 2920 |
2921 | 2921 |
2922 /* Compute overhangs and x-positions for glyph string S and its | 2922 /* Compute overhangs and x-positions for glyph string S and its |
2923 predecessors, or successors. X is the starting x-position for S. | 2923 predecessors, or successors. X is the starting x-position for S. |
2924 BACKWARD_P non-zero means process predecessors. */ | 2924 BACKWARD_P non-zero means process predecessors. */ |
2925 | 2925 |
2926 static void | 2926 static void |
2927 x_compute_overhangs_and_x (s, x, backward_p) | 2927 x_compute_overhangs_and_x (s, x, backward_p) |
2928 struct glyph_string *s; | 2928 struct glyph_string *s; |
2929 int x; | 2929 int x; |
2930 int backward_p; | 2930 int backward_p; |
2961 struct glyph *glyph; | 2961 struct glyph *glyph; |
2962 struct frame *f; | 2962 struct frame *f; |
2963 int *left, *right; | 2963 int *left, *right; |
2964 { | 2964 { |
2965 *left = *right = 0; | 2965 *left = *right = 0; |
2966 | 2966 |
2967 if (glyph->type == CHAR_GLYPH) | 2967 if (glyph->type == CHAR_GLYPH) |
2968 { | 2968 { |
2969 XFontStruct *font; | 2969 XFontStruct *font; |
2970 struct face *face; | 2970 struct face *face; |
2971 struct font_info *font_info; | 2971 struct font_info *font_info; |
2994 static int | 2994 static int |
2995 x_left_overwritten (s) | 2995 x_left_overwritten (s) |
2996 struct glyph_string *s; | 2996 struct glyph_string *s; |
2997 { | 2997 { |
2998 int k; | 2998 int k; |
2999 | 2999 |
3000 if (s->left_overhang) | 3000 if (s->left_overhang) |
3001 { | 3001 { |
3002 int x = 0, i; | 3002 int x = 0, i; |
3003 struct glyph *glyphs = s->row->glyphs[s->area]; | 3003 struct glyph *glyphs = s->row->glyphs[s->area]; |
3004 int first = s->first_glyph - glyphs; | 3004 int first = s->first_glyph - glyphs; |
3056 { | 3056 { |
3057 int x = 0, i; | 3057 int x = 0, i; |
3058 struct glyph *glyphs = s->row->glyphs[s->area]; | 3058 struct glyph *glyphs = s->row->glyphs[s->area]; |
3059 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | 3059 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); |
3060 int end = s->row->used[s->area]; | 3060 int end = s->row->used[s->area]; |
3061 | 3061 |
3062 for (i = first; i < end && s->right_overhang > x; ++i) | 3062 for (i = first; i < end && s->right_overhang > x; ++i) |
3063 x += glyphs[i].pixel_width; | 3063 x += glyphs[i].pixel_width; |
3064 | 3064 |
3065 k = i; | 3065 k = i; |
3066 } | 3066 } |
3281 Widget widget; | 3281 Widget widget; |
3282 { | 3282 { |
3283 struct x_display_info *dpyinfo; | 3283 struct x_display_info *dpyinfo; |
3284 Lisp_Object tail; | 3284 Lisp_Object tail; |
3285 struct frame *f; | 3285 struct frame *f; |
3286 | 3286 |
3287 dpyinfo = x_display_info_for_display (XtDisplay (widget)); | 3287 dpyinfo = x_display_info_for_display (XtDisplay (widget)); |
3288 | 3288 |
3289 /* Find the top-level shell of the widget. Note that this function | 3289 /* Find the top-level shell of the widget. Note that this function |
3290 can be called when the widget is not yet realized, so XtWindow | 3290 can be called when the widget is not yet realized, so XtWindow |
3291 (widget) == 0. That's the reason we can't simply use | 3291 (widget) == 0. That's the reason we can't simply use |
3292 x_any_window_to_frame. */ | 3292 x_any_window_to_frame. */ |
3293 while (!XtIsTopLevelShell (widget)) | 3293 while (!XtIsTopLevelShell (widget)) |
3424 } | 3424 } |
3425 else | 3425 else |
3426 { | 3426 { |
3427 String params[1]; | 3427 String params[1]; |
3428 Cardinal nparams = 1; | 3428 Cardinal nparams = 1; |
3429 | 3429 |
3430 params[0] = color_name; | 3430 params[0] = color_name; |
3431 XtAppWarningMsg (XtDisplayToApplicationContext (dpy), | 3431 XtAppWarningMsg (XtDisplayToApplicationContext (dpy), |
3432 "badValue", "cvt_string_to_pixel", | 3432 "badValue", "cvt_string_to_pixel", |
3433 "XtToolkitError", "Invalid color `%s'", | 3433 "XtToolkitError", "Invalid color `%s'", |
3434 params, &nparams); | 3434 params, &nparams); |
3440 if (to->size < sizeof (Pixel)) | 3440 if (to->size < sizeof (Pixel)) |
3441 { | 3441 { |
3442 to->size = sizeof (Pixel); | 3442 to->size = sizeof (Pixel); |
3443 return False; | 3443 return False; |
3444 } | 3444 } |
3445 | 3445 |
3446 *(Pixel *) to->addr = pixel; | 3446 *(Pixel *) to->addr = pixel; |
3447 } | 3447 } |
3448 else | 3448 else |
3449 { | 3449 { |
3450 cvt_string_to_pixel_value = pixel; | 3450 cvt_string_to_pixel_value = pixel; |
3451 to->addr = (XtPointer) &cvt_string_to_pixel_value; | 3451 to->addr = (XtPointer) &cvt_string_to_pixel_value; |
3452 } | 3452 } |
3453 | 3453 |
3454 to->size = sizeof (Pixel); | 3454 to->size = sizeof (Pixel); |
3455 return True; | 3455 return True; |
3456 } | 3456 } |
3457 | 3457 |
3458 | 3458 |
3511 | 3511 |
3512 if (dpyinfo->color_cells == NULL) | 3512 if (dpyinfo->color_cells == NULL) |
3513 { | 3513 { |
3514 Screen *screen = dpyinfo->screen; | 3514 Screen *screen = dpyinfo->screen; |
3515 int i; | 3515 int i; |
3516 | 3516 |
3517 dpyinfo->ncolor_cells | 3517 dpyinfo->ncolor_cells |
3518 = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); | 3518 = XDisplayCells (dpy, XScreenNumberOfScreen (screen)); |
3519 dpyinfo->color_cells | 3519 dpyinfo->color_cells |
3520 = (XColor *) xmalloc (dpyinfo->ncolor_cells | 3520 = (XColor *) xmalloc (dpyinfo->ncolor_cells |
3521 * sizeof *dpyinfo->color_cells); | 3521 * sizeof *dpyinfo->color_cells); |
3522 | 3522 |
3523 for (i = 0; i < dpyinfo->ncolor_cells; ++i) | 3523 for (i = 0; i < dpyinfo->ncolor_cells; ++i) |
3524 dpyinfo->color_cells[i].pixel = i; | 3524 dpyinfo->color_cells[i].pixel = i; |
3525 | 3525 |
3526 XQueryColors (dpy, dpyinfo->cmap, | 3526 XQueryColors (dpy, dpyinfo->cmap, |
3527 dpyinfo->color_cells, dpyinfo->ncolor_cells); | 3527 dpyinfo->color_cells, dpyinfo->ncolor_cells); |
3528 } | 3528 } |
3529 | 3529 |
3530 *ncells = dpyinfo->ncolor_cells; | 3530 *ncells = dpyinfo->ncolor_cells; |
3567 struct frame *f; | 3567 struct frame *f; |
3568 XColor *color; | 3568 XColor *color; |
3569 { | 3569 { |
3570 x_query_colors (f, color, 1); | 3570 x_query_colors (f, color, 1); |
3571 } | 3571 } |
3572 | 3572 |
3573 | 3573 |
3574 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an | 3574 /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an |
3575 exact match can't be allocated, try the nearest color available. | 3575 exact match can't be allocated, try the nearest color available. |
3576 Value is non-zero if successful. Set *COLOR to the color | 3576 Value is non-zero if successful. Set *COLOR to the color |
3577 allocated. */ | 3577 allocated. */ |
3607 { | 3607 { |
3608 nearest = i; | 3608 nearest = i; |
3609 nearest_delta = delta; | 3609 nearest_delta = delta; |
3610 } | 3610 } |
3611 } | 3611 } |
3612 | 3612 |
3613 color->red = cells[nearest].red; | 3613 color->red = cells[nearest].red; |
3614 color->green = cells[nearest].green; | 3614 color->green = cells[nearest].green; |
3615 color->blue = cells[nearest].blue; | 3615 color->blue = cells[nearest].blue; |
3616 rc = XAllocColor (dpy, cmap, color); | 3616 rc = XAllocColor (dpy, cmap, color); |
3617 } | 3617 } |
3620 /* If allocation succeeded, and the allocated pixel color is not | 3620 /* If allocation succeeded, and the allocated pixel color is not |
3621 equal to a cached pixel color recorded earlier, there was a | 3621 equal to a cached pixel color recorded earlier, there was a |
3622 change in the colormap, so clear the color cache. */ | 3622 change in the colormap, so clear the color cache. */ |
3623 struct x_display_info *dpyinfo = x_display_info_for_display (dpy); | 3623 struct x_display_info *dpyinfo = x_display_info_for_display (dpy); |
3624 XColor *cached_color; | 3624 XColor *cached_color; |
3625 | 3625 |
3626 if (dpyinfo->color_cells | 3626 if (dpyinfo->color_cells |
3627 && (cached_color = &dpyinfo->color_cells[color->pixel], | 3627 && (cached_color = &dpyinfo->color_cells[color->pixel], |
3628 (cached_color->red != color->red | 3628 (cached_color->red != color->red |
3629 || cached_color->blue != color->blue | 3629 || cached_color->blue != color->blue |
3630 || cached_color->green != color->green))) | 3630 || cached_color->green != color->green))) |
3637 | 3637 |
3638 #ifdef DEBUG_X_COLORS | 3638 #ifdef DEBUG_X_COLORS |
3639 if (rc) | 3639 if (rc) |
3640 register_color (color->pixel); | 3640 register_color (color->pixel); |
3641 #endif /* DEBUG_X_COLORS */ | 3641 #endif /* DEBUG_X_COLORS */ |
3642 | 3642 |
3643 return rc; | 3643 return rc; |
3644 } | 3644 } |
3645 | 3645 |
3646 | 3646 |
3647 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an | 3647 /* Allocate the color COLOR->pixel on frame F, colormap CMAP. If an |
3786 if (new.pixel == *pixel) | 3786 if (new.pixel == *pixel) |
3787 { | 3787 { |
3788 /* If we end up with the same color as before, try adding | 3788 /* If we end up with the same color as before, try adding |
3789 delta to the RGB values. */ | 3789 delta to the RGB values. */ |
3790 x_free_colors (f, &new.pixel, 1); | 3790 x_free_colors (f, &new.pixel, 1); |
3791 | 3791 |
3792 new.red = min (0xffff, delta + color.red); | 3792 new.red = min (0xffff, delta + color.red); |
3793 new.green = min (0xffff, delta + color.green); | 3793 new.green = min (0xffff, delta + color.green); |
3794 new.blue = min (0xffff, delta + color.blue); | 3794 new.blue = min (0xffff, delta + color.blue); |
3795 success_p = x_alloc_nearest_color (f, cmap, &new); | 3795 success_p = x_alloc_nearest_color (f, cmap, &new); |
3796 } | 3796 } |
3797 else | 3797 else |
3798 success_p = 1; | 3798 success_p = 1; |
3799 *pixel = new.pixel; | 3799 *pixel = new.pixel; |
3800 } | 3800 } |
3801 | 3801 |
3802 return success_p; | 3802 return success_p; |
3803 } | 3803 } |
3804 | 3804 |
3805 | 3805 |
3806 /* Set up the foreground color for drawing relief lines of glyph | 3806 /* Set up the foreground color for drawing relief lines of glyph |
3807 string S. RELIEF is a pointer to a struct relief containing the GC | 3807 string S. RELIEF is a pointer to a struct relief containing the GC |
3808 with which lines will be drawn. Use a color that is FACTOR or | 3808 with which lines will be drawn. Use a color that is FACTOR or |
3809 DELTA lighter or darker than the relief's background which is found | 3809 DELTA lighter or darker than the relief's background which is found |
3810 in S->f->output_data.x->relief_background. If such a color cannot | 3810 in S->f->output_data.x->relief_background. If such a color cannot |
3811 be allocated, use DEFAULT_PIXEL, instead. */ | 3811 be allocated, use DEFAULT_PIXEL, instead. */ |
3812 | 3812 |
3813 static void | 3813 static void |
3814 x_setup_relief_color (f, relief, factor, delta, default_pixel) | 3814 x_setup_relief_color (f, relief, factor, delta, default_pixel) |
3815 struct frame *f; | 3815 struct frame *f; |
3816 struct relief *relief; | 3816 struct relief *relief; |
3817 double factor; | 3817 double factor; |
3847 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta)) | 3847 && x_alloc_lighter_color (f, dpy, cmap, &pixel, factor, delta)) |
3848 { | 3848 { |
3849 relief->allocated_p = 1; | 3849 relief->allocated_p = 1; |
3850 xgcv.foreground = relief->pixel = pixel; | 3850 xgcv.foreground = relief->pixel = pixel; |
3851 } | 3851 } |
3852 | 3852 |
3853 if (relief->gc == 0) | 3853 if (relief->gc == 0) |
3854 { | 3854 { |
3855 xgcv.stipple = dpyinfo->gray; | 3855 xgcv.stipple = dpyinfo->gray; |
3856 mask |= GCStipple; | 3856 mask |= GCStipple; |
3857 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv); | 3857 relief->gc = XCreateGC (dpy, FRAME_X_WINDOW (f), mask, &xgcv); |
3877 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0)) | 3877 && !IMAGE_BACKGROUND_TRANSPARENT (s->img, s->f, 0)) |
3878 color = IMAGE_BACKGROUND (s->img, s->f, 0); | 3878 color = IMAGE_BACKGROUND (s->img, s->f, 0); |
3879 else | 3879 else |
3880 { | 3880 { |
3881 XGCValues xgcv; | 3881 XGCValues xgcv; |
3882 | 3882 |
3883 /* Get the background color of the face. */ | 3883 /* Get the background color of the face. */ |
3884 XGetGCValues (s->display, s->gc, GCBackground, &xgcv); | 3884 XGetGCValues (s->display, s->gc, GCBackground, &xgcv); |
3885 color = xgcv.background; | 3885 color = xgcv.background; |
3886 } | 3886 } |
3887 | 3887 |
3914 { | 3914 { |
3915 Display *dpy = FRAME_X_DISPLAY (f); | 3915 Display *dpy = FRAME_X_DISPLAY (f); |
3916 Window window = FRAME_X_WINDOW (f); | 3916 Window window = FRAME_X_WINDOW (f); |
3917 int i; | 3917 int i; |
3918 GC gc; | 3918 GC gc; |
3919 | 3919 |
3920 if (raised_p) | 3920 if (raised_p) |
3921 gc = f->output_data.x->white_relief.gc; | 3921 gc = f->output_data.x->white_relief.gc; |
3922 else | 3922 else |
3923 gc = f->output_data.x->black_relief.gc; | 3923 gc = f->output_data.x->black_relief.gc; |
3924 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); | 3924 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); |
3939 if (raised_p) | 3939 if (raised_p) |
3940 gc = f->output_data.x->black_relief.gc; | 3940 gc = f->output_data.x->black_relief.gc; |
3941 else | 3941 else |
3942 gc = f->output_data.x->white_relief.gc; | 3942 gc = f->output_data.x->white_relief.gc; |
3943 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); | 3943 XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted); |
3944 | 3944 |
3945 /* Bottom. */ | 3945 /* Bottom. */ |
3946 for (i = 0; i < width; ++i) | 3946 for (i = 0; i < width; ++i) |
3947 XDrawLine (dpy, window, gc, | 3947 XDrawLine (dpy, window, gc, |
3948 left_x + i * left_p, bottom_y - i, | 3948 left_x + i * left_p, bottom_y - i, |
3949 right_x + 1 - i * right_p, bottom_y - i); | 3949 right_x + 1 - i * right_p, bottom_y - i); |
3950 | 3950 |
3951 /* Right. */ | 3951 /* Right. */ |
3952 if (right_p) | 3952 if (right_p) |
3953 for (i = 0; i < width; ++i) | 3953 for (i = 0; i < width; ++i) |
3954 XDrawLine (dpy, window, gc, | 3954 XDrawLine (dpy, window, gc, |
3955 right_x - i, top_y + i + 1, right_x - i, bottom_y - i); | 3955 right_x - i, top_y + i + 1, right_x - i, bottom_y - i); |
3971 struct glyph_string *s; | 3971 struct glyph_string *s; |
3972 int left_x, top_y, right_x, bottom_y, left_p, right_p; | 3972 int left_x, top_y, right_x, bottom_y, left_p, right_p; |
3973 XRectangle *clip_rect; | 3973 XRectangle *clip_rect; |
3974 { | 3974 { |
3975 XGCValues xgcv; | 3975 XGCValues xgcv; |
3976 | 3976 |
3977 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); | 3977 XGetGCValues (s->display, s->gc, GCForeground, &xgcv); |
3978 XSetForeground (s->display, s->gc, s->face->box_color); | 3978 XSetForeground (s->display, s->gc, s->face->box_color); |
3979 XSetClipRectangles (s->display, s->gc, 0, 0, clip_rect, 1, Unsorted); | 3979 XSetClipRectangles (s->display, s->gc, 0, 0, clip_rect, 1, Unsorted); |
3980 | 3980 |
3981 /* Top. */ | 3981 /* Top. */ |
3982 XFillRectangle (s->display, s->window, s->gc, | 3982 XFillRectangle (s->display, s->window, s->gc, |
3983 left_x, top_y, right_x - left_x + 1, width); | 3983 left_x, top_y, right_x - left_x + 1, width); |
3984 | 3984 |
3985 /* Left. */ | 3985 /* Left. */ |
3988 left_x, top_y, width, bottom_y - top_y + 1); | 3988 left_x, top_y, width, bottom_y - top_y + 1); |
3989 | 3989 |
3990 /* Bottom. */ | 3990 /* Bottom. */ |
3991 XFillRectangle (s->display, s->window, s->gc, | 3991 XFillRectangle (s->display, s->window, s->gc, |
3992 left_x, bottom_y - width + 1, right_x - left_x + 1, width); | 3992 left_x, bottom_y - width + 1, right_x - left_x + 1, width); |
3993 | 3993 |
3994 /* Right. */ | 3994 /* Right. */ |
3995 if (right_p) | 3995 if (right_p) |
3996 XFillRectangle (s->display, s->window, s->gc, | 3996 XFillRectangle (s->display, s->window, s->gc, |
3997 right_x - width + 1, top_y, width, bottom_y - top_y + 1); | 3997 right_x - width + 1, top_y, width, bottom_y - top_y + 1); |
3998 | 3998 |
4018 { | 4018 { |
4019 last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f); | 4019 last_x += FRAME_X_RIGHT_FRINGE_WIDTH (s->f); |
4020 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f)) | 4020 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f)) |
4021 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f); | 4021 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f); |
4022 } | 4022 } |
4023 | 4023 |
4024 /* The glyph that may have a right box line. */ | 4024 /* The glyph that may have a right box line. */ |
4025 last_glyph = (s->cmp || s->img | 4025 last_glyph = (s->cmp || s->img |
4026 ? s->first_glyph | 4026 ? s->first_glyph |
4027 : s->first_glyph + s->nchars - 1); | 4027 : s->first_glyph + s->nchars - 1); |
4028 | 4028 |
4097 xgcv.clip_mask = s->img->mask; | 4097 xgcv.clip_mask = s->img->mask; |
4098 xgcv.clip_x_origin = x; | 4098 xgcv.clip_x_origin = x; |
4099 xgcv.clip_y_origin = y; | 4099 xgcv.clip_y_origin = y; |
4100 xgcv.function = GXcopy; | 4100 xgcv.function = GXcopy; |
4101 XChangeGC (s->display, s->gc, mask, &xgcv); | 4101 XChangeGC (s->display, s->gc, mask, &xgcv); |
4102 | 4102 |
4103 x_get_glyph_string_clip_rect (s, &clip_rect); | 4103 x_get_glyph_string_clip_rect (s, &clip_rect); |
4104 image_rect.x = x; | 4104 image_rect.x = x; |
4105 image_rect.y = y; | 4105 image_rect.y = y; |
4106 image_rect.width = s->img->width; | 4106 image_rect.width = s->img->width; |
4107 image_rect.height = s->img->height; | 4107 image_rect.height = s->img->height; |
4119 image_rect.width = s->img->width; | 4119 image_rect.width = s->img->width; |
4120 image_rect.height = s->img->height; | 4120 image_rect.height = s->img->height; |
4121 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) | 4121 if (x_intersect_rectangles (&clip_rect, &image_rect, &r)) |
4122 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, | 4122 XCopyArea (s->display, s->img->pixmap, s->window, s->gc, |
4123 r.x - x, r.y - y, r.width, r.height, r.x, r.y); | 4123 r.x - x, r.y - y, r.width, r.height, r.x, r.y); |
4124 | 4124 |
4125 /* When the image has a mask, we can expect that at | 4125 /* When the image has a mask, we can expect that at |
4126 least part of a mouse highlight or a block cursor will | 4126 least part of a mouse highlight or a block cursor will |
4127 be visible. If the image doesn't have a mask, make | 4127 be visible. If the image doesn't have a mask, make |
4128 a block cursor visible by drawing a rectangle around | 4128 a block cursor visible by drawing a rectangle around |
4129 the image. I believe it's looking better if we do | 4129 the image. I believe it's looking better if we do |
4152 { | 4152 { |
4153 int x0, y0, x1, y1, thick, raised_p; | 4153 int x0, y0, x1, y1, thick, raised_p; |
4154 XRectangle r; | 4154 XRectangle r; |
4155 int x; | 4155 int x; |
4156 int y = s->ybase - image_ascent (s->img, s->face); | 4156 int y = s->ybase - image_ascent (s->img, s->face); |
4157 | 4157 |
4158 /* If first glyph of S has a left box line, start drawing it to the | 4158 /* If first glyph of S has a left box line, start drawing it to the |
4159 right of that line. */ | 4159 right of that line. */ |
4160 if (s->face->box != FACE_NO_BOX | 4160 if (s->face->box != FACE_NO_BOX |
4161 && s->first_glyph->left_box_line_p) | 4161 && s->first_glyph->left_box_line_p) |
4162 x = s->x + abs (s->face->box_line_width); | 4162 x = s->x + abs (s->face->box_line_width); |
4163 else | 4163 else |
4164 x = s->x; | 4164 x = s->x; |
4165 | 4165 |
4166 /* If there is a margin around the image, adjust x- and y-position | 4166 /* If there is a margin around the image, adjust x- and y-position |
4167 by that margin. */ | 4167 by that margin. */ |
4168 x += s->img->hmargin; | 4168 x += s->img->hmargin; |
4169 y += s->img->vmargin; | 4169 y += s->img->vmargin; |
4170 | 4170 |
4171 if (s->hl == DRAW_IMAGE_SUNKEN | 4171 if (s->hl == DRAW_IMAGE_SUNKEN |
4172 || s->hl == DRAW_IMAGE_RAISED) | 4172 || s->hl == DRAW_IMAGE_RAISED) |
4173 { | 4173 { |
4174 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF; | 4174 thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : DEFAULT_TOOL_BAR_BUTTON_RELIEF; |
4175 raised_p = s->hl == DRAW_IMAGE_RAISED; | 4175 raised_p = s->hl == DRAW_IMAGE_RAISED; |
4177 else | 4177 else |
4178 { | 4178 { |
4179 thick = abs (s->img->relief); | 4179 thick = abs (s->img->relief); |
4180 raised_p = s->img->relief > 0; | 4180 raised_p = s->img->relief > 0; |
4181 } | 4181 } |
4182 | 4182 |
4183 x0 = x - thick; | 4183 x0 = x - thick; |
4184 y0 = y - thick; | 4184 y0 = y - thick; |
4185 x1 = x + s->img->width + thick - 1; | 4185 x1 = x + s->img->width + thick - 1; |
4186 y1 = y + s->img->height + thick - 1; | 4186 y1 = y + s->img->height + thick - 1; |
4187 | 4187 |
4188 x_setup_relief_colors (s); | 4188 x_setup_relief_colors (s); |
4189 x_get_glyph_string_clip_rect (s, &r); | 4189 x_get_glyph_string_clip_rect (s, &r); |
4190 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); | 4190 x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r); |
4191 } | 4191 } |
4192 | 4192 |
4239 } | 4239 } |
4240 else | 4240 else |
4241 { | 4241 { |
4242 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, | 4242 XCopyArea (s->display, s->img->pixmap, pixmap, s->gc, |
4243 0, 0, s->img->width, s->img->height, x, y); | 4243 0, 0, s->img->width, s->img->height, x, y); |
4244 | 4244 |
4245 /* When the image has a mask, we can expect that at | 4245 /* When the image has a mask, we can expect that at |
4246 least part of a mouse highlight or a block cursor will | 4246 least part of a mouse highlight or a block cursor will |
4247 be visible. If the image doesn't have a mask, make | 4247 be visible. If the image doesn't have a mask, make |
4248 a block cursor visible by drawing a rectangle around | 4248 a block cursor visible by drawing a rectangle around |
4249 the image. I believe it's looking better if we do | 4249 the image. I believe it's looking better if we do |
4282 else | 4282 else |
4283 x_clear_glyph_string_rect (s, x, y, w, h); | 4283 x_clear_glyph_string_rect (s, x, y, w, h); |
4284 } | 4284 } |
4285 | 4285 |
4286 | 4286 |
4287 /* Draw image glyph string S. | 4287 /* Draw image glyph string S. |
4288 | 4288 |
4289 s->y | 4289 s->y |
4290 s->x +------------------------- | 4290 s->x +------------------------- |
4291 | s->face->box | 4291 | s->face->box |
4292 | | 4292 | |
4323 { | 4323 { |
4324 if (box_line_hwidth && s->first_glyph->left_box_line_p) | 4324 if (box_line_hwidth && s->first_glyph->left_box_line_p) |
4325 x = s->x + box_line_hwidth; | 4325 x = s->x + box_line_hwidth; |
4326 else | 4326 else |
4327 x = s->x; | 4327 x = s->x; |
4328 | 4328 |
4329 y = s->y + box_line_vwidth; | 4329 y = s->y + box_line_vwidth; |
4330 | 4330 |
4331 if (s->img->mask) | 4331 if (s->img->mask) |
4332 { | 4332 { |
4333 /* Create a pixmap as large as the glyph string. Fill it | 4333 /* Create a pixmap as large as the glyph string. Fill it |
4334 with the background color. Copy the image to it, using | 4334 with the background color. Copy the image to it, using |
4335 its mask. Copy the temporary pixmap to the display. */ | 4335 its mask. Copy the temporary pixmap to the display. */ |
4338 | 4338 |
4339 /* Create a pixmap as large as the glyph string. */ | 4339 /* Create a pixmap as large as the glyph string. */ |
4340 pixmap = XCreatePixmap (s->display, s->window, | 4340 pixmap = XCreatePixmap (s->display, s->window, |
4341 s->background_width, | 4341 s->background_width, |
4342 s->height, depth); | 4342 s->height, depth); |
4343 | 4343 |
4344 /* Don't clip in the following because we're working on the | 4344 /* Don't clip in the following because we're working on the |
4345 pixmap. */ | 4345 pixmap. */ |
4346 XSetClipMask (s->display, s->gc, None); | 4346 XSetClipMask (s->display, s->gc, None); |
4347 | 4347 |
4348 /* Fill the pixmap with the background color/stipple. */ | 4348 /* Fill the pixmap with the background color/stipple. */ |
4365 XSetForeground (s->display, s->gc, xgcv.foreground); | 4365 XSetForeground (s->display, s->gc, xgcv.foreground); |
4366 } | 4366 } |
4367 } | 4367 } |
4368 else | 4368 else |
4369 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); | 4369 x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height); |
4370 | 4370 |
4371 s->background_filled_p = 1; | 4371 s->background_filled_p = 1; |
4372 } | 4372 } |
4373 | 4373 |
4374 /* Draw the foreground. */ | 4374 /* Draw the foreground. */ |
4375 if (pixmap != None) | 4375 if (pixmap != None) |
4424 x_set_mouse_face_gc (s); | 4424 x_set_mouse_face_gc (s); |
4425 gc = s->gc; | 4425 gc = s->gc; |
4426 } | 4426 } |
4427 else | 4427 else |
4428 gc = s->face->gc; | 4428 gc = s->face->gc; |
4429 | 4429 |
4430 x_get_glyph_string_clip_rect (s, &r); | 4430 x_get_glyph_string_clip_rect (s, &r); |
4431 XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted); | 4431 XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted); |
4432 | 4432 |
4433 if (s->face->stipple) | 4433 if (s->face->stipple) |
4434 { | 4434 { |
4435 /* Fill background with a stipple pattern. */ | 4435 /* Fill background with a stipple pattern. */ |
4436 XSetFillStyle (s->display, gc, FillOpaqueStippled); | 4436 XSetFillStyle (s->display, gc, FillOpaqueStippled); |
4437 XFillRectangle (s->display, s->window, gc, x, y, w, h); | 4437 XFillRectangle (s->display, s->window, gc, x, y, w, h); |
4448 } | 4448 } |
4449 } | 4449 } |
4450 else if (!s->background_filled_p) | 4450 else if (!s->background_filled_p) |
4451 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width, | 4451 x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width, |
4452 s->height); | 4452 s->height); |
4453 | 4453 |
4454 s->background_filled_p = 1; | 4454 s->background_filled_p = 1; |
4455 } | 4455 } |
4456 | 4456 |
4457 | 4457 |
4458 /* Draw glyph string S. */ | 4458 /* Draw glyph string S. */ |
4541 the underline. This is a signed value according to the | 4541 the underline. This is a signed value according to the |
4542 specs, and its default is | 4542 specs, and its default is |
4543 | 4543 |
4544 ROUND ((maximum descent) / 2), with | 4544 ROUND ((maximum descent) / 2), with |
4545 ROUND(x) = floor (x + 0.5) */ | 4545 ROUND(x) = floor (x + 0.5) */ |
4546 | 4546 |
4547 if (x_use_underline_position_properties | 4547 if (x_use_underline_position_properties |
4548 && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem)) | 4548 && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem)) |
4549 y = s->ybase + (long) tem; | 4549 y = s->ybase + (long) tem; |
4550 else if (s->face->font) | 4550 else if (s->face->font) |
4551 y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2; | 4551 y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2; |
4552 else | 4552 else |
4553 y = s->y + s->height - h; | 4553 y = s->y + s->height - h; |
4554 | 4554 |
4555 if (s->face->underline_defaulted_p) | 4555 if (s->face->underline_defaulted_p) |
4556 XFillRectangle (s->display, s->window, s->gc, | 4556 XFillRectangle (s->display, s->window, s->gc, |
4557 s->x, y, s->width, h); | 4557 s->x, y, s->width, h); |
4558 else | 4558 else |
4559 { | 4559 { |
4582 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, | 4582 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, |
4583 s->width, h); | 4583 s->width, h); |
4584 XSetForeground (s->display, s->gc, xgcv.foreground); | 4584 XSetForeground (s->display, s->gc, xgcv.foreground); |
4585 } | 4585 } |
4586 } | 4586 } |
4587 | 4587 |
4588 /* Draw strike-through. */ | 4588 /* Draw strike-through. */ |
4589 if (s->face->strike_through_p) | 4589 if (s->face->strike_through_p) |
4590 { | 4590 { |
4591 unsigned long h = 1; | 4591 unsigned long h = 1; |
4592 unsigned long dy = (s->height - h) / 2; | 4592 unsigned long dy = (s->height - h) / 2; |
4602 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, | 4602 XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy, |
4603 s->width, h); | 4603 s->width, h); |
4604 XSetForeground (s->display, s->gc, xgcv.foreground); | 4604 XSetForeground (s->display, s->gc, xgcv.foreground); |
4605 } | 4605 } |
4606 } | 4606 } |
4607 | 4607 |
4608 /* Draw relief if not yet drawn. */ | 4608 /* Draw relief if not yet drawn. */ |
4609 if (!relief_drawn_p && s->face->box != FACE_NO_BOX) | 4609 if (!relief_drawn_p && s->face->box != FACE_NO_BOX) |
4610 x_draw_glyph_string_box (s); | 4610 x_draw_glyph_string_box (s); |
4611 } | 4611 } |
4612 | 4612 |
4613 /* Reset clipping. */ | 4613 /* Reset clipping. */ |
4614 XSetClipMask (s->display, s->gc, None); | 4614 XSetClipMask (s->display, s->gc, None); |
4615 } | 4615 } |
4616 | 4616 |
4617 | 4617 |
4618 static int x_fill_composite_glyph_string P_ ((struct glyph_string *, | 4618 static int x_fill_composite_glyph_string P_ ((struct glyph_string *, |
4619 struct face **, int)); | 4619 struct face **, int)); |
4620 | 4620 |
4621 | 4621 |
4622 /* Fill glyph string S with composition components specified by S->cmp. | 4622 /* Fill glyph string S with composition components specified by S->cmp. |
4623 | 4623 |
4624 FACES is an array of faces for all components of this composition. | 4624 FACES is an array of faces for all components of this composition. |
4625 S->gidx is the index of the first component for S. | 4625 S->gidx is the index of the first component for S. |
4626 OVERLAPS_P non-zero means S should draw the foreground only, and | 4626 OVERLAPS_P non-zero means S should draw the foreground only, and |
4627 use its physical height for clipping. | 4627 use its physical height for clipping. |
4628 | 4628 |
4637 int i; | 4637 int i; |
4638 | 4638 |
4639 xassert (s); | 4639 xassert (s); |
4640 | 4640 |
4641 s->for_overlaps_p = overlaps_p; | 4641 s->for_overlaps_p = overlaps_p; |
4642 | 4642 |
4643 s->face = faces[s->gidx]; | 4643 s->face = faces[s->gidx]; |
4644 s->font = s->face->font; | 4644 s->font = s->face->font; |
4645 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | 4645 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); |
4646 | 4646 |
4647 /* For all glyphs of this composition, starting at the offset | 4647 /* For all glyphs of this composition, starting at the offset |
4666 s->font = FRAME_FONT (s->f); | 4666 s->font = FRAME_FONT (s->f); |
4667 } | 4667 } |
4668 | 4668 |
4669 /* Adjust base line for subscript/superscript text. */ | 4669 /* Adjust base line for subscript/superscript text. */ |
4670 s->ybase += s->first_glyph->voffset; | 4670 s->ybase += s->first_glyph->voffset; |
4671 | 4671 |
4672 xassert (s->face && s->face->gc); | 4672 xassert (s->face && s->face->gc); |
4673 | 4673 |
4674 /* This glyph string must always be drawn with 16-bit functions. */ | 4674 /* This glyph string must always be drawn with 16-bit functions. */ |
4675 s->two_byte_p = 1; | 4675 s->two_byte_p = 1; |
4676 | 4676 |
4677 return s->gidx + s->nchars; | 4677 return s->gidx + s->nchars; |
4678 } | 4678 } |
4679 | 4679 |
4680 | 4680 |
4681 /* Fill glyph string S from a sequence of character glyphs. | 4681 /* Fill glyph string S from a sequence of character glyphs. |
4682 | 4682 |
4683 FACE_ID is the face id of the string. START is the index of the | 4683 FACE_ID is the face id of the string. START is the index of the |
4684 first glyph to consider, END is the index of the last + 1. | 4684 first glyph to consider, END is the index of the last + 1. |
4685 OVERLAPS_P non-zero means S should draw the foreground only, and | 4685 OVERLAPS_P non-zero means S should draw the foreground only, and |
4686 use its physical height for clipping. | 4686 use its physical height for clipping. |
4687 | 4687 |
4694 int start, end, overlaps_p; | 4694 int start, end, overlaps_p; |
4695 { | 4695 { |
4696 struct glyph *glyph, *last; | 4696 struct glyph *glyph, *last; |
4697 int voffset; | 4697 int voffset; |
4698 int glyph_not_available_p; | 4698 int glyph_not_available_p; |
4699 | 4699 |
4700 xassert (s->f == XFRAME (s->w->frame)); | 4700 xassert (s->f == XFRAME (s->w->frame)); |
4701 xassert (s->nchars == 0); | 4701 xassert (s->nchars == 0); |
4702 xassert (start >= 0 && end > start); | 4702 xassert (start >= 0 && end > start); |
4703 | 4703 |
4704 s->for_overlaps_p = overlaps_p, | 4704 s->for_overlaps_p = overlaps_p, |
4705 glyph = s->row->glyphs[s->area] + start; | 4705 glyph = s->row->glyphs[s->area] + start; |
4706 last = s->row->glyphs[s->area] + end; | 4706 last = s->row->glyphs[s->area] + end; |
4707 voffset = glyph->voffset; | 4707 voffset = glyph->voffset; |
4708 | 4708 |
4709 glyph_not_available_p = glyph->glyph_not_available_p; | 4709 glyph_not_available_p = glyph->glyph_not_available_p; |
4710 | 4710 |
4711 while (glyph < last | 4711 while (glyph < last |
4712 && glyph->type == CHAR_GLYPH | 4712 && glyph->type == CHAR_GLYPH |
4713 && glyph->voffset == voffset | 4713 && glyph->voffset == voffset |
4727 ++glyph; | 4727 ++glyph; |
4728 } | 4728 } |
4729 | 4729 |
4730 s->font = s->face->font; | 4730 s->font = s->face->font; |
4731 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | 4731 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); |
4732 | 4732 |
4733 /* If the specified font could not be loaded, use the frame's font, | 4733 /* If the specified font could not be loaded, use the frame's font, |
4734 but record the fact that we couldn't load it in | 4734 but record the fact that we couldn't load it in |
4735 S->font_not_found_p so that we can draw rectangles for the | 4735 S->font_not_found_p so that we can draw rectangles for the |
4736 characters of the glyph string. */ | 4736 characters of the glyph string. */ |
4737 if (s->font == NULL || glyph_not_available_p) | 4737 if (s->font == NULL || glyph_not_available_p) |
4758 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); | 4758 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); |
4759 xassert (s->img); | 4759 xassert (s->img); |
4760 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | 4760 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); |
4761 s->font = s->face->font; | 4761 s->font = s->face->font; |
4762 s->width = s->first_glyph->pixel_width; | 4762 s->width = s->first_glyph->pixel_width; |
4763 | 4763 |
4764 /* Adjust base line for subscript/superscript text. */ | 4764 /* Adjust base line for subscript/superscript text. */ |
4765 s->ybase += s->first_glyph->voffset; | 4765 s->ybase += s->first_glyph->voffset; |
4766 } | 4766 } |
4767 | 4767 |
4768 | 4768 |
4781 enum glyph_row_area area; | 4781 enum glyph_row_area area; |
4782 int start, end; | 4782 int start, end; |
4783 { | 4783 { |
4784 struct glyph *glyph, *last; | 4784 struct glyph *glyph, *last; |
4785 int voffset, face_id; | 4785 int voffset, face_id; |
4786 | 4786 |
4787 xassert (s->first_glyph->type == STRETCH_GLYPH); | 4787 xassert (s->first_glyph->type == STRETCH_GLYPH); |
4788 | 4788 |
4789 glyph = s->row->glyphs[s->area] + start; | 4789 glyph = s->row->glyphs[s->area] + start; |
4790 last = s->row->glyphs[s->area] + end; | 4790 last = s->row->glyphs[s->area] + end; |
4791 face_id = glyph->face_id; | 4791 face_id = glyph->face_id; |
4792 s->face = FACE_FROM_ID (s->f, face_id); | 4792 s->face = FACE_FROM_ID (s->f, face_id); |
4793 s->font = s->face->font; | 4793 s->font = s->face->font; |
4800 && glyph->type == STRETCH_GLYPH | 4800 && glyph->type == STRETCH_GLYPH |
4801 && glyph->voffset == voffset | 4801 && glyph->voffset == voffset |
4802 && glyph->face_id == face_id); | 4802 && glyph->face_id == face_id); |
4803 ++glyph) | 4803 ++glyph) |
4804 s->width += glyph->pixel_width; | 4804 s->width += glyph->pixel_width; |
4805 | 4805 |
4806 /* Adjust base line for subscript/superscript text. */ | 4806 /* Adjust base line for subscript/superscript text. */ |
4807 s->ybase += voffset; | 4807 s->ybase += voffset; |
4808 | 4808 |
4809 /* The case that face->gc == 0 is handled when drawing the glyph | 4809 /* The case that face->gc == 0 is handled when drawing the glyph |
4810 string by calling PREPARE_FACE_FOR_DISPLAY. */ | 4810 string by calling PREPARE_FACE_FOR_DISPLAY. */ |
4818 x_init_glyph_string because it must be allocated via `alloca'. W | 4818 x_init_glyph_string because it must be allocated via `alloca'. W |
4819 is the window on which S is drawn. ROW and AREA are the glyph row | 4819 is the window on which S is drawn. ROW and AREA are the glyph row |
4820 and area within the row from which S is constructed. START is the | 4820 and area within the row from which S is constructed. START is the |
4821 index of the first glyph structure covered by S. HL is a | 4821 index of the first glyph structure covered by S. HL is a |
4822 face-override for drawing S. */ | 4822 face-override for drawing S. */ |
4823 | 4823 |
4824 static void | 4824 static void |
4825 x_init_glyph_string (s, char2b, w, row, area, start, hl) | 4825 x_init_glyph_string (s, char2b, w, row, area, start, hl) |
4826 struct glyph_string *s; | 4826 struct glyph_string *s; |
4827 XChar2b *char2b; | 4827 XChar2b *char2b; |
4828 struct window *w; | 4828 struct window *w; |
4845 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | 4845 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); |
4846 | 4846 |
4847 /* Display the internal border below the tool-bar window. */ | 4847 /* Display the internal border below the tool-bar window. */ |
4848 if (s->w == XWINDOW (s->f->tool_bar_window)) | 4848 if (s->w == XWINDOW (s->f->tool_bar_window)) |
4849 s->y -= s->f->output_data.x->internal_border_width; | 4849 s->y -= s->f->output_data.x->internal_border_width; |
4850 | 4850 |
4851 s->ybase = s->y + row->ascent; | 4851 s->ybase = s->y + row->ascent; |
4852 } | 4852 } |
4853 | 4853 |
4854 | 4854 |
4855 /* Set background width of glyph string S. START is the index of the | 4855 /* Set background width of glyph string S. START is the index of the |
4863 int last_x; | 4863 int last_x; |
4864 { | 4864 { |
4865 /* If the face of this glyph string has to be drawn to the end of | 4865 /* If the face of this glyph string has to be drawn to the end of |
4866 the drawing area, set S->extends_to_end_of_line_p. */ | 4866 the drawing area, set S->extends_to_end_of_line_p. */ |
4867 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); | 4867 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); |
4868 | 4868 |
4869 if (start == s->row->used[s->area] | 4869 if (start == s->row->used[s->area] |
4870 && s->area == TEXT_AREA | 4870 && s->area == TEXT_AREA |
4871 && ((s->hl == DRAW_NORMAL_TEXT | 4871 && ((s->hl == DRAW_NORMAL_TEXT |
4872 && (s->row->fill_line_p | 4872 && (s->row->fill_line_p |
4873 || s->face->background != default_face->background | 4873 || s->face->background != default_face->background |
4875 || s->row->mouse_face_p)) | 4875 || s->row->mouse_face_p)) |
4876 || s->hl == DRAW_MOUSE_FACE | 4876 || s->hl == DRAW_MOUSE_FACE |
4877 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | 4877 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) |
4878 && s->row->fill_line_p))) | 4878 && s->row->fill_line_p))) |
4879 s->extends_to_end_of_line_p = 1; | 4879 s->extends_to_end_of_line_p = 1; |
4880 | 4880 |
4881 /* If S extends its face to the end of the line, set its | 4881 /* If S extends its face to the end of the line, set its |
4882 background_width to the distance to the right edge of the drawing | 4882 background_width to the distance to the right edge of the drawing |
4883 area. */ | 4883 area. */ |
4884 if (s->extends_to_end_of_line_p) | 4884 if (s->extends_to_end_of_line_p) |
4885 s->background_width = last_x - s->x + 1; | 4885 s->background_width = last_x - s->x + 1; |
4956 s->x = (X); \ | 4956 s->x = (X); \ |
4957 START = x_fill_glyph_string (s, face_id, START, END, \ | 4957 START = x_fill_glyph_string (s, face_id, START, END, \ |
4958 OVERLAPS_P); \ | 4958 OVERLAPS_P); \ |
4959 } \ | 4959 } \ |
4960 while (0) | 4960 while (0) |
4961 | 4961 |
4962 | 4962 |
4963 /* Add a glyph string for a composite sequence to the list of strings | 4963 /* Add a glyph string for a composite sequence to the list of strings |
4964 between HEAD and TAIL. START is the index of the first glyph in | 4964 between HEAD and TAIL. START is the index of the first glyph in |
4965 row area AREA of glyph row ROW that is part of the new glyph | 4965 row area AREA of glyph row ROW that is part of the new glyph |
4966 string. END is the index of the last glyph in that glyph row area. | 4966 string. END is the index of the last glyph in that glyph row area. |
5012 } \ | 5012 } \ |
5013 \ | 5013 \ |
5014 ++START; \ | 5014 ++START; \ |
5015 s = first_s; \ | 5015 s = first_s; \ |
5016 } while (0) | 5016 } while (0) |
5017 | 5017 |
5018 | 5018 |
5019 /* Build a list of glyph strings between HEAD and TAIL for the glyphs | 5019 /* Build a list of glyph strings between HEAD and TAIL for the glyphs |
5020 of AREA of glyph row ROW on window W between indices START and END. | 5020 of AREA of glyph row ROW on window W between indices START and END. |
5021 HL overrides the face for drawing glyph strings, e.g. it is | 5021 HL overrides the face for drawing glyph strings, e.g. it is |
5022 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end | 5022 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end |
5081 | 5081 |
5082 If OVERLAPS_P is non-zero, draw only the foreground of characters | 5082 If OVERLAPS_P is non-zero, draw only the foreground of characters |
5083 and clip to the physical height of ROW. | 5083 and clip to the physical height of ROW. |
5084 | 5084 |
5085 Value is the x-position reached, relative to AREA of W. */ | 5085 Value is the x-position reached, relative to AREA of W. */ |
5086 | 5086 |
5087 static int | 5087 static int |
5088 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | 5088 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) |
5089 struct window *w; | 5089 struct window *w; |
5090 int x; | 5090 int x; |
5091 struct glyph_row *row; | 5091 struct glyph_row *row; |
5162 x_compute_glyph_string_overhangs (s); | 5162 x_compute_glyph_string_overhangs (s); |
5163 | 5163 |
5164 /* Prepend glyph strings for glyphs in front of the first glyph | 5164 /* Prepend glyph strings for glyphs in front of the first glyph |
5165 string that are overwritten because of the first glyph | 5165 string that are overwritten because of the first glyph |
5166 string's left overhang. The background of all strings | 5166 string's left overhang. The background of all strings |
5167 prepended must be drawn because the first glyph string | 5167 prepended must be drawn because the first glyph string |
5168 draws over it. */ | 5168 draws over it. */ |
5169 i = x_left_overwritten (head); | 5169 i = x_left_overwritten (head); |
5170 if (i >= 0) | 5170 if (i >= 0) |
5171 { | 5171 { |
5172 j = i; | 5172 j = i; |
5240 completely. */ | 5240 completely. */ |
5241 && !overlaps_p) | 5241 && !overlaps_p) |
5242 { | 5242 { |
5243 int x0 = head ? head->x : x; | 5243 int x0 = head ? head->x : x; |
5244 int x1 = tail ? tail->x + tail->background_width : x; | 5244 int x1 = tail ? tail->x + tail->background_width : x; |
5245 | 5245 |
5246 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); | 5246 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); |
5247 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); | 5247 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); |
5248 | 5248 |
5249 if (XFASTINT (w->left_margin_width) != 0) | 5249 if (XFASTINT (w->left_margin_width) != 0) |
5250 { | 5250 { |
5251 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); | 5251 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); |
5252 x0 -= left_area_width; | 5252 x0 -= left_area_width; |
5253 x1 -= left_area_width; | 5253 x1 -= left_area_width; |
5265 if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0) | 5265 if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0) |
5266 x_reached -= window_box_width (w, LEFT_MARGIN_AREA); | 5266 x_reached -= window_box_width (w, LEFT_MARGIN_AREA); |
5267 if (area > TEXT_AREA) | 5267 if (area > TEXT_AREA) |
5268 x_reached -= window_box_width (w, TEXT_AREA); | 5268 x_reached -= window_box_width (w, TEXT_AREA); |
5269 } | 5269 } |
5270 | 5270 |
5271 return x_reached; | 5271 return x_reached; |
5272 } | 5272 } |
5273 | 5273 |
5274 | 5274 |
5275 /* Fix the display of area AREA of overlapping row ROW in window W. */ | 5275 /* Fix the display of area AREA of overlapping row ROW in window W. */ |
5279 struct window *w; | 5279 struct window *w; |
5280 struct glyph_row *row; | 5280 struct glyph_row *row; |
5281 enum glyph_row_area area; | 5281 enum glyph_row_area area; |
5282 { | 5282 { |
5283 int i, x; | 5283 int i, x; |
5284 | 5284 |
5285 BLOCK_INPUT; | 5285 BLOCK_INPUT; |
5286 | 5286 |
5287 if (area == LEFT_MARGIN_AREA) | 5287 if (area == LEFT_MARGIN_AREA) |
5288 x = 0; | 5288 x = 0; |
5289 else if (area == TEXT_AREA) | 5289 else if (area == TEXT_AREA) |
5290 x = row->x + window_box_width (w, LEFT_MARGIN_AREA); | 5290 x = row->x + window_box_width (w, LEFT_MARGIN_AREA); |
5291 else | 5291 else |
5313 { | 5313 { |
5314 x += row->glyphs[area][i].pixel_width; | 5314 x += row->glyphs[area][i].pixel_width; |
5315 ++i; | 5315 ++i; |
5316 } | 5316 } |
5317 } | 5317 } |
5318 | 5318 |
5319 UNBLOCK_INPUT; | 5319 UNBLOCK_INPUT; |
5320 } | 5320 } |
5321 | 5321 |
5322 | 5322 |
5323 /* Output LEN glyphs starting at START at the nominal cursor position. | 5323 /* Output LEN glyphs starting at START at the nominal cursor position. |
5333 { | 5333 { |
5334 int x, hpos; | 5334 int x, hpos; |
5335 | 5335 |
5336 xassert (updated_window && updated_row); | 5336 xassert (updated_window && updated_row); |
5337 BLOCK_INPUT; | 5337 BLOCK_INPUT; |
5338 | 5338 |
5339 /* Write glyphs. */ | 5339 /* Write glyphs. */ |
5340 | 5340 |
5341 hpos = start - updated_row->glyphs[updated_area]; | 5341 hpos = start - updated_row->glyphs[updated_area]; |
5342 x = x_draw_glyphs (updated_window, output_cursor.x, | 5342 x = x_draw_glyphs (updated_window, output_cursor.x, |
5343 updated_row, updated_area, | 5343 updated_row, updated_area, |
5351 && updated_window->phys_cursor.hpos >= hpos | 5351 && updated_window->phys_cursor.hpos >= hpos |
5352 && updated_window->phys_cursor.hpos < hpos + len) | 5352 && updated_window->phys_cursor.hpos < hpos + len) |
5353 updated_window->phys_cursor_on_p = 0; | 5353 updated_window->phys_cursor_on_p = 0; |
5354 | 5354 |
5355 UNBLOCK_INPUT; | 5355 UNBLOCK_INPUT; |
5356 | 5356 |
5357 /* Advance the output cursor. */ | 5357 /* Advance the output cursor. */ |
5358 output_cursor.hpos += len; | 5358 output_cursor.hpos += len; |
5359 output_cursor.x = x; | 5359 output_cursor.x = x; |
5360 } | 5360 } |
5361 | 5361 |
5404 | 5404 |
5405 /* Write the glyphs. */ | 5405 /* Write the glyphs. */ |
5406 hpos = start - row->glyphs[updated_area]; | 5406 hpos = start - row->glyphs[updated_area]; |
5407 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len, | 5407 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len, |
5408 DRAW_NORMAL_TEXT, 0); | 5408 DRAW_NORMAL_TEXT, 0); |
5409 | 5409 |
5410 /* Advance the output cursor. */ | 5410 /* Advance the output cursor. */ |
5411 output_cursor.hpos += len; | 5411 output_cursor.hpos += len; |
5412 output_cursor.x += shift_by_width; | 5412 output_cursor.x += shift_by_width; |
5413 UNBLOCK_INPUT; | 5413 UNBLOCK_INPUT; |
5414 } | 5414 } |
5454 { | 5454 { |
5455 struct frame *f; | 5455 struct frame *f; |
5456 struct window *w = updated_window; | 5456 struct window *w = updated_window; |
5457 int max_x, min_y, max_y; | 5457 int max_x, min_y, max_y; |
5458 int from_x, from_y, to_y; | 5458 int from_x, from_y, to_y; |
5459 | 5459 |
5460 xassert (updated_window && updated_row); | 5460 xassert (updated_window && updated_row); |
5461 f = XFRAME (w->frame); | 5461 f = XFRAME (w->frame); |
5462 | 5462 |
5463 if (updated_row->full_width_p) | 5463 if (updated_row->full_width_p) |
5464 { | 5464 { |
5465 max_x = XFASTINT (w->width) * CANON_X_UNIT (f); | 5465 max_x = XFASTINT (w->width) * CANON_X_UNIT (f); |
5466 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) | 5466 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) |
5467 && !w->pseudo_window_p) | 5467 && !w->pseudo_window_p) |
5479 to_x = max_x; | 5479 to_x = max_x; |
5480 else | 5480 else |
5481 to_x = min (to_x, max_x); | 5481 to_x = min (to_x, max_x); |
5482 | 5482 |
5483 to_y = min (max_y, output_cursor.y + updated_row->height); | 5483 to_y = min (max_y, output_cursor.y + updated_row->height); |
5484 | 5484 |
5485 /* Notice if the cursor will be cleared by this operation. */ | 5485 /* Notice if the cursor will be cleared by this operation. */ |
5486 if (!updated_row->full_width_p) | 5486 if (!updated_row->full_width_p) |
5487 notice_overwritten_cursor (w, updated_area, | 5487 notice_overwritten_cursor (w, updated_area, |
5488 output_cursor.x, -1, | 5488 output_cursor.x, -1, |
5489 updated_row->y, | 5489 updated_row->y, |
5490 MATRIX_ROW_BOTTOM_Y (updated_row)); | 5490 MATRIX_ROW_BOTTOM_Y (updated_row)); |
5491 | 5491 |
5492 from_x = output_cursor.x; | 5492 from_x = output_cursor.x; |
5493 | 5493 |
5494 /* Translate to frame coordinates. */ | 5494 /* Translate to frame coordinates. */ |
5495 if (updated_row->full_width_p) | 5495 if (updated_row->full_width_p) |
5496 { | 5496 { |
5497 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x); | 5497 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x); |
5498 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x); | 5498 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x); |
5500 else | 5500 else |
5501 { | 5501 { |
5502 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x); | 5502 from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x); |
5503 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x); | 5503 to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x); |
5504 } | 5504 } |
5505 | 5505 |
5506 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); | 5506 min_y = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (w); |
5507 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); | 5507 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y)); |
5508 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); | 5508 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y); |
5509 | 5509 |
5510 /* Prevent inadvertently clearing to end of the X window. */ | 5510 /* Prevent inadvertently clearing to end of the X window. */ |
5511 if (to_x > from_x && to_y > from_y) | 5511 if (to_x > from_x && to_y > from_y) |
5512 { | 5512 { |
5513 BLOCK_INPUT; | 5513 BLOCK_INPUT; |
5514 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 5514 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
5574 { | 5574 { |
5575 int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1; | 5575 int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1; |
5576 y.tv_usec -= 1000000 * nsec; | 5576 y.tv_usec -= 1000000 * nsec; |
5577 y.tv_sec += nsec; | 5577 y.tv_sec += nsec; |
5578 } | 5578 } |
5579 | 5579 |
5580 if (x.tv_usec - y.tv_usec > 1000000) | 5580 if (x.tv_usec - y.tv_usec > 1000000) |
5581 { | 5581 { |
5582 int nsec = (y.tv_usec - x.tv_usec) / 1000000; | 5582 int nsec = (y.tv_usec - x.tv_usec) / 1000000; |
5583 y.tv_usec += 1000000 * nsec; | 5583 y.tv_usec += 1000000 * nsec; |
5584 y.tv_sec -= nsec; | 5584 y.tv_sec -= nsec; |
5658 (height - flash_height | 5658 (height - flash_height |
5659 - FRAME_INTERNAL_BORDER_WIDTH (f)), | 5659 - FRAME_INTERNAL_BORDER_WIDTH (f)), |
5660 width, flash_height); | 5660 width, flash_height); |
5661 } | 5661 } |
5662 else | 5662 else |
5663 /* If it is short, flash it all. */ | 5663 /* If it is short, flash it all. */ |
5664 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, | 5664 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, |
5665 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), | 5665 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), |
5666 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); | 5666 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); |
5667 | 5667 |
5668 x_flush (f); | 5668 x_flush (f); |
5712 (height - flash_height | 5712 (height - flash_height |
5713 - FRAME_INTERNAL_BORDER_WIDTH (f)), | 5713 - FRAME_INTERNAL_BORDER_WIDTH (f)), |
5714 width, flash_height); | 5714 width, flash_height); |
5715 } | 5715 } |
5716 else | 5716 else |
5717 /* If it is short, flash it all. */ | 5717 /* If it is short, flash it all. */ |
5718 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, | 5718 XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc, |
5719 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), | 5719 flash_left, FRAME_INTERNAL_BORDER_WIDTH (f), |
5720 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); | 5720 width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); |
5721 | 5721 |
5722 XFreeGC (FRAME_X_DISPLAY (f), gc); | 5722 XFreeGC (FRAME_X_DISPLAY (f), gc); |
5734 | 5734 |
5735 void | 5735 void |
5736 XTring_bell () | 5736 XTring_bell () |
5737 { | 5737 { |
5738 struct frame *f = SELECTED_FRAME (); | 5738 struct frame *f = SELECTED_FRAME (); |
5739 | 5739 |
5740 if (FRAME_X_DISPLAY (f)) | 5740 if (FRAME_X_DISPLAY (f)) |
5741 { | 5741 { |
5742 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) | 5742 #if defined (HAVE_TIMEVAL) && defined (HAVE_SELECT) |
5743 if (visible_bell) | 5743 if (visible_bell) |
5744 XTflash (f); | 5744 XTflash (f); |
5822 else | 5822 else |
5823 height = run->height; | 5823 height = run->height; |
5824 } | 5824 } |
5825 | 5825 |
5826 BLOCK_INPUT; | 5826 BLOCK_INPUT; |
5827 | 5827 |
5828 /* Cursor off. Will be switched on again in x_update_window_end. */ | 5828 /* Cursor off. Will be switched on again in x_update_window_end. */ |
5829 updated_window = w; | 5829 updated_window = w; |
5830 x_clear_cursor (w); | 5830 x_clear_cursor (w); |
5831 | 5831 |
5832 XCopyArea (FRAME_X_DISPLAY (f), | 5832 XCopyArea (FRAME_X_DISPLAY (f), |
5833 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f), | 5833 FRAME_X_WINDOW (f), FRAME_X_WINDOW (f), |
5834 f->output_data.x->normal_gc, | 5834 f->output_data.x->normal_gc, |
5835 x, from_y, | 5835 x, from_y, |
5836 width, height, | 5836 width, height, |
5837 x, to_y); | 5837 x, to_y); |
5838 | 5838 |
5839 UNBLOCK_INPUT; | 5839 UNBLOCK_INPUT; |
5840 } | 5840 } |
5841 | 5841 |
5842 | 5842 |
5843 | 5843 |
5844 /*********************************************************************** | 5844 /*********************************************************************** |
5845 Exposure Events | 5845 Exposure Events |
5846 ***********************************************************************/ | 5846 ***********************************************************************/ |
5847 | 5847 |
5848 /* Redisplay an exposed area of frame F. X and Y are the upper-left | 5848 /* Redisplay an exposed area of frame F. X and Y are the upper-left |
5849 corner of the exposed rectangle. W and H are width and height of | 5849 corner of the exposed rectangle. W and H are width and height of |
5850 the exposed area. All are pixel values. W or H zero means redraw | 5850 the exposed area. All are pixel values. W or H zero means redraw |
5851 the entire frame. */ | 5851 the entire frame. */ |
5852 | 5852 |
5937 struct window *w; | 5937 struct window *w; |
5938 XRectangle *r; | 5938 XRectangle *r; |
5939 { | 5939 { |
5940 struct frame *f = XFRAME (w->frame); | 5940 struct frame *f = XFRAME (w->frame); |
5941 int mouse_face_overwritten_p = 0; | 5941 int mouse_face_overwritten_p = 0; |
5942 | 5942 |
5943 while (w && !FRAME_GARBAGED_P (f)) | 5943 while (w && !FRAME_GARBAGED_P (f)) |
5944 { | 5944 { |
5945 if (!NILP (w->hchild)) | 5945 if (!NILP (w->hchild)) |
5946 mouse_face_overwritten_p | 5946 mouse_face_overwritten_p |
5947 |= expose_window_tree (XWINDOW (w->hchild), r); | 5947 |= expose_window_tree (XWINDOW (w->hchild), r); |
5948 else if (!NILP (w->vchild)) | 5948 else if (!NILP (w->vchild)) |
5949 mouse_face_overwritten_p | 5949 mouse_face_overwritten_p |
5950 |= expose_window_tree (XWINDOW (w->vchild), r); | 5950 |= expose_window_tree (XWINDOW (w->vchild), r); |
5951 else | 5951 else |
5952 mouse_face_overwritten_p |= expose_window (w, r); | 5952 mouse_face_overwritten_p |= expose_window (w, r); |
5953 | 5953 |
5954 w = NILP (w->next) ? NULL : XWINDOW (w->next); | 5954 w = NILP (w->next) ? NULL : XWINDOW (w->next); |
5955 } | 5955 } |
5956 | 5956 |
5957 return mouse_face_overwritten_p; | 5957 return mouse_face_overwritten_p; |
5958 } | 5958 } |
5996 && x + first->pixel_width < r->x) | 5996 && x + first->pixel_width < r->x) |
5997 { | 5997 { |
5998 x += first->pixel_width; | 5998 x += first->pixel_width; |
5999 ++first; | 5999 ++first; |
6000 } | 6000 } |
6001 | 6001 |
6002 /* Find the last one. */ | 6002 /* Find the last one. */ |
6003 last = first; | 6003 last = first; |
6004 first_x = x; | 6004 first_x = x; |
6005 while (last < end | 6005 while (last < end |
6006 && x < r->x + r->width) | 6006 && x < r->x + r->width) |
6007 { | 6007 { |
6008 x += last->pixel_width; | 6008 x += last->pixel_width; |
6009 ++last; | 6009 ++last; |
6010 } | 6010 } |
6011 | 6011 |
6012 /* Repaint. */ | 6012 /* Repaint. */ |
6013 if (last > first) | 6013 if (last > first) |
6014 x_draw_glyphs (w, first_x - start_x, row, area, | 6014 x_draw_glyphs (w, first_x - start_x, row, area, |
6015 first - row->glyphs[area], | 6015 first - row->glyphs[area], |
6016 last - row->glyphs[area], | 6016 last - row->glyphs[area], |
6017 DRAW_NORMAL_TEXT, 0); | 6017 DRAW_NORMAL_TEXT, 0); |
6018 } | 6018 } |
6019 } | 6019 } |
6020 | 6020 |
6021 | 6021 |
6022 /* Redraw the parts of the glyph row ROW on window W intersecting | 6022 /* Redraw the parts of the glyph row ROW on window W intersecting |
6023 rectangle R. R is in window-relative coordinates. Value is | 6023 rectangle R. R is in window-relative coordinates. Value is |
6024 non-zero if mouse-face was overwritten. */ | 6024 non-zero if mouse-face was overwritten. */ |
6025 | 6025 |
6028 struct window *w; | 6028 struct window *w; |
6029 struct glyph_row *row; | 6029 struct glyph_row *row; |
6030 XRectangle *r; | 6030 XRectangle *r; |
6031 { | 6031 { |
6032 xassert (row->enabled_p); | 6032 xassert (row->enabled_p); |
6033 | 6033 |
6034 if (row->mode_line_p || w->pseudo_window_p) | 6034 if (row->mode_line_p || w->pseudo_window_p) |
6035 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA], | 6035 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA], |
6036 DRAW_NORMAL_TEXT, 0); | 6036 DRAW_NORMAL_TEXT, 0); |
6037 else | 6037 else |
6038 { | 6038 { |
6086 struct window *w; | 6086 struct window *w; |
6087 struct glyph_row *first_overlapping_row; | 6087 struct glyph_row *first_overlapping_row; |
6088 struct glyph_row *last_overlapping_row; | 6088 struct glyph_row *last_overlapping_row; |
6089 { | 6089 { |
6090 struct glyph_row *row; | 6090 struct glyph_row *row; |
6091 | 6091 |
6092 for (row = first_overlapping_row; row <= last_overlapping_row; ++row) | 6092 for (row = first_overlapping_row; row <= last_overlapping_row; ++row) |
6093 if (row->overlapping_p) | 6093 if (row->overlapping_p) |
6094 { | 6094 { |
6095 xassert (row->enabled_p && !row->mode_line_p); | 6095 xassert (row->enabled_p && !row->mode_line_p); |
6096 | 6096 |
6097 if (row->used[LEFT_MARGIN_AREA]) | 6097 if (row->used[LEFT_MARGIN_AREA]) |
6098 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA); | 6098 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA); |
6099 | 6099 |
6100 if (row->used[TEXT_AREA]) | 6100 if (row->used[TEXT_AREA]) |
6101 x_fix_overlapping_area (w, row, TEXT_AREA); | 6101 x_fix_overlapping_area (w, row, TEXT_AREA); |
6102 | 6102 |
6103 if (row->used[RIGHT_MARGIN_AREA]) | 6103 if (row->used[RIGHT_MARGIN_AREA]) |
6104 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA); | 6104 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA); |
6105 } | 6105 } |
6106 } | 6106 } |
6107 | 6107 |
6146 { | 6146 { |
6147 int yb = window_text_bottom_y (w); | 6147 int yb = window_text_bottom_y (w); |
6148 struct glyph_row *row; | 6148 struct glyph_row *row; |
6149 int cursor_cleared_p; | 6149 int cursor_cleared_p; |
6150 struct glyph_row *first_overlapping_row, *last_overlapping_row; | 6150 struct glyph_row *first_overlapping_row, *last_overlapping_row; |
6151 | 6151 |
6152 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", | 6152 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", |
6153 r.x, r.y, r.width, r.height)); | 6153 r.x, r.y, r.width, r.height)); |
6154 | 6154 |
6155 /* Convert to window coordinates. */ | 6155 /* Convert to window coordinates. */ |
6156 r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x); | 6156 r.x = FRAME_TO_WINDOW_PIXEL_X (w, r.x); |
6172 row->enabled_p; | 6172 row->enabled_p; |
6173 ++row) | 6173 ++row) |
6174 { | 6174 { |
6175 int y0 = row->y; | 6175 int y0 = row->y; |
6176 int y1 = MATRIX_ROW_BOTTOM_Y (row); | 6176 int y1 = MATRIX_ROW_BOTTOM_Y (row); |
6177 | 6177 |
6178 if ((y0 >= r.y && y0 < r.y + r.height) | 6178 if ((y0 >= r.y && y0 < r.y + r.height) |
6179 || (y1 > r.y && y1 < r.y + r.height) | 6179 || (y1 > r.y && y1 < r.y + r.height) |
6180 || (r.y >= y0 && r.y < y1) | 6180 || (r.y >= y0 && r.y < y1) |
6181 || (r.y + r.height > y0 && r.y + r.height < y1)) | 6181 || (r.y + r.height > y0 && r.y + r.height < y1)) |
6182 { | 6182 { |
6184 { | 6184 { |
6185 if (first_overlapping_row == NULL) | 6185 if (first_overlapping_row == NULL) |
6186 first_overlapping_row = row; | 6186 first_overlapping_row = row; |
6187 last_overlapping_row = row; | 6187 last_overlapping_row = row; |
6188 } | 6188 } |
6189 | 6189 |
6190 if (expose_line (w, row, &r)) | 6190 if (expose_line (w, row, &r)) |
6191 mouse_face_overwritten_p = 1; | 6191 mouse_face_overwritten_p = 1; |
6192 } | 6192 } |
6193 | 6193 |
6194 if (y1 >= yb) | 6194 if (y1 >= yb) |
6195 break; | 6195 break; |
6196 } | 6196 } |
6197 | 6197 |
6198 /* Display the mode line if there is one. */ | 6198 /* Display the mode line if there is one. */ |
6208 if (!w->pseudo_window_p) | 6208 if (!w->pseudo_window_p) |
6209 { | 6209 { |
6210 /* Fix the display of overlapping rows. */ | 6210 /* Fix the display of overlapping rows. */ |
6211 if (first_overlapping_row) | 6211 if (first_overlapping_row) |
6212 expose_overlaps (w, first_overlapping_row, last_overlapping_row); | 6212 expose_overlaps (w, first_overlapping_row, last_overlapping_row); |
6213 | 6213 |
6214 /* Draw border between windows. */ | 6214 /* Draw border between windows. */ |
6215 x_draw_vertical_border (w); | 6215 x_draw_vertical_border (w); |
6216 | 6216 |
6217 /* Turn the cursor on again. */ | 6217 /* Turn the cursor on again. */ |
6218 if (cursor_cleared_p) | 6218 if (cursor_cleared_p) |
6219 x_update_window_cursor (w, 1); | 6219 x_update_window_cursor (w, 1); |
6220 } | 6220 } |
6221 } | 6221 } |
6233 XRectangle *r1, *r2, *result; | 6233 XRectangle *r1, *r2, *result; |
6234 { | 6234 { |
6235 XRectangle *left, *right; | 6235 XRectangle *left, *right; |
6236 XRectangle *upper, *lower; | 6236 XRectangle *upper, *lower; |
6237 int intersection_p = 0; | 6237 int intersection_p = 0; |
6238 | 6238 |
6239 /* Rearrange so that R1 is the left-most rectangle. */ | 6239 /* Rearrange so that R1 is the left-most rectangle. */ |
6240 if (r1->x < r2->x) | 6240 if (r1->x < r2->x) |
6241 left = r1, right = r2; | 6241 left = r1, right = r2; |
6242 else | 6242 else |
6243 left = r2, right = r1; | 6243 left = r2, right = r1; |
6245 /* X0 of the intersection is right.x0, if this is inside R1, | 6245 /* X0 of the intersection is right.x0, if this is inside R1, |
6246 otherwise there is no intersection. */ | 6246 otherwise there is no intersection. */ |
6247 if (right->x <= left->x + left->width) | 6247 if (right->x <= left->x + left->width) |
6248 { | 6248 { |
6249 result->x = right->x; | 6249 result->x = right->x; |
6250 | 6250 |
6251 /* The right end of the intersection is the minimum of the | 6251 /* The right end of the intersection is the minimum of the |
6252 the right ends of left and right. */ | 6252 the right ends of left and right. */ |
6253 result->width = (min (left->x + left->width, right->x + right->width) | 6253 result->width = (min (left->x + left->width, right->x + right->width) |
6254 - result->x); | 6254 - result->x); |
6255 | 6255 |
6262 /* The upper end of the intersection is lower.y0, if this is inside | 6262 /* The upper end of the intersection is lower.y0, if this is inside |
6263 of upper. Otherwise, there is no intersection. */ | 6263 of upper. Otherwise, there is no intersection. */ |
6264 if (lower->y <= upper->y + upper->height) | 6264 if (lower->y <= upper->y + upper->height) |
6265 { | 6265 { |
6266 result->y = lower->y; | 6266 result->y = lower->y; |
6267 | 6267 |
6268 /* The lower end of the intersection is the minimum of the lower | 6268 /* The lower end of the intersection is the minimum of the lower |
6269 ends of upper and lower. */ | 6269 ends of upper and lower. */ |
6270 result->height = (min (lower->y + lower->height, | 6270 result->height = (min (lower->y + lower->height, |
6271 upper->y + upper->height) | 6271 upper->y + upper->height) |
6272 - result->y); | 6272 - result->y); |
6273 intersection_p = 1; | 6273 intersection_p = 1; |
6274 } | 6274 } |
6275 } | 6275 } |
6350 x_frame_rehighlight (dpyinfo); | 6350 x_frame_rehighlight (dpyinfo); |
6351 } | 6351 } |
6352 | 6352 |
6353 /* Handle FocusIn and FocusOut state changes for FRAME. | 6353 /* Handle FocusIn and FocusOut state changes for FRAME. |
6354 If FRAME has focus and there exists more than one frame, puts | 6354 If FRAME has focus and there exists more than one frame, puts |
6355 an FOCUS_IN_EVENT into BUFP. | 6355 a FOCUS_IN_EVENT into BUFP. |
6356 Returns number of events inserted into BUFP. */ | 6356 Returns number of events inserted into BUFP. */ |
6357 | 6357 |
6358 static int | 6358 static int |
6359 x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) | 6359 x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) |
6360 int type; | 6360 int type; |
6370 { | 6370 { |
6371 if (dpyinfo->x_focus_event_frame != frame) | 6371 if (dpyinfo->x_focus_event_frame != frame) |
6372 { | 6372 { |
6373 x_new_focus_frame (dpyinfo, frame); | 6373 x_new_focus_frame (dpyinfo, frame); |
6374 dpyinfo->x_focus_event_frame = frame; | 6374 dpyinfo->x_focus_event_frame = frame; |
6375 | 6375 |
6376 /* Don't stop displaying the initial startup message | 6376 /* Don't stop displaying the initial startup message |
6377 for a switch-frame event we don't need. */ | 6377 for a switch-frame event we don't need. */ |
6378 if (numchars > 0 | 6378 if (numchars > 0 |
6379 && GC_NILP (Vterminal_frame) | 6379 && GC_NILP (Vterminal_frame) |
6380 && GC_CONSP (Vframe_list) | 6380 && GC_CONSP (Vframe_list) |
6397 #endif | 6397 #endif |
6398 } | 6398 } |
6399 else if (type == FocusOut) | 6399 else if (type == FocusOut) |
6400 { | 6400 { |
6401 frame->output_data.x->focus_state &= ~state; | 6401 frame->output_data.x->focus_state &= ~state; |
6402 | 6402 |
6403 if (dpyinfo->x_focus_event_frame == frame) | 6403 if (dpyinfo->x_focus_event_frame == frame) |
6404 { | 6404 { |
6405 dpyinfo->x_focus_event_frame = 0; | 6405 dpyinfo->x_focus_event_frame = 0; |
6406 x_new_focus_frame (dpyinfo, 0); | 6406 x_new_focus_frame (dpyinfo, 0); |
6407 } | 6407 } |
6427 struct input_event *bufp; | 6427 struct input_event *bufp; |
6428 int numchars; | 6428 int numchars; |
6429 { | 6429 { |
6430 struct frame *frame; | 6430 struct frame *frame; |
6431 int nr_events = 0; | 6431 int nr_events = 0; |
6432 | 6432 |
6433 frame = x_top_window_to_frame (dpyinfo, event->xany.window); | 6433 frame = x_top_window_to_frame (dpyinfo, event->xany.window); |
6434 if (! frame) return nr_events; | 6434 if (! frame) return nr_events; |
6435 | 6435 |
6436 switch (event->type) | 6436 switch (event->type) |
6437 { | 6437 { |
6438 case EnterNotify: | 6438 case EnterNotify: |
6439 case LeaveNotify: | 6439 case LeaveNotify: |
6440 if (event->xcrossing.detail != NotifyInferior | 6440 if (event->xcrossing.detail != NotifyInferior |
6636 EMACS_UINT mod_meta = meta_modifier; | 6636 EMACS_UINT mod_meta = meta_modifier; |
6637 EMACS_UINT mod_alt = alt_modifier; | 6637 EMACS_UINT mod_alt = alt_modifier; |
6638 EMACS_UINT mod_hyper = hyper_modifier; | 6638 EMACS_UINT mod_hyper = hyper_modifier; |
6639 EMACS_UINT mod_super = super_modifier; | 6639 EMACS_UINT mod_super = super_modifier; |
6640 Lisp_Object tem; | 6640 Lisp_Object tem; |
6641 | 6641 |
6642 tem = Fget (Vx_alt_keysym, Qmodifier_value); | 6642 tem = Fget (Vx_alt_keysym, Qmodifier_value); |
6643 if (! EQ (tem, Qnil)) mod_alt = XUINT (tem); | 6643 if (! EQ (tem, Qnil)) mod_alt = XUINT (tem); |
6644 tem = Fget (Vx_meta_keysym, Qmodifier_value); | 6644 tem = Fget (Vx_meta_keysym, Qmodifier_value); |
6645 if (! EQ (tem, Qnil)) mod_meta = XUINT (tem); | 6645 if (! EQ (tem, Qnil)) mod_meta = XUINT (tem); |
6646 tem = Fget (Vx_hyper_keysym, Qmodifier_value); | 6646 tem = Fget (Vx_hyper_keysym, Qmodifier_value); |
6647 if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem); | 6647 if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem); |
6648 tem = Fget (Vx_super_keysym, Qmodifier_value); | 6648 tem = Fget (Vx_super_keysym, Qmodifier_value); |
6649 if (! EQ (tem, Qnil)) mod_super = XUINT (tem); | 6649 if (! EQ (tem, Qnil)) mod_super = XUINT (tem); |
6650 | 6650 |
6651 | 6651 |
6652 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0) | 6652 return ( ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0) |
6653 | ((state & ControlMask) ? ctrl_modifier : 0) | 6653 | ((state & ControlMask) ? ctrl_modifier : 0) |
6654 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0) | 6654 | ((state & dpyinfo->meta_mod_mask) ? mod_meta : 0) |
6655 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0) | 6655 | ((state & dpyinfo->alt_mod_mask) ? mod_alt : 0) |
6664 { | 6664 { |
6665 EMACS_UINT mod_meta = meta_modifier; | 6665 EMACS_UINT mod_meta = meta_modifier; |
6666 EMACS_UINT mod_alt = alt_modifier; | 6666 EMACS_UINT mod_alt = alt_modifier; |
6667 EMACS_UINT mod_hyper = hyper_modifier; | 6667 EMACS_UINT mod_hyper = hyper_modifier; |
6668 EMACS_UINT mod_super = super_modifier; | 6668 EMACS_UINT mod_super = super_modifier; |
6669 | 6669 |
6670 Lisp_Object tem; | 6670 Lisp_Object tem; |
6671 | 6671 |
6672 tem = Fget (Vx_alt_keysym, Qmodifier_value); | 6672 tem = Fget (Vx_alt_keysym, Qmodifier_value); |
6673 if (! EQ (tem, Qnil)) mod_alt = XUINT (tem); | 6673 if (! EQ (tem, Qnil)) mod_alt = XUINT (tem); |
6674 tem = Fget (Vx_meta_keysym, Qmodifier_value); | 6674 tem = Fget (Vx_meta_keysym, Qmodifier_value); |
6675 if (! EQ (tem, Qnil)) mod_meta = XUINT (tem); | 6675 if (! EQ (tem, Qnil)) mod_meta = XUINT (tem); |
6676 tem = Fget (Vx_hyper_keysym, Qmodifier_value); | 6676 tem = Fget (Vx_hyper_keysym, Qmodifier_value); |
6677 if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem); | 6677 if (! EQ (tem, Qnil)) mod_hyper = XUINT (tem); |
6678 tem = Fget (Vx_super_keysym, Qmodifier_value); | 6678 tem = Fget (Vx_super_keysym, Qmodifier_value); |
6679 if (! EQ (tem, Qnil)) mod_super = XUINT (tem); | 6679 if (! EQ (tem, Qnil)) mod_super = XUINT (tem); |
6680 | 6680 |
6681 | 6681 |
6682 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0) | 6682 return ( ((state & mod_alt) ? dpyinfo->alt_mod_mask : 0) |
6683 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0) | 6683 | ((state & mod_super) ? dpyinfo->super_mod_mask : 0) |
6684 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0) | 6684 | ((state & mod_hyper) ? dpyinfo->hyper_mod_mask : 0) |
6685 | ((state & shift_modifier) ? ShiftMask : 0) | 6685 | ((state & shift_modifier) ? ShiftMask : 0) |
6686 | ((state & ctrl_modifier) ? ControlMask : 0) | 6686 | ((state & ctrl_modifier) ? ControlMask : 0) |
6945 if (w->pseudo_window_p) | 6945 if (w->pseudo_window_p) |
6946 break; | 6946 break; |
6947 else if (!buffer_only_p || BUFFERP (glyph->object)) | 6947 else if (!buffer_only_p || BUFFERP (glyph->object)) |
6948 break; | 6948 break; |
6949 } | 6949 } |
6950 | 6950 |
6951 x0 += glyph->pixel_width; | 6951 x0 += glyph->pixel_width; |
6952 ++glyph; | 6952 ++glyph; |
6953 } | 6953 } |
6954 | 6954 |
6955 if (glyph == end) | 6955 if (glyph == end) |
6989 is 1, 3, 6 or 7 for the mode line, header line, left and right | 6989 is 1, 3, 6 or 7 for the mode line, header line, left and right |
6990 marginal area respectively. X is relative to the start of the text | 6990 marginal area respectively. X is relative to the start of the text |
6991 display area of W, so the width of bitmap areas and scroll bars | 6991 display area of W, so the width of bitmap areas and scroll bars |
6992 must be subtracted to get a position relative to the start of the | 6992 must be subtracted to get a position relative to the start of the |
6993 mode line. */ | 6993 mode line. */ |
6994 | 6994 |
6995 static void | 6995 static void |
6996 note_mode_line_or_margin_highlight (w, x, y, portion) | 6996 note_mode_line_or_margin_highlight (w, x, y, portion) |
6997 struct window *w; | 6997 struct window *w; |
6998 int x, y, portion; | 6998 int x, y, portion; |
6999 { | 6999 { |
7009 string = marginal_area_string (w, x, y, portion, &charpos); | 7009 string = marginal_area_string (w, x, y, portion, &charpos); |
7010 | 7010 |
7011 if (STRINGP (string)) | 7011 if (STRINGP (string)) |
7012 { | 7012 { |
7013 pos = make_number (charpos); | 7013 pos = make_number (charpos); |
7014 | 7014 |
7015 /* If we're on a string with `help-echo' text property, arrange | 7015 /* If we're on a string with `help-echo' text property, arrange |
7016 for the help to be displayed. This is done by setting the | 7016 for the help to be displayed. This is done by setting the |
7017 global variable help_echo to the help string. */ | 7017 global variable help_echo to the help string. */ |
7018 help = Fget_text_property (pos, Qhelp_echo, string); | 7018 help = Fget_text_property (pos, Qhelp_echo, string); |
7019 if (!NILP (help)) | 7019 if (!NILP (help)) |
7029 if (!KEYMAPP (map)) | 7029 if (!KEYMAPP (map)) |
7030 map = Fget_text_property (pos, Qkeymap, string); | 7030 map = Fget_text_property (pos, Qkeymap, string); |
7031 if (KEYMAPP (map)) | 7031 if (KEYMAPP (map)) |
7032 cursor = f->output_data.x->nontext_cursor; | 7032 cursor = f->output_data.x->nontext_cursor; |
7033 } | 7033 } |
7034 | 7034 |
7035 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); | 7035 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); |
7036 } | 7036 } |
7037 | 7037 |
7038 | 7038 |
7039 /* Take proper action when the mouse has moved to position X, Y on | 7039 /* Take proper action when the mouse has moved to position X, Y on |
7103 if (portion == 1 || portion == 3 || portion == 6 || portion == 7) | 7103 if (portion == 1 || portion == 3 || portion == 6 || portion == 7) |
7104 { | 7104 { |
7105 note_mode_line_or_margin_highlight (w, x, y, portion); | 7105 note_mode_line_or_margin_highlight (w, x, y, portion); |
7106 return; | 7106 return; |
7107 } | 7107 } |
7108 | 7108 |
7109 if (portion == 2) | 7109 if (portion == 2) |
7110 cursor = f->output_data.x->horizontal_drag_cursor; | 7110 cursor = f->output_data.x->horizontal_drag_cursor; |
7111 else | 7111 else |
7112 cursor = f->output_data.x->text_cursor; | 7112 cursor = f->output_data.x->text_cursor; |
7113 | 7113 |
7212 { | 7212 { |
7213 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); | 7213 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); |
7214 if (!NILP (mouse_face)) | 7214 if (!NILP (mouse_face)) |
7215 overlay = overlay_vec[i]; | 7215 overlay = overlay_vec[i]; |
7216 } | 7216 } |
7217 | 7217 |
7218 /* If we're actually highlighting the same overlay as | 7218 /* If we're actually highlighting the same overlay as |
7219 before, there's no need to do that again. */ | 7219 before, there's no need to do that again. */ |
7220 if (!NILP (overlay) | 7220 if (!NILP (overlay) |
7221 && EQ (overlay, dpyinfo->mouse_face_overlay)) | 7221 && EQ (overlay, dpyinfo->mouse_face_overlay)) |
7222 goto check_help_echo; | 7222 goto check_help_echo; |
7223 | 7223 |
7224 dpyinfo->mouse_face_overlay = overlay; | 7224 dpyinfo->mouse_face_overlay = overlay; |
7225 | 7225 |
7226 /* Clear the display of the old active region, if any. */ | 7226 /* Clear the display of the old active region, if any. */ |
7227 if (clear_mouse_face (dpyinfo)) | 7227 if (clear_mouse_face (dpyinfo)) |
7228 cursor = None; | 7228 cursor = None; |
7245 fast_find_position (w, XFASTINT (before), | 7245 fast_find_position (w, XFASTINT (before), |
7246 &dpyinfo->mouse_face_beg_col, | 7246 &dpyinfo->mouse_face_beg_col, |
7247 &dpyinfo->mouse_face_beg_row, | 7247 &dpyinfo->mouse_face_beg_row, |
7248 &dpyinfo->mouse_face_beg_x, | 7248 &dpyinfo->mouse_face_beg_x, |
7249 &dpyinfo->mouse_face_beg_y, Qnil); | 7249 &dpyinfo->mouse_face_beg_y, Qnil); |
7250 | 7250 |
7251 dpyinfo->mouse_face_past_end | 7251 dpyinfo->mouse_face_past_end |
7252 = !fast_find_position (w, XFASTINT (after), | 7252 = !fast_find_position (w, XFASTINT (after), |
7253 &dpyinfo->mouse_face_end_col, | 7253 &dpyinfo->mouse_face_end_col, |
7254 &dpyinfo->mouse_face_end_row, | 7254 &dpyinfo->mouse_face_end_row, |
7255 &dpyinfo->mouse_face_end_x, | 7255 &dpyinfo->mouse_face_end_x, |
7279 Qmouse_face, | 7279 Qmouse_face, |
7280 object, beginning); | 7280 object, beginning); |
7281 after | 7281 after |
7282 = Fnext_single_property_change (position, Qmouse_face, | 7282 = Fnext_single_property_change (position, Qmouse_face, |
7283 object, end); | 7283 object, end); |
7284 | 7284 |
7285 /* Record this as the current active region. */ | 7285 /* Record this as the current active region. */ |
7286 fast_find_position (w, XFASTINT (before), | 7286 fast_find_position (w, XFASTINT (before), |
7287 &dpyinfo->mouse_face_beg_col, | 7287 &dpyinfo->mouse_face_beg_col, |
7288 &dpyinfo->mouse_face_beg_row, | 7288 &dpyinfo->mouse_face_beg_row, |
7289 &dpyinfo->mouse_face_beg_x, | 7289 &dpyinfo->mouse_face_beg_x, |
7307 } | 7307 } |
7308 else if (!NILP (mouse_face) && STRINGP (object)) | 7308 else if (!NILP (mouse_face) && STRINGP (object)) |
7309 { | 7309 { |
7310 Lisp_Object b, e; | 7310 Lisp_Object b, e; |
7311 int ignore; | 7311 int ignore; |
7312 | 7312 |
7313 b = Fprevious_single_property_change (make_number (pos + 1), | 7313 b = Fprevious_single_property_change (make_number (pos + 1), |
7314 Qmouse_face, | 7314 Qmouse_face, |
7315 object, Qnil); | 7315 object, Qnil); |
7316 e = Fnext_single_property_change (position, Qmouse_face, | 7316 e = Fnext_single_property_change (position, Qmouse_face, |
7317 object, Qnil); | 7317 object, Qnil); |
7341 { | 7341 { |
7342 /* A string which doesn't have mouse-face, but | 7342 /* A string which doesn't have mouse-face, but |
7343 the text ``under'' it might have. */ | 7343 the text ``under'' it might have. */ |
7344 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos); | 7344 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos); |
7345 int start = MATRIX_ROW_START_CHARPOS (r); | 7345 int start = MATRIX_ROW_START_CHARPOS (r); |
7346 | 7346 |
7347 pos = string_buffer_position (w, object, start); | 7347 pos = string_buffer_position (w, object, start); |
7348 if (pos > 0) | 7348 if (pos > 0) |
7349 mouse_face = get_char_property_and_overlay (make_number (pos), | 7349 mouse_face = get_char_property_and_overlay (make_number (pos), |
7350 Qmouse_face, | 7350 Qmouse_face, |
7351 w->buffer, | 7351 w->buffer, |
7365 &dpyinfo->mouse_face_beg_col, | 7365 &dpyinfo->mouse_face_beg_col, |
7366 &dpyinfo->mouse_face_beg_row, | 7366 &dpyinfo->mouse_face_beg_row, |
7367 &dpyinfo->mouse_face_beg_x, | 7367 &dpyinfo->mouse_face_beg_x, |
7368 &dpyinfo->mouse_face_beg_y, | 7368 &dpyinfo->mouse_face_beg_y, |
7369 object); | 7369 object); |
7370 | 7370 |
7371 dpyinfo->mouse_face_past_end | 7371 dpyinfo->mouse_face_past_end |
7372 = !fast_find_position (w, XFASTINT (after), | 7372 = !fast_find_position (w, XFASTINT (after), |
7373 &dpyinfo->mouse_face_end_col, | 7373 &dpyinfo->mouse_face_end_col, |
7374 &dpyinfo->mouse_face_end_row, | 7374 &dpyinfo->mouse_face_end_row, |
7375 &dpyinfo->mouse_face_end_x, | 7375 &dpyinfo->mouse_face_end_x, |
7410 } | 7410 } |
7411 else | 7411 else |
7412 { | 7412 { |
7413 Lisp_Object object = glyph->object; | 7413 Lisp_Object object = glyph->object; |
7414 int charpos = glyph->charpos; | 7414 int charpos = glyph->charpos; |
7415 | 7415 |
7416 /* Try text properties. */ | 7416 /* Try text properties. */ |
7417 if (STRINGP (object) | 7417 if (STRINGP (object) |
7418 && charpos >= 0 | 7418 && charpos >= 0 |
7419 && charpos < SCHARS (object)) | 7419 && charpos < SCHARS (object)) |
7420 { | 7420 { |
7443 else if (BUFFERP (object) | 7443 else if (BUFFERP (object) |
7444 && charpos >= BEGV | 7444 && charpos >= BEGV |
7445 && charpos < ZV) | 7445 && charpos < ZV) |
7446 help = Fget_text_property (make_number (charpos), Qhelp_echo, | 7446 help = Fget_text_property (make_number (charpos), Qhelp_echo, |
7447 object); | 7447 object); |
7448 | 7448 |
7449 if (!NILP (help)) | 7449 if (!NILP (help)) |
7450 { | 7450 { |
7451 help_echo = help; | 7451 help_echo = help; |
7452 help_echo_window = window; | 7452 help_echo_window = window; |
7453 help_echo_object = object; | 7453 help_echo_object = object; |
7454 help_echo_pos = charpos; | 7454 help_echo_pos = charpos; |
7455 } | 7455 } |
7456 } | 7456 } |
7457 } | 7457 } |
7458 | 7458 |
7459 BEGV = obegv; | 7459 BEGV = obegv; |
7460 ZV = ozv; | 7460 ZV = ozv; |
7461 current_buffer = obuf; | 7461 current_buffer = obuf; |
7462 } | 7462 } |
7463 | 7463 |
7464 set_cursor: | 7464 set_cursor: |
7465 | 7465 |
7466 if (cursor != None) | 7466 if (cursor != None) |
7467 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); | 7467 XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); |
7468 } | 7468 } |
7469 | 7469 |
7470 static void | 7470 static void |
7531 || *hpos >= dpyinfo->mouse_face_beg_col) | 7531 || *hpos >= dpyinfo->mouse_face_beg_col) |
7532 && (*vpos < dpyinfo->mouse_face_end_row | 7532 && (*vpos < dpyinfo->mouse_face_end_row |
7533 || *hpos < dpyinfo->mouse_face_end_col | 7533 || *hpos < dpyinfo->mouse_face_end_col |
7534 || dpyinfo->mouse_face_past_end)) | 7534 || dpyinfo->mouse_face_past_end)) |
7535 return 0; | 7535 return 0; |
7536 | 7536 |
7537 return 1; | 7537 return 1; |
7538 } | 7538 } |
7539 | 7539 |
7540 | 7540 |
7541 /* Handle mouse button event on the tool-bar of frame F, at | 7541 /* Handle mouse button event on the tool-bar of frame F, at |
7552 int hpos, vpos, prop_idx; | 7552 int hpos, vpos, prop_idx; |
7553 struct glyph *glyph; | 7553 struct glyph *glyph; |
7554 Lisp_Object enabled_p; | 7554 Lisp_Object enabled_p; |
7555 int x = button_event->x; | 7555 int x = button_event->x; |
7556 int y = button_event->y; | 7556 int y = button_event->y; |
7557 | 7557 |
7558 /* If not on the highlighted tool-bar item, return. */ | 7558 /* If not on the highlighted tool-bar item, return. */ |
7559 frame_to_window_pixel_xy (w, &x, &y); | 7559 frame_to_window_pixel_xy (w, &x, &y); |
7560 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0) | 7560 if (x_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0) |
7561 return; | 7561 return; |
7562 | 7562 |
7563 /* If item is disabled, do nothing. */ | 7563 /* If item is disabled, do nothing. */ |
7564 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); | 7564 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); |
7565 if (NILP (enabled_p)) | 7565 if (NILP (enabled_p)) |
7566 return; | 7566 return; |
7567 | 7567 |
7568 if (button_event->type == ButtonPress) | 7568 if (button_event->type == ButtonPress) |
7569 { | 7569 { |
7570 /* Show item in pressed state. */ | 7570 /* Show item in pressed state. */ |
7571 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN); | 7571 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN); |
7572 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; | 7572 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN; |
7638 } | 7638 } |
7639 else if (rc == 0) | 7639 else if (rc == 0) |
7640 goto set_help_echo; | 7640 goto set_help_echo; |
7641 | 7641 |
7642 clear_mouse_face (dpyinfo); | 7642 clear_mouse_face (dpyinfo); |
7643 | 7643 |
7644 /* Mouse is down, but on different tool-bar item? */ | 7644 /* Mouse is down, but on different tool-bar item? */ |
7645 mouse_down_p = (dpyinfo->grabbed | 7645 mouse_down_p = (dpyinfo->grabbed |
7646 && f == last_mouse_frame | 7646 && f == last_mouse_frame |
7647 && FRAME_LIVE_P (f)); | 7647 && FRAME_LIVE_P (f)); |
7648 if (mouse_down_p | 7648 if (mouse_down_p |
7649 && last_tool_bar_item != prop_idx) | 7649 && last_tool_bar_item != prop_idx) |
7650 return; | 7650 return; |
7651 | 7651 |
7652 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; | 7652 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT; |
7653 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; | 7653 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED; |
7654 | 7654 |
7655 /* If tool-bar item is not enabled, don't highlight it. */ | 7655 /* If tool-bar item is not enabled, don't highlight it. */ |
7656 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); | 7656 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P); |
7657 if (!NILP (enabled_p)) | 7657 if (!NILP (enabled_p)) |
7658 { | 7658 { |
7659 /* Compute the x-position of the glyph. In front and past the | 7659 /* Compute the x-position of the glyph. In front and past the |
7660 image is a space. We include this is the highlighted area. */ | 7660 image is a space. We include this is the highlighted area. */ |
7661 row = MATRIX_ROW (w->current_matrix, vpos); | 7661 row = MATRIX_ROW (w->current_matrix, vpos); |
7662 for (i = x = 0; i < hpos; ++i) | 7662 for (i = x = 0; i < hpos; ++i) |
7663 x += row->glyphs[TEXT_AREA][i].pixel_width; | 7663 x += row->glyphs[TEXT_AREA][i].pixel_width; |
7664 | 7664 |
7665 /* Record this as the current active region. */ | 7665 /* Record this as the current active region. */ |
7666 dpyinfo->mouse_face_beg_col = hpos; | 7666 dpyinfo->mouse_face_beg_col = hpos; |
7667 dpyinfo->mouse_face_beg_row = vpos; | 7667 dpyinfo->mouse_face_beg_row = vpos; |
7668 dpyinfo->mouse_face_beg_x = x; | 7668 dpyinfo->mouse_face_beg_x = x; |
7669 dpyinfo->mouse_face_beg_y = row->y; | 7669 dpyinfo->mouse_face_beg_y = row->y; |
7670 dpyinfo->mouse_face_past_end = 0; | 7670 dpyinfo->mouse_face_past_end = 0; |
7671 | 7671 |
7672 dpyinfo->mouse_face_end_col = hpos + 1; | 7672 dpyinfo->mouse_face_end_col = hpos + 1; |
7673 dpyinfo->mouse_face_end_row = vpos; | 7673 dpyinfo->mouse_face_end_row = vpos; |
7674 dpyinfo->mouse_face_end_x = x + glyph->pixel_width; | 7674 dpyinfo->mouse_face_end_x = x + glyph->pixel_width; |
7675 dpyinfo->mouse_face_end_y = row->y; | 7675 dpyinfo->mouse_face_end_y = row->y; |
7676 dpyinfo->mouse_face_window = window; | 7676 dpyinfo->mouse_face_window = window; |
7677 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; | 7677 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID; |
7678 | 7678 |
7679 /* Display it as active. */ | 7679 /* Display it as active. */ |
7680 show_mouse_face (dpyinfo, draw); | 7680 show_mouse_face (dpyinfo, draw); |
7681 dpyinfo->mouse_face_image_state = draw; | 7681 dpyinfo->mouse_face_image_state = draw; |
7682 } | 7682 } |
7683 | 7683 |
7684 set_help_echo: | 7684 set_help_echo: |
7685 | 7685 |
7686 /* Set help_echo to a help string to display for this tool-bar item. | 7686 /* Set help_echo to a help string to display for this tool-bar item. |
7687 XTread_socket does the rest. */ | 7687 XTread_socket does the rest. */ |
7688 help_echo_object = help_echo_window = Qnil; | 7688 help_echo_object = help_echo_window = Qnil; |
7689 help_echo_pos = -1; | 7689 help_echo_pos = -1; |
7690 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP); | 7690 help_echo = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP); |
7702 having STOP as object. */ | 7702 having STOP as object. */ |
7703 | 7703 |
7704 #if 0 /* This is a version of fast_find_position that's more correct | 7704 #if 0 /* This is a version of fast_find_position that's more correct |
7705 in the presence of hscrolling, for example. I didn't install | 7705 in the presence of hscrolling, for example. I didn't install |
7706 it right away because the problem fixed is minor, it failed | 7706 it right away because the problem fixed is minor, it failed |
7707 in 20.x as well, and I think it's too risky to install | 7707 in 20.x as well, and I think it's too risky to install |
7708 so near the release of 21.1. 2001-09-25 gerd. */ | 7708 so near the release of 21.1. 2001-09-25 gerd. */ |
7709 | 7709 |
7710 static int | 7710 static int |
7711 fast_find_position (w, charpos, hpos, vpos, x, y, stop) | 7711 fast_find_position (w, charpos, hpos, vpos, x, y, stop) |
7712 struct window *w; | 7712 struct window *w; |
7735 } | 7735 } |
7736 | 7736 |
7737 *x = row->x; | 7737 *x = row->x; |
7738 *y = row->y; | 7738 *y = row->y; |
7739 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix); | 7739 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix); |
7740 | 7740 |
7741 glyph = row->glyphs[TEXT_AREA]; | 7741 glyph = row->glyphs[TEXT_AREA]; |
7742 end = glyph + row->used[TEXT_AREA]; | 7742 end = glyph + row->used[TEXT_AREA]; |
7743 | 7743 |
7744 /* Skip over glyphs not having an object at the start of the row. | 7744 /* Skip over glyphs not having an object at the start of the row. |
7745 These are special glyphs like truncation marks on terminal | 7745 These are special glyphs like truncation marks on terminal |
7746 frames. */ | 7746 frames. */ |
7747 if (row->displays_text_p) | 7747 if (row->displays_text_p) |
7748 while (glyph < end | 7748 while (glyph < end |
7812 best_row_vpos = row_vpos; | 7812 best_row_vpos = row_vpos; |
7813 } | 7813 } |
7814 | 7814 |
7815 if (row->y + row->height >= yb) | 7815 if (row->y + row->height >= yb) |
7816 break; | 7816 break; |
7817 | 7817 |
7818 ++row; | 7818 ++row; |
7819 ++row_vpos; | 7819 ++row_vpos; |
7820 } | 7820 } |
7821 | 7821 |
7822 /* Find the right column within BEST_ROW. */ | 7822 /* Find the right column within BEST_ROW. */ |
7823 lastcol = 0; | 7823 lastcol = 0; |
7824 current_x = best_row->x; | 7824 current_x = best_row->x; |
7825 for (i = 0; i < best_row->used[TEXT_AREA]; i++) | 7825 for (i = 0; i < best_row->used[TEXT_AREA]; i++) |
7826 { | 7826 { |
7940 if (right_p) | 7940 if (right_p) |
7941 { | 7941 { |
7942 *x += best_glyph->pixel_width; | 7942 *x += best_glyph->pixel_width; |
7943 ++*hpos; | 7943 ++*hpos; |
7944 } | 7944 } |
7945 | 7945 |
7946 *y = best_row->y; | 7946 *y = best_row->y; |
7947 *vpos = best_row - w->current_matrix->rows; | 7947 *vpos = best_row - w->current_matrix->rows; |
7948 } | 7948 } |
7949 | 7949 |
7950 return best_glyph != NULL; | 7950 return best_glyph != NULL; |
7974 int phys_cursor_on_p = w->phys_cursor_on_p; | 7974 int phys_cursor_on_p = w->phys_cursor_on_p; |
7975 struct glyph_row *row, *first, *last; | 7975 struct glyph_row *row, *first, *last; |
7976 | 7976 |
7977 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); | 7977 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row); |
7978 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); | 7978 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row); |
7979 | 7979 |
7980 for (row = first; row <= last && row->enabled_p; ++row) | 7980 for (row = first; row <= last && row->enabled_p; ++row) |
7981 { | 7981 { |
7982 int start_hpos, end_hpos, start_x; | 7982 int start_hpos, end_hpos, start_x; |
7983 | 7983 |
7984 /* For all but the first row, the highlight starts at column 0. */ | 7984 /* For all but the first row, the highlight starts at column 0. */ |
7998 else | 7998 else |
7999 end_hpos = row->used[TEXT_AREA]; | 7999 end_hpos = row->used[TEXT_AREA]; |
8000 | 8000 |
8001 if (end_hpos > start_hpos) | 8001 if (end_hpos > start_hpos) |
8002 { | 8002 { |
8003 x_draw_glyphs (w, start_x, row, TEXT_AREA, | 8003 x_draw_glyphs (w, start_x, row, TEXT_AREA, |
8004 start_hpos, end_hpos, draw, 0); | 8004 start_hpos, end_hpos, draw, 0); |
8005 | 8005 |
8006 row->mouse_face_p | 8006 row->mouse_face_p |
8007 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED; | 8007 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED; |
8008 } | 8008 } |
8035 static int | 8035 static int |
8036 clear_mouse_face (dpyinfo) | 8036 clear_mouse_face (dpyinfo) |
8037 struct x_display_info *dpyinfo; | 8037 struct x_display_info *dpyinfo; |
8038 { | 8038 { |
8039 int cleared = 0; | 8039 int cleared = 0; |
8040 | 8040 |
8041 if (!NILP (dpyinfo->mouse_face_window)) | 8041 if (!NILP (dpyinfo->mouse_face_window)) |
8042 { | 8042 { |
8043 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); | 8043 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT); |
8044 cleared = 1; | 8044 cleared = 1; |
8045 } | 8045 } |
8114 struct window *w = XWINDOW (window); | 8114 struct window *w = XWINDOW (window); |
8115 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | 8115 struct glyph_row *r = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
8116 struct glyph_row *end = r + w->current_matrix->nrows - 1; | 8116 struct glyph_row *end = r + w->current_matrix->nrows - 1; |
8117 | 8117 |
8118 frame_to_window_pixel_xy (w, &x, &y); | 8118 frame_to_window_pixel_xy (w, &x, &y); |
8119 | 8119 |
8120 for (; !found && r < end && r->enabled_p; ++r) | 8120 for (; !found && r < end && r->enabled_p; ++r) |
8121 if (r->y >= y) | 8121 if (r->y >= y) |
8122 { | 8122 { |
8123 struct glyph *g = r->glyphs[TEXT_AREA]; | 8123 struct glyph *g = r->glyphs[TEXT_AREA]; |
8124 struct glyph *end = g + r->used[TEXT_AREA]; | 8124 struct glyph *end = g + r->used[TEXT_AREA]; |
8125 int gx; | 8125 int gx; |
8126 | 8126 |
8127 for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g) | 8127 for (gx = r->x; !found && g < end; gx += g->pixel_width, ++g) |
8128 if (gx >= x) | 8128 if (gx >= x) |
8129 { | 8129 { |
8130 rect->width = g->pixel_width; | 8130 rect->width = g->pixel_width; |
8131 rect->height = r->height; | 8131 rect->height = r->height; |
8324 on it, i.e. into the same rectangles that matrices on | 8324 on it, i.e. into the same rectangles that matrices on |
8325 the frame are divided into. */ | 8325 the frame are divided into. */ |
8326 | 8326 |
8327 int width, height, gx, gy; | 8327 int width, height, gx, gy; |
8328 XRectangle rect; | 8328 XRectangle rect; |
8329 | 8329 |
8330 if (glyph_rect (f1, win_x, win_y, &rect)) | 8330 if (glyph_rect (f1, win_x, win_y, &rect)) |
8331 last_mouse_glyph = rect; | 8331 last_mouse_glyph = rect; |
8332 else | 8332 else |
8333 { | 8333 { |
8334 width = FRAME_SMALLEST_CHAR_WIDTH (f1); | 8334 width = FRAME_SMALLEST_CHAR_WIDTH (f1); |
8335 height = FRAME_SMALLEST_FONT_HEIGHT (f1); | 8335 height = FRAME_SMALLEST_FONT_HEIGHT (f1); |
8336 gx = win_x; | 8336 gx = win_x; |
8337 gy = win_y; | 8337 gy = win_y; |
8338 | 8338 |
8339 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to | 8339 /* Arrange for the division in PIXEL_TO_CHAR_COL etc. to |
8340 round down even for negative values. */ | 8340 round down even for negative values. */ |
8341 if (gx < 0) | 8341 if (gx < 0) |
8342 gx -= width - 1; | 8342 gx -= width - 1; |
8343 if (gy < 0) | 8343 if (gy < 0) |
8344 gy -= height - 1; | 8344 gy -= height - 1; |
8345 gx = (gx + width - 1) / width * width; | 8345 gx = (gx + width - 1) / width * width; |
8346 gy = (gy + height - 1) / height * height; | 8346 gy = (gy + height - 1) / height * height; |
8347 | 8347 |
8348 last_mouse_glyph.width = width; | 8348 last_mouse_glyph.width = width; |
8349 last_mouse_glyph.height = height; | 8349 last_mouse_glyph.height = height; |
8350 last_mouse_glyph.x = gx; | 8350 last_mouse_glyph.x = gx; |
8351 last_mouse_glyph.y = gy; | 8351 last_mouse_glyph.y = gy; |
8352 } | 8352 } |
8437 static Widget | 8437 static Widget |
8438 x_window_to_menu_bar (window) | 8438 x_window_to_menu_bar (window) |
8439 Window window; | 8439 Window window; |
8440 { | 8440 { |
8441 Lisp_Object tail; | 8441 Lisp_Object tail; |
8442 | 8442 |
8443 for (tail = Vframe_list; | 8443 for (tail = Vframe_list; |
8444 XGCTYPE (tail) == Lisp_Cons; | 8444 XGCTYPE (tail) == Lisp_Cons; |
8445 tail = XCDR (tail)) | 8445 tail = XCDR (tail)) |
8446 { | 8446 { |
8447 Lisp_Object frame = XCAR (tail); | 8447 Lisp_Object frame = XCAR (tail); |
8448 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; | 8448 Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget; |
8449 | 8449 |
8450 if (menu_bar && xlwmenu_window_p (menu_bar, window)) | 8450 if (menu_bar && xlwmenu_window_p (menu_bar, window)) |
8451 return menu_bar; | 8451 return menu_bar; |
8452 } | 8452 } |
8453 | 8453 |
8454 return NULL; | 8454 return NULL; |
8511 String *params; | 8511 String *params; |
8512 Cardinal *num_params; | 8512 Cardinal *num_params; |
8513 { | 8513 { |
8514 int scroll_bar_p; | 8514 int scroll_bar_p; |
8515 char *end_action; | 8515 char *end_action; |
8516 | 8516 |
8517 #ifdef USE_MOTIF | 8517 #ifdef USE_MOTIF |
8518 scroll_bar_p = XmIsScrollBar (widget); | 8518 scroll_bar_p = XmIsScrollBar (widget); |
8519 end_action = "Release"; | 8519 end_action = "Release"; |
8520 #else /* !USE_MOTIF i.e. use Xaw */ | 8520 #else /* !USE_MOTIF i.e. use Xaw */ |
8521 scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass); | 8521 scroll_bar_p = XtIsSubclass (widget, scrollbarWidgetClass); |
8525 if (scroll_bar_p | 8525 if (scroll_bar_p |
8526 && strcmp (action_name, end_action) == 0 | 8526 && strcmp (action_name, end_action) == 0 |
8527 && WINDOWP (window_being_scrolled)) | 8527 && WINDOWP (window_being_scrolled)) |
8528 { | 8528 { |
8529 struct window *w; | 8529 struct window *w; |
8530 | 8530 |
8531 x_send_scroll_bar_event (window_being_scrolled, | 8531 x_send_scroll_bar_event (window_being_scrolled, |
8532 scroll_bar_end_scroll, 0, 0); | 8532 scroll_bar_end_scroll, 0, 0); |
8533 w = XWINDOW (window_being_scrolled); | 8533 w = XWINDOW (window_being_scrolled); |
8534 XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil; | 8534 XSCROLL_BAR (w->vertical_scroll_bar)->dragging = Qnil; |
8535 window_being_scrolled = Qnil; | 8535 window_being_scrolled = Qnil; |
8562 struct window *w = XWINDOW (window); | 8562 struct window *w = XWINDOW (window); |
8563 struct frame *f = XFRAME (w->frame); | 8563 struct frame *f = XFRAME (w->frame); |
8564 int i; | 8564 int i; |
8565 | 8565 |
8566 BLOCK_INPUT; | 8566 BLOCK_INPUT; |
8567 | 8567 |
8568 /* Construct a ClientMessage event to send to the frame. */ | 8568 /* Construct a ClientMessage event to send to the frame. */ |
8569 ev->type = ClientMessage; | 8569 ev->type = ClientMessage; |
8570 ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar; | 8570 ev->message_type = FRAME_X_DISPLAY_INFO (f)->Xatom_Scrollbar; |
8571 ev->display = FRAME_X_DISPLAY (f); | 8571 ev->display = FRAME_X_DISPLAY (f); |
8572 ev->window = FRAME_X_WINDOW (f); | 8572 ev->window = FRAME_X_WINDOW (f); |
8583 if (i == scroll_bar_windows_size) | 8583 if (i == scroll_bar_windows_size) |
8584 { | 8584 { |
8585 int new_size = max (10, 2 * scroll_bar_windows_size); | 8585 int new_size = max (10, 2 * scroll_bar_windows_size); |
8586 size_t nbytes = new_size * sizeof *scroll_bar_windows; | 8586 size_t nbytes = new_size * sizeof *scroll_bar_windows; |
8587 size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; | 8587 size_t old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows; |
8588 | 8588 |
8589 scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, | 8589 scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows, |
8590 nbytes); | 8590 nbytes); |
8591 bzero (&scroll_bar_windows[i], nbytes - old_nbytes); | 8591 bzero (&scroll_bar_windows[i], nbytes - old_nbytes); |
8592 scroll_bar_windows_size = new_size; | 8592 scroll_bar_windows_size = new_size; |
8593 } | 8593 } |
8620 { | 8620 { |
8621 XClientMessageEvent *ev = (XClientMessageEvent *) event; | 8621 XClientMessageEvent *ev = (XClientMessageEvent *) event; |
8622 Lisp_Object window; | 8622 Lisp_Object window; |
8623 struct frame *f; | 8623 struct frame *f; |
8624 struct window *w; | 8624 struct window *w; |
8625 | 8625 |
8626 w = scroll_bar_windows[ev->data.l[0]]; | 8626 w = scroll_bar_windows[ev->data.l[0]]; |
8627 scroll_bar_windows[ev->data.l[0]] = NULL; | 8627 scroll_bar_windows[ev->data.l[0]] = NULL; |
8628 | 8628 |
8629 XSETWINDOW (window, w); | 8629 XSETWINDOW (window, w); |
8630 f = XFRAME (w->frame); | 8630 f = XFRAME (w->frame); |
8631 | 8631 |
8632 ievent->kind = SCROLL_BAR_CLICK_EVENT; | 8632 ievent->kind = SCROLL_BAR_CLICK_EVENT; |
8633 ievent->frame_or_window = window; | 8633 ievent->frame_or_window = window; |
8634 ievent->arg = Qnil; | 8634 ievent->arg = Qnil; |
8635 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f)); | 8635 ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f)); |
8636 ievent->part = ev->data.l[1]; | 8636 ievent->part = ev->data.l[1]; |
8687 | 8687 |
8688 case XmCR_TO_TOP: | 8688 case XmCR_TO_TOP: |
8689 bar->dragging = Qnil; | 8689 bar->dragging = Qnil; |
8690 part = scroll_bar_to_top; | 8690 part = scroll_bar_to_top; |
8691 break; | 8691 break; |
8692 | 8692 |
8693 case XmCR_TO_BOTTOM: | 8693 case XmCR_TO_BOTTOM: |
8694 bar->dragging = Qnil; | 8694 bar->dragging = Qnil; |
8695 part = scroll_bar_to_bottom; | 8695 part = scroll_bar_to_bottom; |
8696 break; | 8696 break; |
8697 | 8697 |
8710 portion = min (cs->value - XM_SB_MIN, whole); | 8710 portion = min (cs->value - XM_SB_MIN, whole); |
8711 part = scroll_bar_handle; | 8711 part = scroll_bar_handle; |
8712 bar->dragging = make_number (cs->value); | 8712 bar->dragging = make_number (cs->value); |
8713 } | 8713 } |
8714 break; | 8714 break; |
8715 | 8715 |
8716 case XmCR_VALUE_CHANGED: | 8716 case XmCR_VALUE_CHANGED: |
8717 break; | 8717 break; |
8718 }; | 8718 }; |
8719 | 8719 |
8720 if (part >= 0) | 8720 if (part >= 0) |
8844 if (pixel != -1) | 8844 if (pixel != -1) |
8845 { | 8845 { |
8846 XtSetArg (av[ac], XmNforeground, pixel); | 8846 XtSetArg (av[ac], XmNforeground, pixel); |
8847 ++ac; | 8847 ++ac; |
8848 } | 8848 } |
8849 | 8849 |
8850 pixel = f->output_data.x->scroll_bar_background_pixel; | 8850 pixel = f->output_data.x->scroll_bar_background_pixel; |
8851 if (pixel != -1) | 8851 if (pixel != -1) |
8852 { | 8852 { |
8853 XtSetArg (av[ac], XmNbackground, pixel); | 8853 XtSetArg (av[ac], XmNbackground, pixel); |
8854 ++ac; | 8854 ++ac; |
8855 } | 8855 } |
8856 | 8856 |
8857 widget = XmCreateScrollBar (f->output_data.x->edit_widget, | 8857 widget = XmCreateScrollBar (f->output_data.x->edit_widget, |
8858 scroll_bar_name, av, ac); | 8858 scroll_bar_name, av, ac); |
8859 | 8859 |
8860 /* Add one callback for everything that can happen. */ | 8860 /* Add one callback for everything that can happen. */ |
8861 XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback, | 8861 XtAddCallback (widget, XmNdecrementCallback, xm_scroll_callback, |
8870 (XtPointer) bar); | 8870 (XtPointer) bar); |
8871 XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback, | 8871 XtAddCallback (widget, XmNtoBottomCallback, xm_scroll_callback, |
8872 (XtPointer) bar); | 8872 (XtPointer) bar); |
8873 XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback, | 8873 XtAddCallback (widget, XmNtoTopCallback, xm_scroll_callback, |
8874 (XtPointer) bar); | 8874 (XtPointer) bar); |
8875 | 8875 |
8876 /* Realize the widget. Only after that is the X window created. */ | 8876 /* Realize the widget. Only after that is the X window created. */ |
8877 XtRealizeWidget (widget); | 8877 XtRealizeWidget (widget); |
8878 | 8878 |
8879 /* Set the cursor to an arrow. I didn't find a resource to do that. | 8879 /* Set the cursor to an arrow. I didn't find a resource to do that. |
8880 And I'm wondering why it hasn't an arrow cursor by default. */ | 8880 And I'm wondering why it hasn't an arrow cursor by default. */ |
8881 XDefineCursor (XtDisplay (widget), XtWindow (widget), | 8881 XDefineCursor (XtDisplay (widget), XtWindow (widget), |
8882 f->output_data.x->nontext_cursor); | 8882 f->output_data.x->nontext_cursor); |
8883 | 8883 |
8884 #else /* !USE_MOTIF i.e. use Xaw */ | 8884 #else /* !USE_MOTIF i.e. use Xaw */ |
8885 | 8885 |
8886 /* Set resources. Create the widget. The background of the | 8886 /* Set resources. Create the widget. The background of the |
8887 Xaw3d scroll bar widget is a little bit light for my taste. | 8887 Xaw3d scroll bar widget is a little bit light for my taste. |
8888 We don't alter it here to let users change it according | 8888 We don't alter it here to let users change it according |
8889 to their taste with `emacs*verticalScrollBar.background: xxx'. */ | 8889 to their taste with `emacs*verticalScrollBar.background: xxx'. */ |
8890 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; | 8890 XtSetArg (av[ac], XtNmappedWhenManaged, False); ++ac; |
8891 XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac; | 8891 XtSetArg (av[ac], XtNorientation, XtorientVertical); ++ac; |
8892 /* For smoother scrolling with Xaw3d -sm */ | 8892 /* For smoother scrolling with Xaw3d -sm */ |
8893 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */ | 8893 /* XtSetArg (av[ac], XtNpickTop, True); ++ac; */ |
8894 | 8894 |
8895 pixel = f->output_data.x->scroll_bar_foreground_pixel; | 8895 pixel = f->output_data.x->scroll_bar_foreground_pixel; |
8896 if (pixel != -1) | 8896 if (pixel != -1) |
8897 { | 8897 { |
8898 XtSetArg (av[ac], XtNforeground, pixel); | 8898 XtSetArg (av[ac], XtNforeground, pixel); |
8899 ++ac; | 8899 ++ac; |
8900 } | 8900 } |
8901 | 8901 |
8902 pixel = f->output_data.x->scroll_bar_background_pixel; | 8902 pixel = f->output_data.x->scroll_bar_background_pixel; |
8903 if (pixel != -1) | 8903 if (pixel != -1) |
8904 { | 8904 { |
8905 XtSetArg (av[ac], XtNbackground, pixel); | 8905 XtSetArg (av[ac], XtNbackground, pixel); |
8906 ++ac; | 8906 ++ac; |
8973 xaw3d_arrow_scroll = True; | 8973 xaw3d_arrow_scroll = True; |
8974 /* Isn't that just a personal preference ? -sm */ | 8974 /* Isn't that just a personal preference ? -sm */ |
8975 XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL); | 8975 XtVaSetValues (widget, XtNcursorName, "top_left_arrow", NULL); |
8976 } | 8976 } |
8977 } | 8977 } |
8978 | 8978 |
8979 /* Define callbacks. */ | 8979 /* Define callbacks. */ |
8980 XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar); | 8980 XtAddCallback (widget, XtNjumpProc, xaw_jump_callback, (XtPointer) bar); |
8981 XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback, | 8981 XtAddCallback (widget, XtNscrollProc, xaw_scroll_callback, |
8982 (XtPointer) bar); | 8982 (XtPointer) bar); |
8983 | 8983 |
8984 /* Realize the widget. Only after that is the X window created. */ | 8984 /* Realize the widget. Only after that is the X window created. */ |
8985 XtRealizeWidget (widget); | 8985 XtRealizeWidget (widget); |
8986 | 8986 |
8987 #endif /* !USE_MOTIF */ | 8987 #endif /* !USE_MOTIF */ |
8988 | 8988 |
8989 /* Install an action hook that lets us detect when the user | 8989 /* Install an action hook that lets us detect when the user |
8990 finishes interacting with a scroll bar. */ | 8990 finishes interacting with a scroll bar. */ |
8991 if (action_hook_id == 0) | 8991 if (action_hook_id == 0) |
8992 action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0); | 8992 action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0); |
8993 | 8993 |
8994 /* Remember X window and widget in the scroll bar vector. */ | 8994 /* Remember X window and widget in the scroll bar vector. */ |
8995 SET_SCROLL_BAR_X_WIDGET (bar, widget); | 8995 SET_SCROLL_BAR_X_WIDGET (bar, widget); |
8996 xwindow = XtWindow (widget); | 8996 xwindow = XtWindow (widget); |
8997 SET_SCROLL_BAR_X_WINDOW (bar, xwindow); | 8997 SET_SCROLL_BAR_X_WINDOW (bar, xwindow); |
8998 | 8998 |
9053 | 9053 |
9054 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ | 9054 /* Position. Must be in the range [MIN .. MAX - SLIDER_SIZE]. */ |
9055 value = top * XM_SB_RANGE; | 9055 value = top * XM_SB_RANGE; |
9056 value = min (value, XM_SB_MAX - size); | 9056 value = min (value, XM_SB_MAX - size); |
9057 value = max (value, XM_SB_MIN); | 9057 value = max (value, XM_SB_MIN); |
9058 | 9058 |
9059 XmScrollBarSetValues (widget, value, size, 0, 0, False); | 9059 XmScrollBarSetValues (widget, value, size, 0, 0, False); |
9060 } | 9060 } |
9061 #else /* !USE_MOTIF i.e. use Xaw */ | 9061 #else /* !USE_MOTIF i.e. use Xaw */ |
9062 | 9062 |
9063 if (whole == 0) | 9063 if (whole == 0) |
9095 else | 9095 else |
9096 { | 9096 { |
9097 #ifdef HAVE_XAW3D | 9097 #ifdef HAVE_XAW3D |
9098 ScrollbarWidget sb = (ScrollbarWidget) widget; | 9098 ScrollbarWidget sb = (ScrollbarWidget) widget; |
9099 int scroll_mode = 0; | 9099 int scroll_mode = 0; |
9100 | 9100 |
9101 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */ | 9101 /* `scroll_mode' only exists with Xaw3d + ARROW_SCROLLBAR. */ |
9102 if (xaw3d_arrow_scroll) | 9102 if (xaw3d_arrow_scroll) |
9103 { | 9103 { |
9104 /* Xaw3d stupidly ignores resize requests while dragging | 9104 /* Xaw3d stupidly ignores resize requests while dragging |
9105 so we have to make it believe it's not in dragging mode. */ | 9105 so we have to make it believe it's not in dragging mode. */ |
9109 } | 9109 } |
9110 #endif | 9110 #endif |
9111 /* Try to make the scrolling a tad smoother. */ | 9111 /* Try to make the scrolling a tad smoother. */ |
9112 if (!xaw3d_pick_top) | 9112 if (!xaw3d_pick_top) |
9113 shown = min (shown, old_shown); | 9113 shown = min (shown, old_shown); |
9114 | 9114 |
9115 XawScrollbarSetThumb (widget, top, shown); | 9115 XawScrollbarSetThumb (widget, top, shown); |
9116 | 9116 |
9117 #ifdef HAVE_XAW3D | 9117 #ifdef HAVE_XAW3D |
9118 if (xaw3d_arrow_scroll && scroll_mode == 2) | 9118 if (xaw3d_arrow_scroll && scroll_mode == 2) |
9119 sb->scrollbar.scroll_mode = scroll_mode; | 9119 sb->scrollbar.scroll_mode = scroll_mode; |
9120 #endif | 9120 #endif |
9121 } | 9121 } |
9131 | 9131 |
9132 | 9132 |
9133 /************************************************************************ | 9133 /************************************************************************ |
9134 Scroll bars, general | 9134 Scroll bars, general |
9135 ************************************************************************/ | 9135 ************************************************************************/ |
9136 | 9136 |
9137 /* Create a scroll bar and return the scroll bar vector for it. W is | 9137 /* Create a scroll bar and return the scroll bar vector for it. W is |
9138 the Emacs window on which to create the scroll bar. TOP, LEFT, | 9138 the Emacs window on which to create the scroll bar. TOP, LEFT, |
9139 WIDTH and HEIGHT are the pixel coordinates and dimensions of the | 9139 WIDTH and HEIGHT are the pixel coordinates and dimensions of the |
9140 scroll bar. */ | 9140 scroll bar. */ |
9141 | 9141 |
9159 Window window; | 9159 Window window; |
9160 | 9160 |
9161 a.background_pixel = f->output_data.x->scroll_bar_background_pixel; | 9161 a.background_pixel = f->output_data.x->scroll_bar_background_pixel; |
9162 if (a.background_pixel == -1) | 9162 if (a.background_pixel == -1) |
9163 a.background_pixel = f->output_data.x->background_pixel; | 9163 a.background_pixel = f->output_data.x->background_pixel; |
9164 | 9164 |
9165 a.event_mask = (ButtonPressMask | ButtonReleaseMask | 9165 a.event_mask = (ButtonPressMask | ButtonReleaseMask |
9166 | ButtonMotionMask | PointerMotionHintMask | 9166 | ButtonMotionMask | PointerMotionHintMask |
9167 | ExposureMask); | 9167 | ExposureMask); |
9168 a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; | 9168 a.cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; |
9169 | 9169 |
9229 return bar; | 9229 return bar; |
9230 } | 9230 } |
9231 | 9231 |
9232 | 9232 |
9233 /* Draw BAR's handle in the proper position. | 9233 /* Draw BAR's handle in the proper position. |
9234 | 9234 |
9235 If the handle is already drawn from START to END, don't bother | 9235 If the handle is already drawn from START to END, don't bother |
9236 redrawing it, unless REBUILD is non-zero; in that case, always | 9236 redrawing it, unless REBUILD is non-zero; in that case, always |
9237 redraw it. (REBUILD is handy for drawing the handle after expose | 9237 redraw it. (REBUILD is handy for drawing the handle after expose |
9238 events.) | 9238 events.) |
9239 | 9239 |
9356 #ifdef USE_TOOLKIT_SCROLL_BARS | 9356 #ifdef USE_TOOLKIT_SCROLL_BARS |
9357 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); | 9357 XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar)); |
9358 #else | 9358 #else |
9359 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); | 9359 XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar)); |
9360 #endif | 9360 #endif |
9361 | 9361 |
9362 /* Disassociate this scroll bar from its window. */ | 9362 /* Disassociate this scroll bar from its window. */ |
9363 XWINDOW (bar->window)->vertical_scroll_bar = Qnil; | 9363 XWINDOW (bar->window)->vertical_scroll_bar = Qnil; |
9364 | 9364 |
9365 UNBLOCK_INPUT; | 9365 UNBLOCK_INPUT; |
9366 } | 9366 } |
9403 sb_width = width; | 9403 sb_width = width; |
9404 | 9404 |
9405 /* Compute the left edge of the scroll bar. */ | 9405 /* Compute the left edge of the scroll bar. */ |
9406 #ifdef USE_TOOLKIT_SCROLL_BARS | 9406 #ifdef USE_TOOLKIT_SCROLL_BARS |
9407 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | 9407 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) |
9408 sb_left = left + width - sb_width - (width - sb_width) / 2; | 9408 sb_left = left + width - sb_width - (width - sb_width) / 2; |
9409 else | 9409 else |
9410 sb_left = left + (width - sb_width) / 2; | 9410 sb_left = left + (width - sb_width) / 2; |
9411 #else | 9411 #else |
9412 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | 9412 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) |
9413 sb_left = left + width - sb_width; | 9413 sb_left = left + width - sb_width; |
9414 else | 9414 else |
9415 sb_left = left; | 9415 sb_left = left; |
9416 #endif | 9416 #endif |
9417 | 9417 |
9418 /* Does the scroll bar exist yet? */ | 9418 /* Does the scroll bar exist yet? */ |
9419 if (NILP (w->vertical_scroll_bar)) | 9419 if (NILP (w->vertical_scroll_bar)) |
9420 { | 9420 { |
9421 if (width > 0 && height > 0) | 9421 if (width > 0 && height > 0) |
9422 { | 9422 { |
9423 BLOCK_INPUT; | 9423 BLOCK_INPUT; |
9424 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 9424 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
9425 left, top, width, height, False); | 9425 left, top, width, height, False); |
9426 UNBLOCK_INPUT; | 9426 UNBLOCK_INPUT; |
9427 } | 9427 } |
9428 | 9428 |
9429 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); | 9429 bar = x_scroll_bar_create (w, top, sb_left, sb_width, height); |
9430 } | 9430 } |
9431 else | 9431 else |
9432 { | 9432 { |
9433 /* It may just need to be moved and resized. */ | 9433 /* It may just need to be moved and resized. */ |
9434 unsigned int mask = 0; | 9434 unsigned int mask = 0; |
9435 | 9435 |
9436 bar = XSCROLL_BAR (w->vertical_scroll_bar); | 9436 bar = XSCROLL_BAR (w->vertical_scroll_bar); |
9437 | 9437 |
9438 BLOCK_INPUT; | 9438 BLOCK_INPUT; |
9439 | 9439 |
9440 if (sb_left != XINT (bar->left)) | 9440 if (sb_left != XINT (bar->left)) |
9441 mask |= CWX; | 9441 mask |= CWX; |
9442 if (top != XINT (bar->top)) | 9442 if (top != XINT (bar->top)) |
9443 mask |= CWY; | 9443 mask |= CWY; |
9444 if (sb_width != XINT (bar->width)) | 9444 if (sb_width != XINT (bar->width)) |
9445 mask |= CWWidth; | 9445 mask |= CWWidth; |
9446 if (height != XINT (bar->height)) | 9446 if (height != XINT (bar->height)) |
9447 mask |= CWHeight; | 9447 mask |= CWHeight; |
9448 | 9448 |
9449 #ifdef USE_TOOLKIT_SCROLL_BARS | 9449 #ifdef USE_TOOLKIT_SCROLL_BARS |
9450 | 9450 |
9451 /* Since toolkit scroll bars are smaller than the space reserved | 9451 /* Since toolkit scroll bars are smaller than the space reserved |
9452 for them on the frame, we have to clear "under" them. */ | 9452 for them on the frame, we have to clear "under" them. */ |
9453 if (width > 0 && height > 0) | 9453 if (width > 0 && height > 0) |
9461 top, | 9461 top, |
9462 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, | 9462 sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, |
9463 max (height, 1), 0); | 9463 max (height, 1), 0); |
9464 | 9464 |
9465 #else /* not USE_TOOLKIT_SCROLL_BARS */ | 9465 #else /* not USE_TOOLKIT_SCROLL_BARS */ |
9466 | 9466 |
9467 /* Clear areas not covered by the scroll bar because of | 9467 /* Clear areas not covered by the scroll bar because of |
9468 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */ | 9468 VERTICAL_SCROLL_BAR_WIDTH_TRIM. */ |
9469 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM) | 9469 if (VERTICAL_SCROLL_BAR_WIDTH_TRIM) |
9470 { | 9470 { |
9471 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 9471 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
9493 else | 9493 else |
9494 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 9494 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
9495 left, top, rest, height, False); | 9495 left, top, rest, height, False); |
9496 } | 9496 } |
9497 } | 9497 } |
9498 | 9498 |
9499 /* Move/size the scroll bar window. */ | 9499 /* Move/size the scroll bar window. */ |
9500 if (mask) | 9500 if (mask) |
9501 { | 9501 { |
9502 XWindowChanges wc; | 9502 XWindowChanges wc; |
9503 | 9503 |
9504 wc.x = sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM; | 9504 wc.x = sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM; |
9505 wc.y = top; | 9505 wc.y = top; |
9506 wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2; | 9506 wc.width = sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2; |
9507 wc.height = height; | 9507 wc.height = height; |
9508 XConfigureWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar), | 9508 XConfigureWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar), |
9509 mask, &wc); | 9509 mask, &wc); |
9510 } | 9510 } |
9511 | 9511 |
9512 #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 9512 #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
9513 | 9513 |
9514 /* Remember new settings. */ | 9514 /* Remember new settings. */ |
9515 XSETINT (bar->left, sb_left); | 9515 XSETINT (bar->left, sb_left); |
9516 XSETINT (bar->top, top); | 9516 XSETINT (bar->top, top); |
9517 XSETINT (bar->width, sb_width); | 9517 XSETINT (bar->width, sb_width); |
9518 XSETINT (bar->height, height); | 9518 XSETINT (bar->height, height); |
9519 | 9519 |
9520 UNBLOCK_INPUT; | 9520 UNBLOCK_INPUT; |
9521 } | 9521 } |
9522 | 9522 |
9523 #ifdef USE_TOOLKIT_SCROLL_BARS | 9523 #ifdef USE_TOOLKIT_SCROLL_BARS |
9524 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); | 9524 x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole); |
9678 | 9678 |
9679 /* x, y, width, height */ | 9679 /* x, y, width, height */ |
9680 0, 0, | 9680 0, 0, |
9681 XINT (bar->width) - 1 - width_trim - width_trim, | 9681 XINT (bar->width) - 1 - width_trim - width_trim, |
9682 XINT (bar->height) - 1); | 9682 XINT (bar->height) - 1); |
9683 | 9683 |
9684 UNBLOCK_INPUT; | 9684 UNBLOCK_INPUT; |
9685 | 9685 |
9686 #endif /* not USE_TOOLKIT_SCROLL_BARS */ | 9686 #endif /* not USE_TOOLKIT_SCROLL_BARS */ |
9687 } | 9687 } |
9688 | 9688 |
9704 abort (); | 9704 abort (); |
9705 | 9705 |
9706 emacs_event->kind = SCROLL_BAR_CLICK_EVENT; | 9706 emacs_event->kind = SCROLL_BAR_CLICK_EVENT; |
9707 emacs_event->code = event->xbutton.button - Button1; | 9707 emacs_event->code = event->xbutton.button - Button1; |
9708 emacs_event->modifiers | 9708 emacs_event->modifiers |
9709 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO | 9709 = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO |
9710 (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))), | 9710 (XFRAME (WINDOW_FRAME (XWINDOW (bar->window)))), |
9711 event->xbutton.state) | 9711 event->xbutton.state) |
9712 | (event->type == ButtonRelease | 9712 | (event->type == ButtonRelease |
9713 ? up_modifier | 9713 ? up_modifier |
9714 : down_modifier)); | 9714 : down_modifier)); |
10123 | 10123 |
10124 if (numchars <= 0) | 10124 if (numchars <= 0) |
10125 abort (); /* Don't think this happens. */ | 10125 abort (); /* Don't think this happens. */ |
10126 | 10126 |
10127 ++handling_signal; | 10127 ++handling_signal; |
10128 | 10128 |
10129 /* Find the display we are supposed to read input for. | 10129 /* Find the display we are supposed to read input for. |
10130 It's the one communicating on descriptor SD. */ | 10130 It's the one communicating on descriptor SD. */ |
10131 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | 10131 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) |
10132 { | 10132 { |
10133 #if 0 /* This ought to be unnecessary; let's verify it. */ | 10133 #if 0 /* This ought to be unnecessary; let's verify it. */ |
10219 The call to XSetInputFocus below has also caused trouble. In | 10219 The call to XSetInputFocus below has also caused trouble. In |
10220 cases where the XSetInputFocus done by the WM and the one | 10220 cases where the XSetInputFocus done by the WM and the one |
10221 below are temporally close (on a fast machine), the call | 10221 below are temporally close (on a fast machine), the call |
10222 below can generate additional FocusIn events which confuse | 10222 below can generate additional FocusIn events which confuse |
10223 Emacs. */ | 10223 Emacs. */ |
10224 | 10224 |
10225 /* Since we set WM_TAKE_FOCUS, we must call | 10225 /* Since we set WM_TAKE_FOCUS, we must call |
10226 XSetInputFocus explicitly. But not if f is null, | 10226 XSetInputFocus explicitly. But not if f is null, |
10227 since that might be an event for a deleted frame. */ | 10227 since that might be an event for a deleted frame. */ |
10228 if (f) | 10228 if (f) |
10229 { | 10229 { |
10238 event.xclient.data.l[1]); | 10238 event.xclient.data.l[1]); |
10239 /* This is needed to detect the error | 10239 /* This is needed to detect the error |
10240 if there is an error. */ | 10240 if there is an error. */ |
10241 XSync (d, False); | 10241 XSync (d, False); |
10242 x_uncatch_errors (d, count); | 10242 x_uncatch_errors (d, count); |
10243 } | 10243 } |
10244 /* Not certain about handling scroll bars here */ | 10244 /* Not certain about handling scroll bars here */ |
10245 #endif /* 0 */ | 10245 #endif /* 0 */ |
10246 } | 10246 } |
10247 else if (event.xclient.data.l[0] | 10247 else if (event.xclient.data.l[0] |
10248 == dpyinfo->Xatom_wm_save_yourself) | 10248 == dpyinfo->Xatom_wm_save_yourself) |
10526 if (event.xmap.window == tip_window) | 10526 if (event.xmap.window == tip_window) |
10527 { | 10527 { |
10528 tip_window = 0; | 10528 tip_window = 0; |
10529 redo_mouse_highlight (); | 10529 redo_mouse_highlight (); |
10530 } | 10530 } |
10531 | 10531 |
10532 f = x_top_window_to_frame (dpyinfo, event.xunmap.window); | 10532 f = x_top_window_to_frame (dpyinfo, event.xunmap.window); |
10533 if (f) /* F may no longer exist if | 10533 if (f) /* F may no longer exist if |
10534 the frame was deleted. */ | 10534 the frame was deleted. */ |
10535 { | 10535 { |
10536 /* While a frame is unmapped, display generation is | 10536 /* While a frame is unmapped, display generation is |
10560 case MapNotify: | 10560 case MapNotify: |
10561 if (event.xmap.window == tip_window) | 10561 if (event.xmap.window == tip_window) |
10562 /* The tooltip has been drawn already. Avoid | 10562 /* The tooltip has been drawn already. Avoid |
10563 the SET_FRAME_GARBAGED below. */ | 10563 the SET_FRAME_GARBAGED below. */ |
10564 goto OTHER; | 10564 goto OTHER; |
10565 | 10565 |
10566 /* We use x_top_window_to_frame because map events can | 10566 /* We use x_top_window_to_frame because map events can |
10567 come for sub-windows and they don't mean that the | 10567 come for sub-windows and they don't mean that the |
10568 frame is visible. */ | 10568 frame is visible. */ |
10569 f = x_top_window_to_frame (dpyinfo, event.xmap.window); | 10569 f = x_top_window_to_frame (dpyinfo, event.xmap.window); |
10570 if (f) | 10570 if (f) |
10879 if (nchars == nbytes) | 10879 if (nchars == nbytes) |
10880 c = copy_bufptr[i], len = 1; | 10880 c = copy_bufptr[i], len = 1; |
10881 else | 10881 else |
10882 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, | 10882 c = STRING_CHAR_AND_LENGTH (copy_bufptr + i, |
10883 nbytes - i, len); | 10883 nbytes - i, len); |
10884 | 10884 |
10885 bufp->kind = (SINGLE_BYTE_CHAR_P (c) | 10885 bufp->kind = (SINGLE_BYTE_CHAR_P (c) |
10886 ? ASCII_KEYSTROKE_EVENT | 10886 ? ASCII_KEYSTROKE_EVENT |
10887 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | 10887 : MULTIBYTE_CHAR_KEYSTROKE_EVENT); |
10888 bufp->code = c; | 10888 bufp->code = c; |
10889 XSETFRAME (bufp->frame_or_window, f); | 10889 XSETFRAME (bufp->frame_or_window, f); |
10933 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); | 10933 n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); |
10934 if (n > 0) | 10934 if (n > 0) |
10935 { | 10935 { |
10936 bufp += n, count += n, numchars -= n; | 10936 bufp += n, count += n, numchars -= n; |
10937 } | 10937 } |
10938 | 10938 |
10939 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); | 10939 f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); |
10940 | 10940 |
10941 #if 0 | 10941 #if 0 |
10942 if (event.xcrossing.focus) | 10942 if (event.xcrossing.focus) |
10943 { | 10943 { |
11031 case MotionNotify: | 11031 case MotionNotify: |
11032 { | 11032 { |
11033 previous_help_echo = help_echo; | 11033 previous_help_echo = help_echo; |
11034 help_echo = help_echo_object = help_echo_window = Qnil; | 11034 help_echo = help_echo_object = help_echo_window = Qnil; |
11035 help_echo_pos = -1; | 11035 help_echo_pos = -1; |
11036 | 11036 |
11037 if (dpyinfo->grabbed && last_mouse_frame | 11037 if (dpyinfo->grabbed && last_mouse_frame |
11038 && FRAME_LIVE_P (last_mouse_frame)) | 11038 && FRAME_LIVE_P (last_mouse_frame)) |
11039 f = last_mouse_frame; | 11039 f = last_mouse_frame; |
11040 else | 11040 else |
11041 f = x_window_to_frame (dpyinfo, event.xmotion.window); | 11041 f = x_window_to_frame (dpyinfo, event.xmotion.window); |
11109 n = gen_help_event (bufp, numchars, help_echo, frame, | 11109 n = gen_help_event (bufp, numchars, help_echo, frame, |
11110 help_echo_window, help_echo_object, | 11110 help_echo_window, help_echo_object, |
11111 help_echo_pos); | 11111 help_echo_pos); |
11112 bufp += n, count += n, numchars -= n; | 11112 bufp += n, count += n, numchars -= n; |
11113 } | 11113 } |
11114 | 11114 |
11115 goto OTHER; | 11115 goto OTHER; |
11116 } | 11116 } |
11117 | 11117 |
11118 case ConfigureNotify: | 11118 case ConfigureNotify: |
11119 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window); | 11119 f = x_top_window_to_frame (dpyinfo, event.xconfigure.window); |
11129 && FRAME_NEW_WIDTH (f) != 0); | 11129 && FRAME_NEW_WIDTH (f) != 0); |
11130 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height); | 11130 int rows = PIXEL_TO_CHAR_HEIGHT (f, event.xconfigure.height); |
11131 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width); | 11131 int columns = PIXEL_TO_CHAR_WIDTH (f, event.xconfigure.width); |
11132 if (dont_resize) | 11132 if (dont_resize) |
11133 goto OTHER; | 11133 goto OTHER; |
11134 | 11134 |
11135 /* In the toolkit version, change_frame_size | 11135 /* In the toolkit version, change_frame_size |
11136 is called by the code that handles resizing | 11136 is called by the code that handles resizing |
11137 of the EmacsFrame widget. */ | 11137 of the EmacsFrame widget. */ |
11138 | 11138 |
11139 /* Even if the number of character rows and columns has | 11139 /* Even if the number of character rows and columns has |
11182 { | 11182 { |
11183 /* If we decide we want to generate an event to be seen | 11183 /* If we decide we want to generate an event to be seen |
11184 by the rest of Emacs, we put it here. */ | 11184 by the rest of Emacs, we put it here. */ |
11185 struct input_event emacs_event; | 11185 struct input_event emacs_event; |
11186 int tool_bar_p = 0; | 11186 int tool_bar_p = 0; |
11187 | 11187 |
11188 emacs_event.kind = NO_EVENT; | 11188 emacs_event.kind = NO_EVENT; |
11189 bzero (&compose_status, sizeof (compose_status)); | 11189 bzero (&compose_status, sizeof (compose_status)); |
11190 | 11190 |
11191 if (dpyinfo->grabbed | 11191 if (dpyinfo->grabbed |
11192 && last_mouse_frame | 11192 && last_mouse_frame |
11240 before this event; any subsequent mouse-movement | 11240 before this event; any subsequent mouse-movement |
11241 Emacs events should reflect only motion after | 11241 Emacs events should reflect only motion after |
11242 the ButtonPress. */ | 11242 the ButtonPress. */ |
11243 if (f != 0) | 11243 if (f != 0) |
11244 f->mouse_moved = 0; | 11244 f->mouse_moved = 0; |
11245 | 11245 |
11246 if (!tool_bar_p) | 11246 if (!tool_bar_p) |
11247 last_tool_bar_item = -1; | 11247 last_tool_bar_item = -1; |
11248 } | 11248 } |
11249 else | 11249 else |
11250 { | 11250 { |
11304 } | 11304 } |
11305 break; | 11305 break; |
11306 | 11306 |
11307 case CirculateNotify: | 11307 case CirculateNotify: |
11308 goto OTHER; | 11308 goto OTHER; |
11309 | 11309 |
11310 case CirculateRequest: | 11310 case CirculateRequest: |
11311 goto OTHER; | 11311 goto OTHER; |
11312 | 11312 |
11313 case VisibilityNotify: | 11313 case VisibilityNotify: |
11314 goto OTHER; | 11314 goto OTHER; |
11418 Likewise if part of the cursor is below y1, with the | 11418 Likewise if part of the cursor is below y1, with the |
11419 exception of the cursor being in the first blank row at | 11419 exception of the cursor being in the first blank row at |
11420 the buffer and window end because update_text_area | 11420 the buffer and window end because update_text_area |
11421 doesn't draw that row. (Except when it does, but | 11421 doesn't draw that row. (Except when it does, but |
11422 that's handled in update_text_area.) */ | 11422 that's handled in update_text_area.) */ |
11423 | 11423 |
11424 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) | 11424 if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) |
11425 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) | 11425 && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) |
11426 w->phys_cursor_on_p = 0; | 11426 w->phys_cursor_on_p = 0; |
11427 } | 11427 } |
11428 } | 11428 } |
11504 wd = cursor_glyph->pixel_width - 1; | 11504 wd = cursor_glyph->pixel_width - 1; |
11505 if (cursor_glyph->type == STRETCH_GLYPH | 11505 if (cursor_glyph->type == STRETCH_GLYPH |
11506 && !x_stretch_cursor_p) | 11506 && !x_stretch_cursor_p) |
11507 wd = min (CANON_X_UNIT (f), wd); | 11507 wd = min (CANON_X_UNIT (f), wd); |
11508 w->phys_cursor_width = wd; | 11508 w->phys_cursor_width = wd; |
11509 | 11509 |
11510 /* The foreground of cursor_gc is typically the same as the normal | 11510 /* The foreground of cursor_gc is typically the same as the normal |
11511 background color, which can cause the cursor box to be invisible. */ | 11511 background color, which can cause the cursor box to be invisible. */ |
11512 xgcv.foreground = f->output_data.x->cursor_pixel; | 11512 xgcv.foreground = f->output_data.x->cursor_pixel; |
11513 if (dpyinfo->scratch_cursor_gc) | 11513 if (dpyinfo->scratch_cursor_gc) |
11514 XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv); | 11514 XChangeGC (dpy, dpyinfo->scratch_cursor_gc, GCForeground, &xgcv); |
11538 int width; | 11538 int width; |
11539 enum text_cursor_kinds kind; | 11539 enum text_cursor_kinds kind; |
11540 { | 11540 { |
11541 struct frame *f = XFRAME (w->frame); | 11541 struct frame *f = XFRAME (w->frame); |
11542 struct glyph *cursor_glyph; | 11542 struct glyph *cursor_glyph; |
11543 | 11543 |
11544 /* If cursor is out of bounds, don't draw garbage. This can happen | 11544 /* If cursor is out of bounds, don't draw garbage. This can happen |
11545 in mini-buffer windows when switching between echo area glyphs | 11545 in mini-buffer windows when switching between echo area glyphs |
11546 and mini-buffer. */ | 11546 and mini-buffer. */ |
11547 cursor_glyph = get_phys_cursor_glyph (w); | 11547 cursor_glyph = get_phys_cursor_glyph (w); |
11548 if (cursor_glyph == NULL) | 11548 if (cursor_glyph == NULL) |
11574 if (face->background == f->output_data.x->cursor_pixel) | 11574 if (face->background == f->output_data.x->cursor_pixel) |
11575 xgcv.background = xgcv.foreground = face->foreground; | 11575 xgcv.background = xgcv.foreground = face->foreground; |
11576 else | 11576 else |
11577 xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel; | 11577 xgcv.background = xgcv.foreground = f->output_data.x->cursor_pixel; |
11578 xgcv.graphics_exposures = 0; | 11578 xgcv.graphics_exposures = 0; |
11579 | 11579 |
11580 if (gc) | 11580 if (gc) |
11581 XChangeGC (dpy, gc, mask, &xgcv); | 11581 XChangeGC (dpy, gc, mask, &xgcv); |
11582 else | 11582 else |
11583 { | 11583 { |
11584 gc = XCreateGC (dpy, window, mask, &xgcv); | 11584 gc = XCreateGC (dpy, window, mask, &xgcv); |
11585 FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc = gc; | 11585 FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc = gc; |
11586 } | 11586 } |
11587 | 11587 |
11588 if (width < 0) | 11588 if (width < 0) |
11589 width = FRAME_CURSOR_WIDTH (f); | 11589 width = FRAME_CURSOR_WIDTH (f); |
11590 width = min (cursor_glyph->pixel_width, width); | 11590 width = min (cursor_glyph->pixel_width, width); |
11591 | 11591 |
11592 w->phys_cursor_width = width; | 11592 w->phys_cursor_width = width; |
11593 x_clip_to_row (w, row, gc, 0); | 11593 x_clip_to_row (w, row, gc, 0); |
11594 | 11594 |
11595 if (kind == BAR_CURSOR) | 11595 if (kind == BAR_CURSOR) |
11596 XFillRectangle (dpy, window, gc, | 11596 XFillRectangle (dpy, window, gc, |
11597 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), | 11597 WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), |
11598 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), | 11598 WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), |
11599 width, row->height); | 11599 width, row->height); |
11637 glyphs and mini-buffer. */ | 11637 glyphs and mini-buffer. */ |
11638 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) | 11638 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) |
11639 { | 11639 { |
11640 int on_p = w->phys_cursor_on_p; | 11640 int on_p = w->phys_cursor_on_p; |
11641 int x1; | 11641 int x1; |
11642 | 11642 |
11643 x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, | 11643 x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, |
11644 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, | 11644 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, |
11645 hl, 0); | 11645 hl, 0); |
11646 w->phys_cursor_on_p = on_p; | 11646 w->phys_cursor_on_p = on_p; |
11647 | 11647 |
11683 | 11683 |
11684 /* No cursor displayed or row invalidated => nothing to do on the | 11684 /* No cursor displayed or row invalidated => nothing to do on the |
11685 screen. */ | 11685 screen. */ |
11686 if (w->phys_cursor_type == NO_CURSOR) | 11686 if (w->phys_cursor_type == NO_CURSOR) |
11687 goto mark_cursor_off; | 11687 goto mark_cursor_off; |
11688 | 11688 |
11689 /* VPOS >= active_glyphs->nrows means that window has been resized. | 11689 /* VPOS >= active_glyphs->nrows means that window has been resized. |
11690 Don't bother to erase the cursor. */ | 11690 Don't bother to erase the cursor. */ |
11691 if (vpos >= active_glyphs->nrows) | 11691 if (vpos >= active_glyphs->nrows) |
11692 goto mark_cursor_off; | 11692 goto mark_cursor_off; |
11693 | 11693 |
11694 /* If row containing cursor is marked invalid, there is nothing we | 11694 /* If row containing cursor is marked invalid, there is nothing we |
11695 can do. */ | 11695 can do. */ |
11696 cursor_row = MATRIX_ROW (active_glyphs, vpos); | 11696 cursor_row = MATRIX_ROW (active_glyphs, vpos); |
11697 if (!cursor_row->enabled_p) | 11697 if (!cursor_row->enabled_p) |
11698 goto mark_cursor_off; | 11698 goto mark_cursor_off; |
11699 | 11699 |
11700 /* If row is completely invisible, don't attempt to delete a cursor which | 11700 /* If row is completely invisible, don't attempt to delete a cursor which |
11701 isn't there. This can happen if cursor is at top of a window, and | 11701 isn't there. This can happen if cursor is at top of a window, and |
11702 we switch to a buffer with a header line in that window. */ | 11702 we switch to a buffer with a header line in that window. */ |
11703 if (cursor_row->visible_height <= 0) | 11703 if (cursor_row->visible_height <= 0) |
11704 goto mark_cursor_off; | 11704 goto mark_cursor_off; |
11705 | 11705 |
11706 /* This can happen when the new row is shorter than the old one. | 11706 /* This can happen when the new row is shorter than the old one. |
11707 In this case, either x_draw_glyphs or clear_end_of_line | 11707 In this case, either x_draw_glyphs or clear_end_of_line |
11708 should have cleared the cursor. Note that we wouldn't be | 11708 should have cleared the cursor. Note that we wouldn't be |
11709 able to erase the cursor in this case because we don't have a | 11709 able to erase the cursor in this case because we don't have a |
11710 cursor glyph at hand. */ | 11710 cursor glyph at hand. */ |
11711 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) | 11711 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA]) |
11712 goto mark_cursor_off; | 11712 goto mark_cursor_off; |
11713 | 11713 |
11714 /* If the cursor is in the mouse face area, redisplay that when | 11714 /* If the cursor is in the mouse face area, redisplay that when |
11715 we clear the cursor. */ | 11715 we clear the cursor. */ |
11716 if (! NILP (dpyinfo->mouse_face_window) | 11716 if (! NILP (dpyinfo->mouse_face_window) |
11717 && w == XWINDOW (dpyinfo->mouse_face_window) | 11717 && w == XWINDOW (dpyinfo->mouse_face_window) |
11718 && (vpos > dpyinfo->mouse_face_beg_row | 11718 && (vpos > dpyinfo->mouse_face_beg_row |
11736 cursor_glyph = get_phys_cursor_glyph (w); | 11736 cursor_glyph = get_phys_cursor_glyph (w); |
11737 if (cursor_glyph == NULL) | 11737 if (cursor_glyph == NULL) |
11738 goto mark_cursor_off; | 11738 goto mark_cursor_off; |
11739 | 11739 |
11740 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); | 11740 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x); |
11741 | 11741 |
11742 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 11742 x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
11743 x, | 11743 x, |
11744 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, | 11744 WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, |
11745 cursor_row->y)), | 11745 cursor_row->y)), |
11746 cursor_glyph->pixel_width, | 11746 cursor_glyph->pixel_width, |
11747 cursor_row->visible_height, | 11747 cursor_row->visible_height, |
11748 False); | 11748 False); |
11749 } | 11749 } |
11750 | 11750 |
11751 /* Erase the cursor by redrawing the character underneath it. */ | 11751 /* Erase the cursor by redrawing the character underneath it. */ |
11752 if (mouse_face_here_p) | 11752 if (mouse_face_here_p) |
11753 hl = DRAW_MOUSE_FACE; | 11753 hl = DRAW_MOUSE_FACE; |
11754 else | 11754 else |
11755 hl = DRAW_NORMAL_TEXT; | 11755 hl = DRAW_NORMAL_TEXT; |
11767 cursor_in_mouse_face_p (w) | 11767 cursor_in_mouse_face_p (w) |
11768 struct window *w; | 11768 struct window *w; |
11769 { | 11769 { |
11770 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); | 11770 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame)); |
11771 int in_mouse_face = 0; | 11771 int in_mouse_face = 0; |
11772 | 11772 |
11773 if (WINDOWP (dpyinfo->mouse_face_window) | 11773 if (WINDOWP (dpyinfo->mouse_face_window) |
11774 && XWINDOW (dpyinfo->mouse_face_window) == w) | 11774 && XWINDOW (dpyinfo->mouse_face_window) == w) |
11775 { | 11775 { |
11776 int hpos = w->phys_cursor.hpos; | 11776 int hpos = w->phys_cursor.hpos; |
11777 int vpos = w->phys_cursor.vpos; | 11777 int vpos = w->phys_cursor.vpos; |
11821 return; | 11821 return; |
11822 | 11822 |
11823 current_glyphs = w->current_matrix; | 11823 current_glyphs = w->current_matrix; |
11824 glyph_row = MATRIX_ROW (current_glyphs, vpos); | 11824 glyph_row = MATRIX_ROW (current_glyphs, vpos); |
11825 glyph = glyph_row->glyphs[TEXT_AREA] + hpos; | 11825 glyph = glyph_row->glyphs[TEXT_AREA] + hpos; |
11826 | 11826 |
11827 /* If cursor row is not enabled, we don't really know where to | 11827 /* If cursor row is not enabled, we don't really know where to |
11828 display the cursor. */ | 11828 display the cursor. */ |
11829 if (!glyph_row->enabled_p) | 11829 if (!glyph_row->enabled_p) |
11830 { | 11830 { |
11831 w->phys_cursor_on_p = 0; | 11831 w->phys_cursor_on_p = 0; |
11832 return; | 11832 return; |
11856 still not be visible, or it has only been partly erased. */ | 11856 still not be visible, or it has only been partly erased. */ |
11857 if (on) | 11857 if (on) |
11858 { | 11858 { |
11859 w->phys_cursor_ascent = glyph_row->ascent; | 11859 w->phys_cursor_ascent = glyph_row->ascent; |
11860 w->phys_cursor_height = glyph_row->height; | 11860 w->phys_cursor_height = glyph_row->height; |
11861 | 11861 |
11862 /* Set phys_cursor_.* before x_draw_.* is called because some | 11862 /* Set phys_cursor_.* before x_draw_.* is called because some |
11863 of them may need the information. */ | 11863 of them may need the information. */ |
11864 w->phys_cursor.x = x; | 11864 w->phys_cursor.x = x; |
11865 w->phys_cursor.y = glyph_row->y; | 11865 w->phys_cursor.y = glyph_row->y; |
11866 w->phys_cursor.hpos = hpos; | 11866 w->phys_cursor.hpos = hpos; |
11891 break; | 11891 break; |
11892 | 11892 |
11893 default: | 11893 default: |
11894 abort (); | 11894 abort (); |
11895 } | 11895 } |
11896 | 11896 |
11897 #ifdef HAVE_X_I18N | 11897 #ifdef HAVE_X_I18N |
11898 if (w == XWINDOW (f->selected_window)) | 11898 if (w == XWINDOW (f->selected_window)) |
11899 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMPreeditPosition)) | 11899 if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMPreeditPosition)) |
11900 xic_set_preeditarea (w, x, y); | 11900 xic_set_preeditarea (w, x, y); |
11901 #endif | 11901 #endif |
12186 #endif /* ! 0 */ | 12186 #endif /* ! 0 */ |
12187 | 12187 |
12188 | 12188 |
12189 /* Handle SIGPIPE, which can happen when the connection to a server | 12189 /* Handle SIGPIPE, which can happen when the connection to a server |
12190 simply goes away. SIGPIPE is handled by x_connection_signal. | 12190 simply goes away. SIGPIPE is handled by x_connection_signal. |
12191 Don't need to do anything, because the write which caused the | 12191 Don't need to do anything, because the write which caused the |
12192 SIGPIPE will fail, causing Xlib to invoke the X IO error handler, | 12192 SIGPIPE will fail, causing Xlib to invoke the X IO error handler, |
12193 which will do the appropriate cleanup for us. */ | 12193 which will do the appropriate cleanup for us. */ |
12194 | 12194 |
12195 static SIGTYPE | 12195 static SIGTYPE |
12196 x_connection_signal (signalnum) /* If we don't have an argument, */ | 12196 x_connection_signal (signalnum) /* If we don't have an argument, */ |
12197 int signalnum; /* some compilers complain in signal calls. */ | 12197 int signalnum; /* some compilers complain in signal calls. */ |
12198 { | 12198 { |
12199 #ifdef USG | 12199 #ifdef USG |
12232 char *error_message; | 12232 char *error_message; |
12233 { | 12233 { |
12234 struct x_display_info *dpyinfo = x_display_info_for_display (dpy); | 12234 struct x_display_info *dpyinfo = x_display_info_for_display (dpy); |
12235 Lisp_Object frame, tail; | 12235 Lisp_Object frame, tail; |
12236 int count; | 12236 int count; |
12237 | 12237 |
12238 error_msg = (char *) alloca (strlen (error_message) + 1); | 12238 error_msg = (char *) alloca (strlen (error_message) + 1); |
12239 strcpy (error_msg, error_message); | 12239 strcpy (error_msg, error_message); |
12240 handling_signal = 0; | 12240 handling_signal = 0; |
12241 | 12241 |
12242 /* Prevent being called recursively because of an error condition | 12242 /* Prevent being called recursively because of an error condition |
12243 below. Otherwise, we might end up with printing ``can't find per | 12243 below. Otherwise, we might end up with printing ``can't find per |
12244 display information'' in the recursive call instead of printing | 12244 display information'' in the recursive call instead of printing |
12245 the original message here. */ | 12245 the original message here. */ |
12246 count = x_catch_errors (dpy); | 12246 count = x_catch_errors (dpy); |
12247 | 12247 |
12248 /* We have to close the display to inform Xt that it doesn't | 12248 /* We have to close the display to inform Xt that it doesn't |
12249 exist anymore. If we don't, Xt will continue to wait for | 12249 exist anymore. If we don't, Xt will continue to wait for |
12250 events from the display. As a consequence, a sequence of | 12250 events from the display. As a consequence, a sequence of |
12251 | 12251 |
12252 M-x make-frame-on-display RET :1 RET | 12252 M-x make-frame-on-display RET :1 RET |
12257 in the first class to make-frame-on-display. | 12257 in the first class to make-frame-on-display. |
12258 | 12258 |
12259 Closing the display is reported to lead to a bus error on | 12259 Closing the display is reported to lead to a bus error on |
12260 OpenWindows in certain situations. I suspect that is a bug | 12260 OpenWindows in certain situations. I suspect that is a bug |
12261 in OpenWindows. I don't know how to cicumvent it here. */ | 12261 in OpenWindows. I don't know how to cicumvent it here. */ |
12262 | 12262 |
12263 #ifdef USE_X_TOOLKIT | 12263 #ifdef USE_X_TOOLKIT |
12264 /* If DPYINFO is null, this means we didn't open the display | 12264 /* If DPYINFO is null, this means we didn't open the display |
12265 in the first place, so don't try to close it. */ | 12265 in the first place, so don't try to close it. */ |
12266 if (dpyinfo) | 12266 if (dpyinfo) |
12267 { | 12267 { |
12305 | 12305 |
12306 if (dpyinfo) | 12306 if (dpyinfo) |
12307 x_delete_display (dpyinfo); | 12307 x_delete_display (dpyinfo); |
12308 | 12308 |
12309 x_uncatch_errors (dpy, count); | 12309 x_uncatch_errors (dpy, count); |
12310 | 12310 |
12311 if (x_display_list == 0) | 12311 if (x_display_list == 0) |
12312 { | 12312 { |
12313 fprintf (stderr, "%s\n", error_msg); | 12313 fprintf (stderr, "%s\n", error_msg); |
12314 shut_down_emacs (0, 0, Qnil); | 12314 shut_down_emacs (0, 0, Qnil); |
12315 exit (70); | 12315 exit (70); |
12473 #ifdef HAVE_X_I18N | 12473 #ifdef HAVE_X_I18N |
12474 if (FRAME_XIC (f) | 12474 if (FRAME_XIC (f) |
12475 && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea))) | 12475 && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea))) |
12476 xic_set_xfontset (f, SDATA (fontset_ascii (fontset))); | 12476 xic_set_xfontset (f, SDATA (fontset_ascii (fontset))); |
12477 #endif | 12477 #endif |
12478 | 12478 |
12479 return build_string (fontsetname); | 12479 return build_string (fontsetname); |
12480 } | 12480 } |
12481 | 12481 |
12482 /* Compute actual fringe widths */ | 12482 /* Compute actual fringe widths */ |
12483 | 12483 |
12582 XPointer client_data; | 12582 XPointer client_data; |
12583 XPointer call_data; | 12583 XPointer call_data; |
12584 { | 12584 { |
12585 struct x_display_info *dpyinfo = (struct x_display_info *) client_data; | 12585 struct x_display_info *dpyinfo = (struct x_display_info *) client_data; |
12586 Lisp_Object frame, tail; | 12586 Lisp_Object frame, tail; |
12587 | 12587 |
12588 BLOCK_INPUT; | 12588 BLOCK_INPUT; |
12589 | 12589 |
12590 /* No need to call XDestroyIC.. */ | 12590 /* No need to call XDestroyIC.. */ |
12591 FOR_EACH_FRAME (tail, frame) | 12591 FOR_EACH_FRAME (tail, frame) |
12592 { | 12592 { |
12593 struct frame *f = XFRAME (frame); | 12593 struct frame *f = XFRAME (frame); |
12594 if (FRAME_X_DISPLAY_INFO (f) == dpyinfo) | 12594 if (FRAME_X_DISPLAY_INFO (f) == dpyinfo) |
12599 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); | 12599 XFreeFontSet (FRAME_X_DISPLAY (f), FRAME_XIC_FONTSET (f)); |
12600 FRAME_XIC_FONTSET (f) = NULL; | 12600 FRAME_XIC_FONTSET (f) = NULL; |
12601 } | 12601 } |
12602 } | 12602 } |
12603 } | 12603 } |
12604 | 12604 |
12605 /* No need to call XCloseIM. */ | 12605 /* No need to call XCloseIM. */ |
12606 dpyinfo->xim = NULL; | 12606 dpyinfo->xim = NULL; |
12607 XFree (dpyinfo->xim_styles); | 12607 XFree (dpyinfo->xim_styles); |
12608 UNBLOCK_INPUT; | 12608 UNBLOCK_INPUT; |
12609 } | 12609 } |
12627 if (xim) | 12627 if (xim) |
12628 { | 12628 { |
12629 #ifdef HAVE_X11R6 | 12629 #ifdef HAVE_X11R6 |
12630 XIMCallback destroy; | 12630 XIMCallback destroy; |
12631 #endif | 12631 #endif |
12632 | 12632 |
12633 /* Get supported styles and XIM values. */ | 12633 /* Get supported styles and XIM values. */ |
12634 XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL); | 12634 XGetIMValues (xim, XNQueryInputStyle, &dpyinfo->xim_styles, NULL); |
12635 | 12635 |
12636 #ifdef HAVE_X11R6 | 12636 #ifdef HAVE_X11R6 |
12637 destroy.callback = xim_destroy_callback; | 12637 destroy.callback = xim_destroy_callback; |
12638 destroy.client_data = (XPointer)dpyinfo; | 12638 destroy.client_data = (XPointer)dpyinfo; |
12639 /* This isn't prototyped in OSF 5.0. */ | 12639 /* This isn't prototyped in OSF 5.0. */ |
12640 XSetIMValues (xim, XNDestroyCallback, &destroy, NULL); | 12640 XSetIMValues (xim, XNDestroyCallback, &destroy, NULL); |
12641 #endif | 12641 #endif |
12642 } | 12642 } |
12643 | 12643 |
12644 #else /* not USE_XIM */ | 12644 #else /* not USE_XIM */ |
12645 dpyinfo->xim = NULL; | 12645 dpyinfo->xim = NULL; |
12646 #endif /* not USE_XIM */ | 12646 #endif /* not USE_XIM */ |
12647 } | 12647 } |
12648 | 12648 |
12670 struct x_display_info *dpyinfo = xim_inst->dpyinfo; | 12670 struct x_display_info *dpyinfo = xim_inst->dpyinfo; |
12671 | 12671 |
12672 /* We don't support multiple XIM connections. */ | 12672 /* We don't support multiple XIM connections. */ |
12673 if (dpyinfo->xim) | 12673 if (dpyinfo->xim) |
12674 return; | 12674 return; |
12675 | 12675 |
12676 xim_open_dpy (dpyinfo, xim_inst->resource_name); | 12676 xim_open_dpy (dpyinfo, xim_inst->resource_name); |
12677 | 12677 |
12678 /* Create XIC for the existing frames on the same display, as long | 12678 /* Create XIC for the existing frames on the same display, as long |
12679 as they have no XIC. */ | 12679 as they have no XIC. */ |
12680 if (dpyinfo->xim && dpyinfo->reference_count > 0) | 12680 if (dpyinfo->xim && dpyinfo->reference_count > 0) |
12683 | 12683 |
12684 BLOCK_INPUT; | 12684 BLOCK_INPUT; |
12685 FOR_EACH_FRAME (tail, frame) | 12685 FOR_EACH_FRAME (tail, frame) |
12686 { | 12686 { |
12687 struct frame *f = XFRAME (frame); | 12687 struct frame *f = XFRAME (frame); |
12688 | 12688 |
12689 if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) | 12689 if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo) |
12690 if (FRAME_XIC (f) == NULL) | 12690 if (FRAME_XIC (f) == NULL) |
12691 { | 12691 { |
12692 create_frame_xic (f); | 12692 create_frame_xic (f); |
12693 if (FRAME_XIC_STYLE (f) & XIMStatusArea) | 12693 if (FRAME_XIC_STYLE (f) & XIMStatusArea) |
12697 struct window *w = XWINDOW (f->selected_window); | 12697 struct window *w = XWINDOW (f->selected_window); |
12698 xic_set_preeditarea (w, w->cursor.x, w->cursor.y); | 12698 xic_set_preeditarea (w, w->cursor.x, w->cursor.y); |
12699 } | 12699 } |
12700 } | 12700 } |
12701 } | 12701 } |
12702 | 12702 |
12703 UNBLOCK_INPUT; | 12703 UNBLOCK_INPUT; |
12704 } | 12704 } |
12705 } | 12705 } |
12706 | 12706 |
12707 #endif /* HAVE_X11R6_XIM */ | 12707 #endif /* HAVE_X11R6_XIM */ |
12719 { | 12719 { |
12720 #ifdef USE_XIM | 12720 #ifdef USE_XIM |
12721 #ifdef HAVE_X11R6_XIM | 12721 #ifdef HAVE_X11R6_XIM |
12722 struct xim_inst_t *xim_inst; | 12722 struct xim_inst_t *xim_inst; |
12723 int len; | 12723 int len; |
12724 | 12724 |
12725 dpyinfo->xim = NULL; | 12725 dpyinfo->xim = NULL; |
12726 xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t)); | 12726 xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t)); |
12727 xim_inst->dpyinfo = dpyinfo; | 12727 xim_inst->dpyinfo = dpyinfo; |
12728 len = strlen (resource_name); | 12728 len = strlen (resource_name); |
12729 xim_inst->resource_name = (char *) xmalloc (len + 1); | 12729 xim_inst->resource_name = (char *) xmalloc (len + 1); |
12737 (XPointer) xim_inst); | 12737 (XPointer) xim_inst); |
12738 #else /* not HAVE_X11R6_XIM */ | 12738 #else /* not HAVE_X11R6_XIM */ |
12739 dpyinfo->xim = NULL; | 12739 dpyinfo->xim = NULL; |
12740 xim_open_dpy (dpyinfo, resource_name); | 12740 xim_open_dpy (dpyinfo, resource_name); |
12741 #endif /* not HAVE_X11R6_XIM */ | 12741 #endif /* not HAVE_X11R6_XIM */ |
12742 | 12742 |
12743 #else /* not USE_XIM */ | 12743 #else /* not USE_XIM */ |
12744 dpyinfo->xim = NULL; | 12744 dpyinfo->xim = NULL; |
12745 #endif /* not USE_XIM */ | 12745 #endif /* not USE_XIM */ |
12746 } | 12746 } |
12747 | 12747 |
12859 later invocations, when Emacs is up, the frame's pixel height | 12859 later invocations, when Emacs is up, the frame's pixel height |
12860 is right, though. | 12860 is right, though. |
12861 | 12861 |
12862 It's not obvious where the initial small difference comes from. | 12862 It's not obvious where the initial small difference comes from. |
12863 2000-12-01, gerd. */ | 12863 2000-12-01, gerd. */ |
12864 | 12864 |
12865 XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); | 12865 XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL); |
12866 #endif | 12866 #endif |
12867 | 12867 |
12868 if (flags & YNegative) | 12868 if (flags & YNegative) |
12869 f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height | 12869 f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height |
12870 - 2 * f->output_data.x->border_width | 12870 - 2 * f->output_data.x->border_width |
12871 - win_y | 12871 - win_y |
12872 - height | 12872 - height |
12873 + f->output_data.x->top_pos); | 12873 + f->output_data.x->top_pos); |
12874 } | 12874 } |
12875 | 12875 |
12876 /* The left_pos and top_pos | 12876 /* The left_pos and top_pos |
12877 are now relative to the top and left screen edges, | 12877 are now relative to the top and left screen edges, |
12878 so the flags should correspond. */ | 12878 so the flags should correspond. */ |
12879 f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative); | 12879 f->output_data.x->size_hint_flags &= ~ (XNegative | YNegative); |
12880 } | 12880 } |
12939 struct frame *f; | 12939 struct frame *f; |
12940 { | 12940 { |
12941 if (f->output_data.x->want_fullscreen & FULLSCREEN_BOTH) | 12941 if (f->output_data.x->want_fullscreen & FULLSCREEN_BOTH) |
12942 { | 12942 { |
12943 int width, height, ign; | 12943 int width, height, ign; |
12944 | 12944 |
12945 x_real_positions (f, &f->output_data.x->left_pos, | 12945 x_real_positions (f, &f->output_data.x->left_pos, |
12946 &f->output_data.x->top_pos); | 12946 &f->output_data.x->top_pos); |
12947 | 12947 |
12948 x_fullscreen_adjust (f, &width, &height, &ign, &ign); | 12948 x_fullscreen_adjust (f, &width, &height, &ign, &ign); |
12949 | 12949 |
12950 /* We do not need to move the window, it shall be taken care of | 12950 /* We do not need to move the window, it shall be taken care of |
12951 when setting WM manager hints. | 12951 when setting WM manager hints. |
12952 If the frame is visible already, the position is checked by | 12952 If the frame is visible already, the position is checked by |
12953 x_check_fullscreen_move. */ | 12953 x_check_fullscreen_move. */ |
12954 if (f->width != width || f->height != height) | 12954 if (f->width != width || f->height != height) |
12957 SET_FRAME_GARBAGED (f); | 12957 SET_FRAME_GARBAGED (f); |
12958 cancel_mouse_face (f); | 12958 cancel_mouse_face (f); |
12959 | 12959 |
12960 /* Wait for the change of frame size to occur */ | 12960 /* Wait for the change of frame size to occur */ |
12961 f->output_data.x->want_fullscreen |= FULLSCREEN_WAIT; | 12961 f->output_data.x->want_fullscreen |= FULLSCREEN_WAIT; |
12962 | 12962 |
12963 } | 12963 } |
12964 } | 12964 } |
12965 } | 12965 } |
12966 | 12966 |
12967 /* If frame parameters are set after the frame is mapped, we need to move | 12967 /* If frame parameters are set after the frame is mapped, we need to move |
12981 | 12981 |
12982 if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT) | 12982 if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT) |
12983 expect_top = 0; | 12983 expect_top = 0; |
12984 if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH) | 12984 if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH) |
12985 expect_left = 0; | 12985 expect_left = 0; |
12986 | 12986 |
12987 if (expect_top != f->output_data.x->top_pos | 12987 if (expect_top != f->output_data.x->top_pos |
12988 || expect_left != f->output_data.x->left_pos) | 12988 || expect_left != f->output_data.x->left_pos) |
12989 x_set_offset (f, expect_left, expect_top, 1); | 12989 x_set_offset (f, expect_left, expect_top, 1); |
12990 | 12990 |
12991 /* Just do this once */ | 12991 /* Just do this once */ |
13009 { | 13009 { |
13010 int newwidth = f->width, newheight = f->height; | 13010 int newwidth = f->width, newheight = f->height; |
13011 | 13011 |
13012 *top_pos = f->output_data.x->top_pos; | 13012 *top_pos = f->output_data.x->top_pos; |
13013 *left_pos = f->output_data.x->left_pos; | 13013 *left_pos = f->output_data.x->left_pos; |
13014 | 13014 |
13015 if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT) | 13015 if (f->output_data.x->want_fullscreen & FULLSCREEN_HEIGHT) |
13016 { | 13016 { |
13017 int ph; | 13017 int ph; |
13018 | 13018 |
13019 ph = FRAME_X_DISPLAY_INFO (f)->height; | 13019 ph = FRAME_X_DISPLAY_INFO (f)->height; |
13020 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph); | 13020 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph); |
13021 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight) | 13021 ph = CHAR_TO_PIXEL_HEIGHT (f, newheight) |
13022 - f->output_data.x->y_pixels_diff; | 13022 - f->output_data.x->y_pixels_diff; |
13023 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph); | 13023 newheight = PIXEL_TO_CHAR_HEIGHT (f, ph); |
13025 } | 13025 } |
13026 | 13026 |
13027 if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH) | 13027 if (f->output_data.x->want_fullscreen & FULLSCREEN_WIDTH) |
13028 { | 13028 { |
13029 int pw; | 13029 int pw; |
13030 | 13030 |
13031 pw = FRAME_X_DISPLAY_INFO (f)->width; | 13031 pw = FRAME_X_DISPLAY_INFO (f)->width; |
13032 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw); | 13032 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw); |
13033 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth) | 13033 pw = CHAR_TO_PIXEL_WIDTH (f, newwidth) |
13034 - f->output_data.x->x_pixels_diff; | 13034 - f->output_data.x->x_pixels_diff; |
13035 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw); | 13035 newwidth = PIXEL_TO_CHAR_WIDTH (f, pw); |
13113 int cols, rows; | 13113 int cols, rows; |
13114 { | 13114 { |
13115 BLOCK_INPUT; | 13115 BLOCK_INPUT; |
13116 | 13116 |
13117 #ifdef USE_X_TOOLKIT | 13117 #ifdef USE_X_TOOLKIT |
13118 | 13118 |
13119 if (f->output_data.x->widget != NULL) | 13119 if (f->output_data.x->widget != NULL) |
13120 { | 13120 { |
13121 /* The x and y position of the widget is clobbered by the | 13121 /* The x and y position of the widget is clobbered by the |
13122 call to XtSetValues within EmacsFrameSetCharSize. | 13122 call to XtSetValues within EmacsFrameSetCharSize. |
13123 This is a real kludge, but I don't understand Xt so I can't | 13123 This is a real kludge, but I don't understand Xt so I can't |
13128 f->output_data.x->widget->core.x = xpos; | 13128 f->output_data.x->widget->core.x = xpos; |
13129 f->output_data.x->widget->core.y = ypos; | 13129 f->output_data.x->widget->core.y = ypos; |
13130 } | 13130 } |
13131 else | 13131 else |
13132 x_set_window_size_1 (f, change_gravity, cols, rows); | 13132 x_set_window_size_1 (f, change_gravity, cols, rows); |
13133 | 13133 |
13134 #else /* not USE_X_TOOLKIT */ | 13134 #else /* not USE_X_TOOLKIT */ |
13135 | 13135 |
13136 x_set_window_size_1 (f, change_gravity, cols, rows); | 13136 x_set_window_size_1 (f, change_gravity, cols, rows); |
13137 | 13137 |
13138 #endif /* not USE_X_TOOLKIT */ | 13138 #endif /* not USE_X_TOOLKIT */ |
13139 | 13139 |
13140 /* If cursor was outside the new size, mark it as off. */ | 13140 /* If cursor was outside the new size, mark it as off. */ |
13141 mark_window_cursors_off (XWINDOW (f->root_window)); | 13141 mark_window_cursors_off (XWINDOW (f->root_window)); |
13142 | 13142 |
13143 /* Clear out any recollection of where the mouse highlighting was, | 13143 /* Clear out any recollection of where the mouse highlighting was, |
13144 since it might be in a place that's outside the new frame size. | 13144 since it might be in a place that's outside the new frame size. |
13145 Actually checking whether it is outside is a pain in the neck, | 13145 Actually checking whether it is outside is a pain in the neck, |
13146 so don't try--just let the highlighting be done afresh with new size. */ | 13146 so don't try--just let the highlighting be done afresh with new size. */ |
13147 cancel_mouse_face (f); | 13147 cancel_mouse_face (f); |
13148 | 13148 |
13149 UNBLOCK_INPUT; | 13149 UNBLOCK_INPUT; |
13355 && previously_visible) | 13355 && previously_visible) |
13356 { | 13356 { |
13357 Drawable rootw; | 13357 Drawable rootw; |
13358 int x, y; | 13358 int x, y; |
13359 unsigned int width, height, border, depth; | 13359 unsigned int width, height, border, depth; |
13360 | 13360 |
13361 BLOCK_INPUT; | 13361 BLOCK_INPUT; |
13362 | 13362 |
13363 /* On some window managers (such as FVWM) moving an existing | 13363 /* On some window managers (such as FVWM) moving an existing |
13364 window, even to the same place, causes the window manager | 13364 window, even to the same place, causes the window manager |
13365 to introduce an offset. This can cause the window to move | 13365 to introduce an offset. This can cause the window to move |
13418 | 13418 |
13419 the frame is not raised with various window managers on | 13419 the frame is not raised with various window managers on |
13420 FreeBSD, Linux and Solaris. It turns out that, for some | 13420 FreeBSD, Linux and Solaris. It turns out that, for some |
13421 unknown reason, the call to XtMapWidget is completely ignored. | 13421 unknown reason, the call to XtMapWidget is completely ignored. |
13422 Mapping the widget a second time works. */ | 13422 Mapping the widget a second time works. */ |
13423 | 13423 |
13424 if (!FRAME_VISIBLE_P (f) && --retry_count > 0) | 13424 if (!FRAME_VISIBLE_P (f) && --retry_count > 0) |
13425 goto retry; | 13425 goto retry; |
13426 } | 13426 } |
13427 } | 13427 } |
13428 | 13428 |
13695 if (f->output_data.x->black_relief.allocated_p) | 13695 if (f->output_data.x->black_relief.allocated_p) |
13696 unload_color (f, f->output_data.x->black_relief.pixel); | 13696 unload_color (f, f->output_data.x->black_relief.pixel); |
13697 | 13697 |
13698 if (FRAME_FACE_CACHE (f)) | 13698 if (FRAME_FACE_CACHE (f)) |
13699 free_frame_faces (f); | 13699 free_frame_faces (f); |
13700 | 13700 |
13701 x_free_gcs (f); | 13701 x_free_gcs (f); |
13702 XFlush (FRAME_X_DISPLAY (f)); | 13702 XFlush (FRAME_X_DISPLAY (f)); |
13703 } | 13703 } |
13704 | 13704 |
13705 if (f->output_data.x->saved_menu_event) | 13705 if (f->output_data.x->saved_menu_event) |
13706 xfree (f->output_data.x->saved_menu_event); | 13706 xfree (f->output_data.x->saved_menu_event); |
13707 | 13707 |
13708 xfree (f->output_data.x); | 13708 xfree (f->output_data.x); |
13709 f->output_data.x = NULL; | 13709 f->output_data.x = NULL; |
13710 | 13710 |
13711 if (f == dpyinfo->x_focus_frame) | 13711 if (f == dpyinfo->x_focus_frame) |
13712 dpyinfo->x_focus_frame = 0; | 13712 dpyinfo->x_focus_frame = 0; |
13713 if (f == dpyinfo->x_focus_event_frame) | 13713 if (f == dpyinfo->x_focus_event_frame) |
13714 dpyinfo->x_focus_event_frame = 0; | 13714 dpyinfo->x_focus_event_frame = 0; |
13715 if (f == dpyinfo->x_highlight_frame) | 13715 if (f == dpyinfo->x_highlight_frame) |
13959 XtSetArg (al[0], XtNiconPixmap, icon_pixmap); | 13959 XtSetArg (al[0], XtNiconPixmap, icon_pixmap); |
13960 XtSetValues (f->output_data.x->widget, al, 1); | 13960 XtSetValues (f->output_data.x->widget, al, 1); |
13961 } | 13961 } |
13962 | 13962 |
13963 #else /* not USE_X_TOOLKIT */ | 13963 #else /* not USE_X_TOOLKIT */ |
13964 | 13964 |
13965 f->output_data.x->wm_hints.flags |= IconPixmapHint; | 13965 f->output_data.x->wm_hints.flags |= IconPixmapHint; |
13966 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints); | 13966 XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints); |
13967 | 13967 |
13968 #endif /* not USE_X_TOOLKIT */ | 13968 #endif /* not USE_X_TOOLKIT */ |
13969 } | 13969 } |
14139 for (i = 0; i < num_fonts; i++) | 14139 for (i = 0; i < num_fonts; i++) |
14140 { | 14140 { |
14141 int width = 0; | 14141 int width = 0; |
14142 char *p = names[i]; | 14142 char *p = names[i]; |
14143 int average_width = -1, dashes = 0; | 14143 int average_width = -1, dashes = 0; |
14144 | 14144 |
14145 /* Count the number of dashes in NAMES[I]. If there are | 14145 /* Count the number of dashes in NAMES[I]. If there are |
14146 14 dashes, and the field value following 12th dash | 14146 14 dashes, and the field value following 12th dash |
14147 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which | 14147 (AVERAGE_WIDTH) is 0, this is a auto-scaled font which |
14148 is usually too ugly to be used for editing. Let's | 14148 is usually too ugly to be used for editing. Let's |
14149 ignore it. */ | 14149 ignore it. */ |
14154 if (dashes == 7) /* PIXEL_SIZE field */ | 14154 if (dashes == 7) /* PIXEL_SIZE field */ |
14155 width = atoi (p); | 14155 width = atoi (p); |
14156 else if (dashes == 12) /* AVERAGE_WIDTH field */ | 14156 else if (dashes == 12) /* AVERAGE_WIDTH field */ |
14157 average_width = atoi (p); | 14157 average_width = atoi (p); |
14158 } | 14158 } |
14159 | 14159 |
14160 if (allow_scalable_fonts_p | 14160 if (allow_scalable_fonts_p |
14161 || dashes < 14 || average_width != 0) | 14161 || dashes < 14 || average_width != 0) |
14162 { | 14162 { |
14163 tem = build_string (names[i]); | 14163 tem = build_string (names[i]); |
14164 if (NILP (Fassoc (tem, list))) | 14164 if (NILP (Fassoc (tem, list))) |
14174 /* For the moment, width is not known. */ | 14174 /* For the moment, width is not known. */ |
14175 list = Fcons (Fcons (tem, Qnil), list); | 14175 list = Fcons (Fcons (tem, Qnil), list); |
14176 } | 14176 } |
14177 } | 14177 } |
14178 } | 14178 } |
14179 | 14179 |
14180 if (!try_XLoadQueryFont) | 14180 if (!try_XLoadQueryFont) |
14181 { | 14181 { |
14182 BLOCK_INPUT; | 14182 BLOCK_INPUT; |
14183 XFreeFontNames (names); | 14183 XFreeFontNames (names); |
14184 UNBLOCK_INPUT; | 14184 UNBLOCK_INPUT; |
14274 break; | 14274 break; |
14275 } | 14275 } |
14276 } | 14276 } |
14277 | 14277 |
14278 return newlist; | 14278 return newlist; |
14279 } | 14279 } |
14280 | 14280 |
14281 | 14281 |
14282 #if GLYPH_DEBUG | 14282 #if GLYPH_DEBUG |
14283 | 14283 |
14284 /* Check that FONT is valid on frame F. It is if it can be found in F's | 14284 /* Check that FONT is valid on frame F. It is if it can be found in F's |
14293 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 14293 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
14294 | 14294 |
14295 xassert (font != NULL); | 14295 xassert (font != NULL); |
14296 | 14296 |
14297 for (i = 0; i < dpyinfo->n_fonts; i++) | 14297 for (i = 0; i < dpyinfo->n_fonts; i++) |
14298 if (dpyinfo->font_table[i].name | 14298 if (dpyinfo->font_table[i].name |
14299 && font == dpyinfo->font_table[i].font) | 14299 && font == dpyinfo->font_table[i].font) |
14300 break; | 14300 break; |
14301 | 14301 |
14302 xassert (i < dpyinfo->n_fonts); | 14302 xassert (i < dpyinfo->n_fonts); |
14303 } | 14303 } |
14339 int i; | 14339 int i; |
14340 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | 14340 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); |
14341 XFontStruct *font; | 14341 XFontStruct *font; |
14342 int old_width = dpyinfo->smallest_char_width; | 14342 int old_width = dpyinfo->smallest_char_width; |
14343 int old_height = dpyinfo->smallest_font_height; | 14343 int old_height = dpyinfo->smallest_font_height; |
14344 | 14344 |
14345 dpyinfo->smallest_font_height = 100000; | 14345 dpyinfo->smallest_font_height = 100000; |
14346 dpyinfo->smallest_char_width = 100000; | 14346 dpyinfo->smallest_char_width = 100000; |
14347 | 14347 |
14348 for (i = 0; i < dpyinfo->n_fonts; ++i) | 14348 for (i = 0; i < dpyinfo->n_fonts; ++i) |
14349 if (dpyinfo->font_table[i].name) | 14349 if (dpyinfo->font_table[i].name) |
14350 { | 14350 { |
14351 struct font_info *fontp = dpyinfo->font_table + i; | 14351 struct font_info *fontp = dpyinfo->font_table + i; |
14352 int w, h; | 14352 int w, h; |
14353 | 14353 |
14354 font = (XFontStruct *) fontp->font; | 14354 font = (XFontStruct *) fontp->font; |
14355 xassert (font != (XFontStruct *) ~0); | 14355 xassert (font != (XFontStruct *) ~0); |
14356 x_font_min_bounds (font, &w, &h); | 14356 x_font_min_bounds (font, &w, &h); |
14357 | 14357 |
14358 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h); | 14358 dpyinfo->smallest_font_height = min (dpyinfo->smallest_font_height, h); |
14359 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w); | 14359 dpyinfo->smallest_char_width = min (dpyinfo->smallest_char_width, w); |
14360 } | 14360 } |
14361 | 14361 |
14362 xassert (dpyinfo->smallest_char_width > 0 | 14362 xassert (dpyinfo->smallest_char_width > 0 |
14487 bcopy (name, full_name, p - name + 1); | 14487 bcopy (name, full_name, p - name + 1); |
14488 } | 14488 } |
14489 | 14489 |
14490 XFree (name); | 14490 XFree (name); |
14491 } | 14491 } |
14492 | 14492 |
14493 if (full_name != 0) | 14493 if (full_name != 0) |
14494 fontp->full_name = full_name; | 14494 fontp->full_name = full_name; |
14495 else | 14495 else |
14496 fontp->full_name = fontp->name; | 14496 fontp->full_name = fontp->name; |
14497 | 14497 |
14619 >= 0) | 14619 >= 0) |
14620 || (fast_c_string_match_ignore_case (XCAR (elt), fontp->full_name) | 14620 || (fast_c_string_match_ignore_case (XCAR (elt), fontp->full_name) |
14621 >= 0))) | 14621 >= 0))) |
14622 break; | 14622 break; |
14623 } | 14623 } |
14624 | 14624 |
14625 if (! NILP (list)) | 14625 if (! NILP (list)) |
14626 { | 14626 { |
14627 struct ccl_program *ccl | 14627 struct ccl_program *ccl |
14628 = (struct ccl_program *) xmalloc (sizeof (struct ccl_program)); | 14628 = (struct ccl_program *) xmalloc (sizeof (struct ccl_program)); |
14629 | 14629 |
14822 | 14822 |
14823 /* Put this display on the chain. */ | 14823 /* Put this display on the chain. */ |
14824 dpyinfo->next = x_display_list; | 14824 dpyinfo->next = x_display_list; |
14825 x_display_list = dpyinfo; | 14825 x_display_list = dpyinfo; |
14826 | 14826 |
14827 /* Put it on x_display_name_list as well, to keep them parallel. */ | 14827 /* Put it on x_display_name_list as well, to keep them parallel. */ |
14828 x_display_name_list = Fcons (Fcons (display_name, Qnil), | 14828 x_display_name_list = Fcons (Fcons (display_name, Qnil), |
14829 x_display_name_list); | 14829 x_display_name_list); |
14830 dpyinfo->name_list_element = XCAR (x_display_name_list); | 14830 dpyinfo->name_list_element = XCAR (x_display_name_list); |
14831 | 14831 |
14832 dpyinfo->display = dpy; | 14832 dpyinfo->display = dpy; |
14909 } | 14909 } |
14910 } | 14910 } |
14911 else | 14911 else |
14912 dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window, | 14912 dpyinfo->cmap = XCreateColormap (dpyinfo->display, dpyinfo->root_window, |
14913 dpyinfo->visual, AllocNone); | 14913 dpyinfo->visual, AllocNone); |
14914 | 14914 |
14915 { | 14915 { |
14916 int screen_number = XScreenNumberOfScreen (dpyinfo->screen); | 14916 int screen_number = XScreenNumberOfScreen (dpyinfo->screen); |
14917 double pixels = DisplayHeight (dpyinfo->display, screen_number); | 14917 double pixels = DisplayHeight (dpyinfo->display, screen_number); |
14918 double mm = DisplayHeightMM (dpyinfo->display, screen_number); | 14918 double mm = DisplayHeightMM (dpyinfo->display, screen_number); |
14919 dpyinfo->resy = pixels * 25.4 / mm; | 14919 dpyinfo->resy = pixels * 25.4 / mm; |
14920 pixels = DisplayWidth (dpyinfo->display, screen_number); | 14920 pixels = DisplayWidth (dpyinfo->display, screen_number); |
14921 mm = DisplayWidthMM (dpyinfo->display, screen_number); | 14921 mm = DisplayWidthMM (dpyinfo->display, screen_number); |
14922 dpyinfo->resx = pixels * 25.4 / mm; | 14922 dpyinfo->resx = pixels * 25.4 / mm; |
14923 } | 14923 } |
14924 | 14924 |
14925 dpyinfo->Xatom_wm_protocols | 14925 dpyinfo->Xatom_wm_protocols |
14926 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False); | 14926 = XInternAtom (dpyinfo->display, "WM_PROTOCOLS", False); |
14927 dpyinfo->Xatom_wm_take_focus | 14927 dpyinfo->Xatom_wm_take_focus |
14928 = XInternAtom (dpyinfo->display, "WM_TAKE_FOCUS", False); | 14928 = XInternAtom (dpyinfo->display, "WM_TAKE_FOCUS", False); |
14929 dpyinfo->Xatom_wm_save_yourself | 14929 dpyinfo->Xatom_wm_save_yourself |
14973 = XInternAtom (dpyinfo->display, "_MULE_DEFAULT_ASCENT", False); | 14973 = XInternAtom (dpyinfo->display, "_MULE_DEFAULT_ASCENT", False); |
14974 | 14974 |
14975 /* Ghostscript support. */ | 14975 /* Ghostscript support. */ |
14976 dpyinfo->Xatom_PAGE = XInternAtom (dpyinfo->display, "PAGE", False); | 14976 dpyinfo->Xatom_PAGE = XInternAtom (dpyinfo->display, "PAGE", False); |
14977 dpyinfo->Xatom_DONE = XInternAtom (dpyinfo->display, "DONE", False); | 14977 dpyinfo->Xatom_DONE = XInternAtom (dpyinfo->display, "DONE", False); |
14978 | 14978 |
14979 dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR", | 14979 dpyinfo->Xatom_Scrollbar = XInternAtom (dpyinfo->display, "SCROLLBAR", |
14980 False); | 14980 False); |
14981 | 14981 |
14982 dpyinfo->cut_buffers_initialized = 0; | 14982 dpyinfo->cut_buffers_initialized = 0; |
14983 | 14983 |
14988 char null_bits[1]; | 14988 char null_bits[1]; |
14989 | 14989 |
14990 null_bits[0] = 0x00; | 14990 null_bits[0] = 0x00; |
14991 | 14991 |
14992 dpyinfo->null_pixel | 14992 dpyinfo->null_pixel |
14993 = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window, | 14993 = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window, |
14994 null_bits, 1, 1, (long) 0, (long) 0, | 14994 null_bits, 1, 1, (long) 0, (long) 0, |
14995 1); | 14995 1); |
14996 } | 14996 } |
14997 | 14997 |
14998 { | 14998 { |
15006 } | 15006 } |
15007 | 15007 |
15008 #ifdef HAVE_X_I18N | 15008 #ifdef HAVE_X_I18N |
15009 xim_initialize (dpyinfo, resource_name); | 15009 xim_initialize (dpyinfo, resource_name); |
15010 #endif | 15010 #endif |
15011 | 15011 |
15012 #ifdef subprocesses | 15012 #ifdef subprocesses |
15013 /* This is only needed for distinguishing keyboard and process input. */ | 15013 /* This is only needed for distinguishing keyboard and process input. */ |
15014 if (connection != 0) | 15014 if (connection != 0) |
15015 add_keyboard_wait_descriptor (connection); | 15015 add_keyboard_wait_descriptor (connection); |
15016 #endif | 15016 #endif |
15038 { | 15038 { |
15039 Display *dpy = dpyinfo->display; | 15039 Display *dpy = dpyinfo->display; |
15040 XrmValue d, fr, to; | 15040 XrmValue d, fr, to; |
15041 Font font; | 15041 Font font; |
15042 int count; | 15042 int count; |
15043 | 15043 |
15044 d.addr = (XPointer)&dpy; | 15044 d.addr = (XPointer)&dpy; |
15045 d.size = sizeof (Display *); | 15045 d.size = sizeof (Display *); |
15046 fr.addr = XtDefaultFont; | 15046 fr.addr = XtDefaultFont; |
15047 fr.size = sizeof (XtDefaultFont); | 15047 fr.size = sizeof (XtDefaultFont); |
15048 to.size = sizeof (Font *); | 15048 to.size = sizeof (Font *); |
15068 if (STRINGP (value) | 15068 if (STRINGP (value) |
15069 && (!strcmp (SDATA (value), "true") | 15069 && (!strcmp (SDATA (value), "true") |
15070 || !strcmp (SDATA (value), "on"))) | 15070 || !strcmp (SDATA (value), "on"))) |
15071 XSynchronize (dpyinfo->display, True); | 15071 XSynchronize (dpyinfo->display, True); |
15072 } | 15072 } |
15073 | 15073 |
15074 UNBLOCK_INPUT; | 15074 UNBLOCK_INPUT; |
15075 | 15075 |
15076 return dpyinfo; | 15076 return dpyinfo; |
15077 } | 15077 } |
15078 | 15078 |
15131 #endif | 15131 #endif |
15132 #ifdef HAVE_X_I18N | 15132 #ifdef HAVE_X_I18N |
15133 if (dpyinfo->xim) | 15133 if (dpyinfo->xim) |
15134 xim_close_dpy (dpyinfo); | 15134 xim_close_dpy (dpyinfo); |
15135 #endif | 15135 #endif |
15136 | 15136 |
15137 xfree (dpyinfo->font_table); | 15137 xfree (dpyinfo->font_table); |
15138 xfree (dpyinfo->x_id_name); | 15138 xfree (dpyinfo->x_id_name); |
15139 xfree (dpyinfo->color_cells); | 15139 xfree (dpyinfo->color_cells); |
15140 xfree (dpyinfo); | 15140 xfree (dpyinfo); |
15141 } | 15141 } |
15194 baud_rate = 19200; | 15194 baud_rate = 19200; |
15195 | 15195 |
15196 x_noop_count = 0; | 15196 x_noop_count = 0; |
15197 last_tool_bar_item = -1; | 15197 last_tool_bar_item = -1; |
15198 any_help_event_p = 0; | 15198 any_help_event_p = 0; |
15199 | 15199 |
15200 /* Try to use interrupt input; if we can't, then start polling. */ | 15200 /* Try to use interrupt input; if we can't, then start polling. */ |
15201 Fset_input_mode (Qt, Qnil, Qt, Qnil); | 15201 Fset_input_mode (Qt, Qnil, Qt, Qnil); |
15202 | 15202 |
15203 #ifdef USE_X_TOOLKIT | 15203 #ifdef USE_X_TOOLKIT |
15204 XtToolkitInitialize (); | 15204 XtToolkitInitialize (); |
15205 | 15205 |
15206 Xt_app_con = XtCreateApplicationContext (); | 15206 Xt_app_con = XtCreateApplicationContext (); |
15207 | 15207 |
15208 /* Register a converter from strings to pixels, which uses | 15208 /* Register a converter from strings to pixels, which uses |
15209 Emacs' color allocation infrastructure. */ | 15209 Emacs' color allocation infrastructure. */ |
15210 XtAppSetTypeConverter (Xt_app_con, | 15210 XtAppSetTypeConverter (Xt_app_con, |
15211 XtRString, XtRPixel, cvt_string_to_pixel, | 15211 XtRString, XtRPixel, cvt_string_to_pixel, |
15212 cvt_string_to_pixel_args, | 15212 cvt_string_to_pixel_args, |
15224 EMACS_TIME interval; | 15224 EMACS_TIME interval; |
15225 EMACS_SET_SECS_USECS (interval, 0, 100000); | 15225 EMACS_SET_SECS_USECS (interval, 0, 100000); |
15226 start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts, 0); | 15226 start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts, 0); |
15227 } | 15227 } |
15228 #endif | 15228 #endif |
15229 | 15229 |
15230 #ifdef USE_TOOLKIT_SCROLL_BARS | 15230 #ifdef USE_TOOLKIT_SCROLL_BARS |
15231 xaw3d_arrow_scroll = False; | 15231 xaw3d_arrow_scroll = False; |
15232 xaw3d_pick_top = True; | 15232 xaw3d_pick_top = True; |
15233 #endif | 15233 #endif |
15234 | 15234 |
15317 Vx_toolkit_scroll_bars = Qnil; | 15317 Vx_toolkit_scroll_bars = Qnil; |
15318 #endif | 15318 #endif |
15319 | 15319 |
15320 staticpro (&last_mouse_motion_frame); | 15320 staticpro (&last_mouse_motion_frame); |
15321 last_mouse_motion_frame = Qnil; | 15321 last_mouse_motion_frame = Qnil; |
15322 | 15322 |
15323 Qmodifier_value = intern ("modifier-value"); | 15323 Qmodifier_value = intern ("modifier-value"); |
15324 Qalt = intern ("alt"); | 15324 Qalt = intern ("alt"); |
15325 Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); | 15325 Fput (Qalt, Qmodifier_value, make_number (alt_modifier)); |
15326 Qhyper = intern ("hyper"); | 15326 Qhyper = intern ("hyper"); |
15327 Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); | 15327 Fput (Qhyper, Qmodifier_value, make_number (hyper_modifier)); |
15328 Qmeta = intern ("meta"); | 15328 Qmeta = intern ("meta"); |
15329 Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); | 15329 Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); |
15330 Qsuper = intern ("super"); | 15330 Qsuper = intern ("super"); |
15331 Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); | 15331 Fput (Qsuper, Qmodifier_value, make_number (super_modifier)); |
15332 | 15332 |
15333 DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym, | 15333 DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym, |
15334 doc: /* Which keys Emacs uses for the alt modifier. | 15334 doc: /* Which keys Emacs uses for the alt modifier. |
15335 This should be one of the symbols `alt', `hyper', `meta', `super'. | 15335 This should be one of the symbols `alt', `hyper', `meta', `super'. |
15336 For example, `alt' means use the Alt_L and Alt_R keysyms. The default | 15336 For example, `alt' means use the Alt_L and Alt_R keysyms. The default |
15337 is nil, which is the same as `alt'. */); | 15337 is nil, which is the same as `alt'. */); |
15338 Vx_alt_keysym = Qnil; | 15338 Vx_alt_keysym = Qnil; |
15339 | 15339 |
15340 DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym, | 15340 DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym, |
15341 doc: /* Which keys Emacs uses for the hyper modifier. | 15341 doc: /* Which keys Emacs uses for the hyper modifier. |
15342 This should be one of the symbols `alt', `hyper', `meta', `super'. | 15342 This should be one of the symbols `alt', `hyper', `meta', `super'. |
15343 For example, `hyper' means use the Hyper_L and Hyper_R keysyms. The | 15343 For example, `hyper' means use the Hyper_L and Hyper_R keysyms. The |
15344 default is nil, which is the same as `hyper'. */); | 15344 default is nil, which is the same as `hyper'. */); |
15345 Vx_hyper_keysym = Qnil; | 15345 Vx_hyper_keysym = Qnil; |
15346 | 15346 |
15347 DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym, | 15347 DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym, |
15348 doc: /* Which keys Emacs uses for the meta modifier. | 15348 doc: /* Which keys Emacs uses for the meta modifier. |
15349 This should be one of the symbols `alt', `hyper', `meta', `super'. | 15349 This should be one of the symbols `alt', `hyper', `meta', `super'. |
15350 For example, `meta' means use the Meta_L and Meta_R keysyms. The | 15350 For example, `meta' means use the Meta_L and Meta_R keysyms. The |
15351 default is nil, which is the same as `meta'. */); | 15351 default is nil, which is the same as `meta'. */); |
15352 Vx_meta_keysym = Qnil; | 15352 Vx_meta_keysym = Qnil; |
15353 | 15353 |
15354 DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym, | 15354 DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym, |
15355 doc: /* Which keys Emacs uses for the super modifier. | 15355 doc: /* Which keys Emacs uses for the super modifier. |
15356 This should be one of the symbols `alt', `hyper', `meta', `super'. | 15356 This should be one of the symbols `alt', `hyper', `meta', `super'. |
15357 For example, `super' means use the Super_L and Super_R keysyms. The | 15357 For example, `super' means use the Super_L and Super_R keysyms. The |
15358 default is nil, which is the same as `super'. */); | 15358 default is nil, which is the same as `super'. */); |