Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 95016f13131a |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
52 #include "mule-ccl.h" | 52 #include "mule-ccl.h" |
53 #include "file-coding.h" /* for CCL conversion */ | 53 #include "file-coding.h" /* for CCL conversion */ |
54 #endif | 54 #endif |
55 | 55 |
56 /* Number of pixels below each line. */ | 56 /* Number of pixels below each line. */ |
57 /* #### implement me */ | 57 int x_interline_space; /* #### implement me */ |
58 int x_interline_space; | |
59 | 58 |
60 #define EOL_CURSOR_WIDTH 5 | 59 #define EOL_CURSOR_WIDTH 5 |
61 | 60 |
62 static void x_output_pixmap (struct window *w, struct display_line *dl, | |
63 Lisp_Object image_instance, int xpos, | |
64 int xoffset, | |
65 int start_pixpos, int width, face_index findex, | |
66 int cursor_start, int cursor_width, | |
67 int cursor_height); | |
68 static void x_output_vertical_divider (struct window *w, int clear); | 61 static void x_output_vertical_divider (struct window *w, int clear); |
69 static void x_output_blank (struct window *w, struct display_line *dl, | 62 static void x_output_blank (struct window *w, struct display_line *dl, |
70 struct rune *rb, int start_pixpos, | 63 struct rune *rb, int start_pixpos, |
71 int cursor_start, int cursor_width); | 64 int cursor_start, int cursor_width); |
72 static void x_output_hline (struct window *w, struct display_line *dl, | 65 static void x_output_hline (struct window *w, struct display_line *dl, |
77 int width, int height); | 70 int width, int height); |
78 static void x_output_eol_cursor (struct window *w, struct display_line *dl, | 71 static void x_output_eol_cursor (struct window *w, struct display_line *dl, |
79 int xpos, face_index findex); | 72 int xpos, face_index findex); |
80 static void x_clear_frame (struct frame *f); | 73 static void x_clear_frame (struct frame *f); |
81 static void x_clear_frame_windows (Lisp_Object window); | 74 static void x_clear_frame_windows (Lisp_Object window); |
82 void bevel_modeline (struct window *w, struct display_line *dl); | |
83 | 75 |
84 | 76 |
85 /* Note: We do not use the Xmb*() functions and XFontSets. | 77 /* Note: We do not use the Xmb*() functions and XFontSets. |
86 Those functions are generally losing for a number of reasons: | 78 Those functions are generally losing for a number of reasons: |
87 | 79 |
406 elt++; | 398 elt++; |
407 } | 399 } |
408 else if (rb->object.chr.ch == '\n') | 400 else if (rb->object.chr.ch == '\n') |
409 { | 401 { |
410 /* Clear in case a cursor was formerly here. */ | 402 /* Clear in case a cursor was formerly here. */ |
411 int height = dl->ascent + dl->descent - dl->clip; | 403 redisplay_clear_region (window, findex, xpos, |
412 | 404 DISPLAY_LINE_YPOS (dl), |
413 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, | 405 rb->width, |
414 rb->width, height); | 406 DISPLAY_LINE_HEIGHT (dl)); |
415 elt++; | 407 elt++; |
416 } | 408 } |
417 } | 409 } |
418 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | 410 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) |
419 { | 411 { |
443 } | 435 } |
444 } | 436 } |
445 else if (rb->type == RUNE_DGLYPH) | 437 else if (rb->type == RUNE_DGLYPH) |
446 { | 438 { |
447 Lisp_Object instance; | 439 Lisp_Object instance; |
440 struct display_box dbox; | |
441 struct display_glyph_area dga; | |
442 redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset, | |
443 start_pixpos, rb->width, | |
444 &dbox, &dga); | |
448 | 445 |
449 XSETWINDOW (window, w); | 446 XSETWINDOW (window, w); |
450 instance = glyph_image_instance (rb->object.dglyph.glyph, | 447 instance = glyph_image_instance (rb->object.dglyph.glyph, |
451 window, ERROR_ME_NOT, 1); | 448 window, ERROR_ME_NOT, 1); |
452 findex = rb->findex; | 449 findex = rb->findex; |
473 } | 470 } |
474 break; | 471 break; |
475 | 472 |
476 case IMAGE_MONO_PIXMAP: | 473 case IMAGE_MONO_PIXMAP: |
477 case IMAGE_COLOR_PIXMAP: | 474 case IMAGE_COLOR_PIXMAP: |
478 x_output_pixmap (w, dl, instance, xpos, | 475 redisplay_output_pixmap (w, instance, &dbox, &dga, findex, |
479 rb->object.dglyph.xoffset, start_pixpos, | 476 cursor_start, cursor_width, |
480 rb->width, findex, cursor_start, | 477 cursor_height, 0); |
481 cursor_width, cursor_height); | |
482 break; | 478 break; |
483 | |
484 case IMAGE_POINTER: | |
485 abort (); | |
486 | 479 |
487 case IMAGE_WIDGET: | 480 case IMAGE_WIDGET: |
488 case IMAGE_SUBWINDOW: | 481 case IMAGE_SUBWINDOW: |
489 redisplay_output_subwindow (w, dl, instance, xpos, | 482 redisplay_output_subwindow (w, instance, &dbox, &dga, findex, |
490 rb->object.dglyph.xoffset, start_pixpos, | 483 cursor_start, cursor_width, |
491 rb->width, findex, cursor_start, | 484 cursor_height); |
492 cursor_width, cursor_height); | 485 break; |
486 | |
487 case IMAGE_LAYOUT: | |
488 redisplay_output_layout (w, instance, &dbox, &dga, findex, | |
489 cursor_start, cursor_width, | |
490 cursor_height); | |
491 break; | |
493 | 492 |
494 case IMAGE_NOTHING: | 493 case IMAGE_NOTHING: |
495 /* nothing is as nothing does */ | 494 /* nothing is as nothing does */ |
496 break; | 495 break; |
497 | 496 |
497 case IMAGE_POINTER: | |
498 default: | 498 default: |
499 abort (); | 499 abort (); |
500 } | 500 } |
501 | 501 |
502 xpos += rb->width; | 502 xpos += rb->width; |
529 Draw a shadows for the given area in the given face. | 529 Draw a shadows for the given area in the given face. |
530 ****************************************************************************/ | 530 ****************************************************************************/ |
531 static void | 531 static void |
532 x_bevel_area (struct window *w, face_index findex, | 532 x_bevel_area (struct window *w, face_index findex, |
533 int x, int y, int width, int height, | 533 int x, int y, int width, int height, |
534 int shadow_thickness) | 534 int shadow_thickness, int edges, enum edge_style style) |
535 { | 535 { |
536 struct frame *f = XFRAME (w->frame); | 536 struct frame *f = XFRAME (w->frame); |
537 struct device *d = XDEVICE (f->device); | 537 struct device *d = XDEVICE (f->device); |
538 | 538 |
539 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | 539 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); |
547 | 547 |
548 int use_pixmap = 0; | 548 int use_pixmap = 0; |
549 int flip_gcs = 0; | 549 int flip_gcs = 0; |
550 unsigned long mask; | 550 unsigned long mask; |
551 | 551 |
552 assert (shadow_thickness >=0); | |
552 memset (&gcv, ~0, sizeof (XGCValues)); | 553 memset (&gcv, ~0, sizeof (XGCValues)); |
553 | 554 |
554 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 555 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); |
555 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 556 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
556 | 557 |
616 } | 617 } |
617 | 618 |
618 gcv.foreground = background_pixel; | 619 gcv.foreground = background_pixel; |
619 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | 620 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
620 | 621 |
621 /* possibly revert the GC's in case the shadow thickness is < 0. | 622 /* possibly revert the GC's This will give a depressed look to the |
622 This will give a depressed look to the divider */ | 623 divider */ |
623 if (shadow_thickness < 0) | 624 if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN) |
624 { | 625 { |
625 GC temp; | 626 GC temp; |
626 | 627 |
627 temp = top_shadow_gc; | 628 temp = top_shadow_gc; |
628 top_shadow_gc = bottom_shadow_gc; | 629 top_shadow_gc = bottom_shadow_gc; |
629 bottom_shadow_gc = temp; | 630 bottom_shadow_gc = temp; |
630 | 631 } |
631 /* better avoid a Bad Address XLib error ;-) */ | 632 |
632 shadow_thickness = - shadow_thickness; | 633 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) |
633 } | 634 shadow_thickness /= 2; |
634 | 635 |
635 /* Draw the shadows around the divider line */ | 636 /* Draw the shadows around the divider line */ |
636 x_output_shadows (f, x, y, width, height, | 637 x_output_shadows (f, x, y, width, height, |
637 top_shadow_gc, bottom_shadow_gc, | 638 top_shadow_gc, bottom_shadow_gc, |
638 background_gc, shadow_thickness); | 639 background_gc, shadow_thickness, edges); |
640 | |
641 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) | |
642 { | |
643 /* Draw the shadows around the divider line */ | |
644 x_output_shadows (f, x + shadow_thickness, y + shadow_thickness, | |
645 width - 2*shadow_thickness, height - 2*shadow_thickness, | |
646 bottom_shadow_gc, top_shadow_gc, | |
647 background_gc, shadow_thickness, edges); | |
648 } | |
639 } | 649 } |
640 | 650 |
641 /***************************************************************************** | 651 /***************************************************************************** |
642 x_get_gc | 652 x_get_gc |
643 | 653 |
801 XSETDEVICE (device, d); | 811 XSETDEVICE (device, d); |
802 XSETWINDOW (window, w); | 812 XSETWINDOW (window, w); |
803 | 813 |
804 if (width < 0) | 814 if (width < 0) |
805 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); | 815 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); |
806 height = dl->ascent + dl->descent - dl->clip; | 816 height = DISPLAY_LINE_HEIGHT (dl); |
807 | 817 |
808 /* Regularize the variables passed in. */ | 818 /* Regularize the variables passed in. */ |
809 | 819 |
810 if (clip_start < xpos) | 820 if (clip_start < xpos) |
811 clip_start = xpos; | 821 clip_start = xpos; |
813 if (clip_start >= clip_end) | 823 if (clip_start >= clip_end) |
814 /* It's all clipped out. */ | 824 /* It's all clipped out. */ |
815 return; | 825 return; |
816 | 826 |
817 xpos -= xoffset; | 827 xpos -= xoffset; |
828 | |
829 /* make sure the area we are about to display is subwindow free. */ | |
830 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
831 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
818 | 832 |
819 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), | 833 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), |
820 Dynarr_length (buf)); | 834 Dynarr_length (buf)); |
821 | 835 |
822 cursor_clip = (cursor_start >= clip_start && | 836 cursor_clip = (cursor_start >= clip_start && |
858 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, | 872 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, |
859 bg_pmap, Qnil); | 873 bg_pmap, Qnil); |
860 | 874 |
861 if (bgc) | 875 if (bgc) |
862 XFillRectangle (dpy, x_win, bgc, clip_start, | 876 XFillRectangle (dpy, x_win, bgc, clip_start, |
863 dl->ypos - dl->ascent, clip_end - clip_start, | 877 DISPLAY_LINE_YPOS (dl), clip_end - clip_start, |
864 height); | 878 height); |
865 | 879 |
866 for (i = 0; i < nruns; i++) | 880 for (i = 0; i < nruns; i++) |
867 { | 881 { |
868 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | 882 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); |
879 | 893 |
880 /* XDrawImageString only clears the area equal to the height of | 894 /* XDrawImageString only clears the area equal to the height of |
881 the given font. It is possible that a font is being displayed | 895 the given font. It is possible that a font is being displayed |
882 on a line taller than it is, so this would cause us to fail to | 896 on a line taller than it is, so this would cause us to fail to |
883 clear some areas. */ | 897 clear some areas. */ |
884 if ((int) fi->height < (int) (height + dl->clip)) | 898 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) |
885 { | 899 { |
886 int clear_start = max (xpos, clip_start); | 900 int clear_start = max (xpos, clip_start); |
887 int clear_end = min (xpos + this_width, clip_end); | 901 int clear_end = min (xpos + this_width, clip_end); |
888 | 902 |
889 if (cursor) | 903 if (cursor) |
890 { | 904 { |
891 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; | 905 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; |
892 | 906 |
893 ypos1_string = dl->ypos - fi->ascent; | 907 ypos1_string = dl->ypos - fi->ascent; |
894 ypos2_string = dl->ypos + fi->descent; | 908 ypos2_string = dl->ypos + fi->descent; |
895 ypos1_line = dl->ypos - dl->ascent; | 909 ypos1_line = DISPLAY_LINE_YPOS (dl); |
896 ypos2_line = dl->ypos + dl->descent - dl->clip; | 910 ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl); |
897 | 911 |
898 /* Make sure we don't clear below the real bottom of the | 912 /* Make sure we don't clear below the real bottom of the |
899 line. */ | 913 line. */ |
900 if (ypos1_string > ypos2_line) | 914 if (ypos1_string > ypos2_line) |
901 ypos1_string = ypos2_line; | 915 ypos1_string = ypos2_line; |
917 } | 931 } |
918 } | 932 } |
919 else | 933 else |
920 { | 934 { |
921 redisplay_clear_region (window, findex, clear_start, | 935 redisplay_clear_region (window, findex, clear_start, |
922 dl->ypos - dl->ascent, clear_end - clear_start, | 936 DISPLAY_LINE_YPOS (dl), clear_end - clear_start, |
923 height); | 937 height); |
924 } | 938 } |
925 } | 939 } |
926 | 940 |
927 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) | 941 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) |
950 clip_box[0].x = 0; | 964 clip_box[0].x = 0; |
951 clip_box[0].y = 0; | 965 clip_box[0].y = 0; |
952 clip_box[0].width = clip_end - clip_start; | 966 clip_box[0].width = clip_end - clip_start; |
953 clip_box[0].height = height; | 967 clip_box[0].height = height; |
954 | 968 |
955 XSetClipRectangles (dpy, gc, clip_start, dl->ypos - dl->ascent, | 969 XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl), |
956 clip_box, 1, Unsorted); | 970 clip_box, 1, Unsorted); |
957 } | 971 } |
958 | 972 |
959 if (runs[i].dimension == 1) | 973 if (runs[i].dimension == 1) |
960 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, | 974 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, |
1050 clip_box[0].x = 0; | 1064 clip_box[0].x = 0; |
1051 clip_box[0].y = 0; | 1065 clip_box[0].y = 0; |
1052 clip_box[0].width = cursor_width; | 1066 clip_box[0].width = cursor_width; |
1053 clip_box[0].height = height; | 1067 clip_box[0].height = height; |
1054 | 1068 |
1055 XSetClipRectangles (dpy, cgc, cursor_start, dl->ypos - dl->ascent, | 1069 XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl), |
1056 clip_box, 1, Unsorted); | 1070 clip_box, 1, Unsorted); |
1057 | 1071 |
1058 if (runs[i].dimension == 1) | 1072 if (runs[i].dimension == 1) |
1059 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, | 1073 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, |
1060 (char *) runs[i].ptr, runs[i].len); | 1074 (char *) runs[i].ptr, runs[i].len); |
1110 Qnil, Qnil, Qnil); | 1124 Qnil, Qnil, Qnil); |
1111 } | 1125 } |
1112 | 1126 |
1113 tmp_y = dl->ypos - bogusly_obtained_ascent_value; | 1127 tmp_y = dl->ypos - bogusly_obtained_ascent_value; |
1114 tmp_height = cursor_height; | 1128 tmp_height = cursor_height; |
1115 if (tmp_y + tmp_height > (int) (dl->ypos - dl->ascent + height)) | 1129 if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height)) |
1116 { | 1130 { |
1117 tmp_y = dl->ypos - dl->ascent + height - tmp_height; | 1131 tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height; |
1118 if (tmp_y < (int) (dl->ypos - dl->ascent)) | 1132 if (tmp_y < (int) DISPLAY_LINE_YPOS (dl)) |
1119 tmp_y = dl->ypos - dl->ascent; | 1133 tmp_y = DISPLAY_LINE_YPOS (dl); |
1120 tmp_height = dl->ypos - dl->ascent + height - tmp_y; | 1134 tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y; |
1121 } | 1135 } |
1122 | 1136 |
1123 if (need_clipping) | 1137 if (need_clipping) |
1124 { | 1138 { |
1125 XRectangle clip_box[1]; | 1139 XRectangle clip_box[1]; |
1151 } | 1165 } |
1152 } | 1166 } |
1153 | 1167 |
1154 void | 1168 void |
1155 x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x, | 1169 x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x, |
1156 int y, int clip_x, int clip_y, int clip_width, | 1170 int y, int xoffset, int yoffset, |
1157 int clip_height, int width, int height, int pixmap_offset, | 1171 int width, int height, unsigned long fg, unsigned long bg, |
1158 unsigned long fg, unsigned long bg, GC override_gc) | 1172 GC override_gc) |
1159 { | 1173 { |
1160 struct device *d = XDEVICE (f->device); | 1174 struct device *d = XDEVICE (f->device); |
1161 Display *dpy = DEVICE_X_DISPLAY (d); | 1175 Display *dpy = DEVICE_X_DISPLAY (d); |
1162 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1176 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1163 | 1177 |
1164 GC gc; | 1178 GC gc; |
1165 XGCValues gcv; | 1179 XGCValues gcv; |
1166 unsigned long pixmap_mask; | 1180 unsigned long pixmap_mask; |
1167 int need_clipping = (clip_x || clip_y); | |
1168 | 1181 |
1169 if (!override_gc) | 1182 if (!override_gc) |
1170 { | 1183 { |
1171 memset (&gcv, ~0, sizeof (XGCValues)); | 1184 memset (&gcv, ~0, sizeof (XGCValues)); |
1172 gcv.graphics_exposures = False; | 1185 gcv.graphics_exposures = False; |
1176 | 1189 |
1177 if (IMAGE_INSTANCE_X_MASK (p)) | 1190 if (IMAGE_INSTANCE_X_MASK (p)) |
1178 { | 1191 { |
1179 gcv.function = GXcopy; | 1192 gcv.function = GXcopy; |
1180 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); | 1193 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); |
1181 gcv.clip_x_origin = x; | 1194 gcv.clip_x_origin = x - xoffset; |
1182 gcv.clip_y_origin = y - pixmap_offset; | 1195 gcv.clip_y_origin = y - yoffset; |
1183 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | | 1196 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | |
1184 GCClipYOrigin); | 1197 GCClipYOrigin); |
1185 /* Can't set a clip rectangle below because we already have a mask. | 1198 /* Can't set a clip rectangle because we already have a mask. |
1186 We could conceivably create a new clipmask by zeroing out | |
1187 everything outside the clip region. Is it worth it? | |
1188 Is it possible to get an equivalent effect by changing the | 1199 Is it possible to get an equivalent effect by changing the |
1189 args to XCopyArea below rather than messing with a clip box? | 1200 args to XCopyArea below rather than messing with a clip box? |
1190 - dkindred@cs.cmu.edu */ | 1201 - dkindred@cs.cmu.edu |
1191 need_clipping = 0; | 1202 Yes. We don't clip at all now - andy@xemacs.org |
1203 */ | |
1192 } | 1204 } |
1193 | 1205 |
1194 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask); | 1206 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask); |
1195 } | 1207 } |
1196 else | 1208 else |
1197 { | 1209 { |
1198 gc = override_gc; | 1210 gc = override_gc; |
1199 /* override_gc might have a mask already--we don't want to nuke it. | 1211 /* override_gc might have a mask already--we don't want to nuke it. |
1200 Maybe we can insist that override_gc have no mask, or use | 1212 Maybe we can insist that override_gc have no mask, or use |
1201 one of the suggestions above. */ | 1213 one of the suggestions above. */ |
1202 need_clipping = 0; | |
1203 } | |
1204 | |
1205 if (need_clipping) | |
1206 { | |
1207 XRectangle clip_box[1]; | |
1208 | |
1209 clip_box[0].x = clip_x; | |
1210 clip_box[0].y = clip_y; | |
1211 clip_box[0].width = clip_width; | |
1212 clip_box[0].height = clip_height; | |
1213 | |
1214 XSetClipRectangles (dpy, gc, x, y, clip_box, 1, Unsorted); | |
1215 } | 1214 } |
1216 | 1215 |
1217 /* depth of 0 means it's a bitmap, not a pixmap, and we should use | 1216 /* depth of 0 means it's a bitmap, not a pixmap, and we should use |
1218 XCopyPlane (1 = current foreground color, 0 = background) instead | 1217 XCopyPlane (1 = current foreground color, 0 = background) instead |
1219 of XCopyArea, which means that the bits in the pixmap are actual | 1218 of XCopyArea, which means that the bits in the pixmap are actual |
1220 pixel values, instead of symbolic of fg/bg. */ | 1219 pixel values, instead of symbolic of fg/bg. */ |
1221 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) | 1220 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) |
1222 { | 1221 { |
1223 XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, | 1222 XCopyArea (dpy, |
1224 pixmap_offset, width, | 1223 IMAGE_INSTANCE_X_PIXMAP_SLICE |
1224 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, xoffset, | |
1225 yoffset, width, | |
1225 height, x, y); | 1226 height, x, y); |
1226 } | 1227 } |
1227 else | 1228 else |
1228 { | 1229 { |
1229 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, | 1230 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE |
1230 (pixmap_offset < 0 | 1231 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, |
1231 ? 0 | 1232 xoffset, yoffset, width, height, x, y, 1L); |
1232 : pixmap_offset), | |
1233 width, height, x, | |
1234 (pixmap_offset < 0 | |
1235 ? y - pixmap_offset | |
1236 : y), | |
1237 1L); | |
1238 } | |
1239 | |
1240 if (need_clipping) | |
1241 { | |
1242 XSetClipMask (dpy, gc, None); | |
1243 XSetClipOrigin (dpy, gc, 0, 0); | |
1244 } | 1233 } |
1245 } | 1234 } |
1246 | 1235 |
1247 static void | 1236 static void |
1248 x_output_pixmap (struct window *w, struct display_line *dl, | 1237 x_output_pixmap (struct window *w, Lisp_Object image_instance, |
1249 Lisp_Object image_instance, int xpos, int xoffset, | 1238 struct display_box *db, struct display_glyph_area *dga, |
1250 int start_pixpos, int width, face_index findex, | 1239 face_index findex, int cursor_start, int cursor_width, |
1251 int cursor_start, int cursor_width, int cursor_height) | 1240 int cursor_height, int bg_pixmap) |
1252 { | 1241 { |
1253 struct frame *f = XFRAME (w->frame); | 1242 struct frame *f = XFRAME (w->frame); |
1254 struct device *d = XDEVICE (f->device); | 1243 struct device *d = XDEVICE (f->device); |
1255 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 1244 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
1256 Lisp_Object window; | |
1257 | 1245 |
1258 Display *dpy = DEVICE_X_DISPLAY (d); | 1246 Display *dpy = DEVICE_X_DISPLAY (d); |
1259 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1247 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1260 int lheight = dl->ascent + dl->descent - dl->clip; | 1248 |
1261 int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight : | |
1262 IMAGE_INSTANCE_PIXMAP_HEIGHT (p)); | |
1263 int pwidth = min (width + xoffset, (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p)); | |
1264 int clip_x, clip_y, clip_width, clip_height; | |
1265 | |
1266 /* The pixmap_offset is used to center the pixmap on lines which are | |
1267 shorter than it is. This results in odd effects when scrolling | |
1268 pixmaps off of the bottom. Let's try not using it. */ | |
1269 #if 0 | |
1270 int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2; | |
1271 #else | |
1272 int pixmap_offset = 0; | |
1273 #endif | |
1274 | |
1275 XSETWINDOW (window, w); | |
1276 | |
1277 if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset) | |
1278 { | |
1279 if (start_pixpos > xpos && start_pixpos > xpos + width) | |
1280 return; | |
1281 | |
1282 clip_x = xoffset; | |
1283 clip_width = width; | |
1284 if (start_pixpos > xpos) | |
1285 { | |
1286 clip_x += (start_pixpos - xpos); | |
1287 clip_width -= (start_pixpos - xpos); | |
1288 } | |
1289 } | |
1290 else | |
1291 { | |
1292 clip_x = 0; | |
1293 clip_width = 0; | |
1294 } | |
1295 | |
1296 /* Place markers for possible future functionality (clipping the top | |
1297 half instead of the bottom half; think pixel scrolling). */ | |
1298 clip_y = 0; | |
1299 clip_height = pheight; | |
1300 | |
1301 /* Clear the area the pixmap is going into. The pixmap itself will | |
1302 always take care of the full width. We don't want to clear where | |
1303 it is going to go in order to avoid flicker. So, all we have to | |
1304 take care of is any area above or below the pixmap. */ | |
1305 /* #### We take a shortcut for now. We know that since we have | |
1306 pixmap_offset hardwired to 0 that the pixmap is against the top | |
1307 edge so all we have to worry about is below it. */ | |
1308 /* #### Unless the pixmap has a mask in which case we have to clear | |
1309 the whole damn thing since we can't yet clear just the area not | |
1310 included in the mask. */ | |
1311 if (((int) (dl->ypos - dl->ascent + pheight) < | |
1312 (int) (dl->ypos + dl->descent - dl->clip)) | |
1313 || IMAGE_INSTANCE_X_MASK (p)) | |
1314 { | |
1315 int clear_x, clear_y, clear_width, clear_height; | |
1316 | |
1317 if (IMAGE_INSTANCE_X_MASK (p)) | |
1318 { | |
1319 clear_y = dl->ypos - dl->ascent; | |
1320 clear_height = lheight; | |
1321 } | |
1322 else | |
1323 { | |
1324 clear_y = dl->ypos - dl->ascent + pheight; | |
1325 clear_height = lheight - pheight; | |
1326 } | |
1327 | |
1328 if (start_pixpos >= 0 && start_pixpos > xpos) | |
1329 { | |
1330 clear_x = start_pixpos; | |
1331 clear_width = xpos + width - start_pixpos; | |
1332 } | |
1333 else | |
1334 { | |
1335 clear_x = xpos; | |
1336 clear_width = width; | |
1337 } | |
1338 | |
1339 redisplay_clear_region (window, findex, clear_x, clear_y, | |
1340 clear_width, clear_height); | |
1341 } | |
1342 | |
1343 /* Output the pixmap. */ | 1249 /* Output the pixmap. */ |
1344 { | 1250 { |
1345 Lisp_Object tmp_pixel; | 1251 Lisp_Object tmp_pixel; |
1346 XColor tmp_bcolor, tmp_fcolor; | 1252 XColor tmp_bcolor, tmp_fcolor; |
1347 | 1253 |
1348 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | 1254 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); |
1349 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 1255 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1350 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 1256 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); |
1351 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 1257 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1352 | 1258 |
1353 x_output_x_pixmap (f, p, xpos - xoffset, dl->ypos - dl->ascent, clip_x, | 1259 x_output_x_pixmap (f, p, db->xpos, db->ypos, |
1354 clip_y, clip_width, clip_height, | 1260 dga->xoffset, dga->yoffset, |
1355 pwidth, pheight, pixmap_offset, | 1261 dga->width, dga->height, |
1356 tmp_fcolor.pixel, tmp_bcolor.pixel, 0); | 1262 tmp_fcolor.pixel, tmp_bcolor.pixel, 0); |
1357 } | 1263 } |
1358 | 1264 |
1359 /* Draw a cursor over top of the pixmap. */ | 1265 /* Draw a cursor over top of the pixmap. */ |
1360 if (cursor_width && cursor_height && (cursor_start >= xpos) | 1266 if (cursor_width && cursor_height && (cursor_start >= db->xpos) |
1361 && !NILP (w->text_cursor_visible_p) | 1267 && !NILP (w->text_cursor_visible_p) |
1362 && (cursor_start < xpos + pwidth)) | 1268 && (cursor_start < db->xpos + dga->width)) |
1363 { | 1269 { |
1364 GC gc; | 1270 GC gc; |
1365 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 1271 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
1366 int y = dl->ypos - dl->ascent; | |
1367 struct face_cachel *cursor_cachel = | 1272 struct face_cachel *cursor_cachel = |
1368 WINDOW_FACE_CACHEL (w, | 1273 WINDOW_FACE_CACHEL (w, |
1369 get_builtin_face_cache_index | 1274 get_builtin_face_cache_index |
1370 (w, Vtext_cursor_face)); | 1275 (w, Vtext_cursor_face)); |
1371 | 1276 |
1372 gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil); | 1277 gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil); |
1373 | 1278 |
1374 if (cursor_width > xpos + pwidth - cursor_start) | 1279 if (cursor_width > db->xpos + dga->width - cursor_start) |
1375 cursor_width = xpos + pwidth - cursor_start; | 1280 cursor_width = db->xpos + dga->width - cursor_start; |
1376 | 1281 |
1377 if (focus) | 1282 if (focus) |
1378 { | 1283 { |
1379 XFillRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, | 1284 XFillRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, |
1380 cursor_height); | 1285 cursor_height); |
1381 } | 1286 } |
1382 else | 1287 else |
1383 { | 1288 { |
1384 XDrawRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, | 1289 XDrawRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, |
1385 cursor_height); | 1290 cursor_height); |
1386 } | 1291 } |
1387 } | 1292 } |
1388 } | 1293 } |
1389 | 1294 |
1402 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1307 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1403 Lisp_Object tmp_pixel; | 1308 Lisp_Object tmp_pixel; |
1404 XColor tmp_color; | 1309 XColor tmp_color; |
1405 XGCValues gcv; | 1310 XGCValues gcv; |
1406 GC background_gc; | 1311 GC background_gc; |
1312 enum edge_style style; | |
1407 | 1313 |
1408 unsigned long mask; | 1314 unsigned long mask; |
1409 int x, y1, y2, width, shadow_thickness, spacing, line_width; | 1315 int x, y1, y2, width, shadow_thickness, spacing, line_width; |
1410 face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); | 1316 face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); |
1411 | 1317 |
1437 /* Draw the divider line. */ | 1343 /* Draw the divider line. */ |
1438 XFillRectangle (dpy, x_win, background_gc, | 1344 XFillRectangle (dpy, x_win, background_gc, |
1439 x + spacing + shadow_thickness, y1, | 1345 x + spacing + shadow_thickness, y1, |
1440 line_width, y2 - y1); | 1346 line_width, y2 - y1); |
1441 | 1347 |
1348 if (shadow_thickness < 0) | |
1349 { | |
1350 shadow_thickness = -shadow_thickness; | |
1351 style = EDGE_BEVEL_IN; | |
1352 } | |
1353 else | |
1354 { | |
1355 style = EDGE_BEVEL_OUT; | |
1356 } | |
1357 | |
1442 /* Draw the shadows around the divider line */ | 1358 /* Draw the shadows around the divider line */ |
1443 x_bevel_area (w, div_face, x + spacing, y1, | 1359 x_bevel_area (w, div_face, x + spacing, y1, |
1444 width - 2 * spacing, y2 - y1, | 1360 width - 2 * spacing, y2 - y1, |
1445 shadow_thickness); | 1361 shadow_thickness, EDGE_ALL, style); |
1446 } | 1362 } |
1447 | 1363 |
1448 /***************************************************************************** | 1364 /***************************************************************************** |
1449 x_output_blank | 1365 x_output_blank |
1450 | 1366 |
1469 Lisp_Object buffer = WINDOW_BUFFER (w); | 1385 Lisp_Object buffer = WINDOW_BUFFER (w); |
1470 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, | 1386 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, |
1471 buffer); | 1387 buffer); |
1472 | 1388 |
1473 int x = rb->xpos; | 1389 int x = rb->xpos; |
1474 int y = dl->ypos - dl->ascent; | 1390 int y = DISPLAY_LINE_YPOS (dl); |
1475 int width = rb->width; | 1391 int width = rb->width; |
1476 int height = dl->ascent + dl->descent - dl->clip; | 1392 int height = DISPLAY_LINE_HEIGHT (dl); |
1393 | |
1394 /* Unmap all subwindows in the area we are going to blank. */ | |
1395 redisplay_unmap_subwindows_maybe (f, x, y, width, height); | |
1477 | 1396 |
1478 if (start_pixpos > x) | 1397 if (start_pixpos > x) |
1479 { | 1398 { |
1480 if (start_pixpos >= (x + width)) | 1399 if (start_pixpos >= (x + width)) |
1481 return; | 1400 return; |
1565 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1484 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1566 GC gc; | 1485 GC gc; |
1567 | 1486 |
1568 int x = rb->xpos; | 1487 int x = rb->xpos; |
1569 int width = rb->width; | 1488 int width = rb->width; |
1570 int height = dl->ascent + dl->descent - dl->clip; | 1489 int height = DISPLAY_LINE_HEIGHT (dl); |
1571 int ypos1, ypos2, ypos3, ypos4; | 1490 int ypos1, ypos2, ypos3, ypos4; |
1572 | 1491 |
1573 ypos1 = dl->ypos - dl->ascent; | 1492 ypos1 = DISPLAY_LINE_YPOS (dl); |
1574 ypos2 = ypos1 + rb->object.hline.yoffset; | 1493 ypos2 = ypos1 + rb->object.hline.yoffset; |
1575 ypos3 = ypos2 + rb->object.hline.thickness; | 1494 ypos3 = ypos2 + rb->object.hline.thickness; |
1576 ypos4 = dl->ypos + dl->descent - dl->clip; | 1495 ypos4 = dl->ypos + dl->descent - dl->clip; |
1577 | 1496 |
1578 /* First clear the area not covered by the line. */ | 1497 /* First clear the area not covered by the line. */ |
1607 callers responsibility to set the GC's appropriately. | 1526 callers responsibility to set the GC's appropriately. |
1608 ****************************************************************************/ | 1527 ****************************************************************************/ |
1609 void | 1528 void |
1610 x_output_shadows (struct frame *f, int x, int y, int width, int height, | 1529 x_output_shadows (struct frame *f, int x, int y, int width, int height, |
1611 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, | 1530 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, |
1612 int shadow_thickness) | 1531 int shadow_thickness, int edges) |
1613 { | 1532 { |
1614 struct device *d = XDEVICE (f->device); | 1533 struct device *d = XDEVICE (f->device); |
1615 | 1534 |
1616 Display *dpy = DEVICE_X_DISPLAY (d); | 1535 Display *dpy = DEVICE_X_DISPLAY (d); |
1617 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1536 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1629 shadow_thickness = height / 2; | 1548 shadow_thickness = height / 2; |
1630 | 1549 |
1631 for (elt = 0; elt < shadow_thickness; elt++) | 1550 for (elt = 0; elt < shadow_thickness; elt++) |
1632 { | 1551 { |
1633 int seg1 = elt; | 1552 int seg1 = elt; |
1634 int seg2 = elt + shadow_thickness; | 1553 int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt; |
1635 | 1554 int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt; |
1636 top_shadow[seg1].x1 = x; | 1555 |
1637 top_shadow[seg1].x2 = x + width - elt - 1; | 1556 if (edges & EDGE_TOP) |
1638 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; | 1557 { |
1639 | 1558 top_shadow[seg1].x1 = x + elt; |
1640 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; | 1559 top_shadow[seg1].x2 = x + width - elt - 1; |
1641 top_shadow[seg2].y1 = y + shadow_thickness; | 1560 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; |
1642 top_shadow[seg2].y2 = y + height - elt - 1; | 1561 } |
1643 | 1562 if (edges & EDGE_LEFT) |
1644 bottom_shadow[seg1].x1 = x + elt + 1; | 1563 { |
1645 bottom_shadow[seg1].x2 = x + width - 1; | 1564 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; |
1646 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; | 1565 top_shadow[seg2].y1 = y + elt; |
1647 | 1566 top_shadow[seg2].y2 = y + height - elt - 1; |
1648 bottom_shadow[seg2].x1 = bottom_shadow[seg2].x2 = x + width - elt - 1; | 1567 } |
1649 bottom_shadow[seg2].y1 = y + elt + 1; | 1568 if (edges & EDGE_BOTTOM) |
1650 bottom_shadow[seg2].y2 = y + height - shadow_thickness; | 1569 { |
1651 } | 1570 bottom_shadow[seg1].x1 = x + elt; |
1652 | 1571 bottom_shadow[seg1].x2 = x + width - elt - 1; |
1653 XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, shadow_thickness * 2); | 1572 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; |
1573 } | |
1574 if (edges & EDGE_RIGHT) | |
1575 { | |
1576 bottom_shadow[bot_seg2].x1 = bottom_shadow[bot_seg2].x2 = x + width - elt - 1; | |
1577 bottom_shadow[bot_seg2].y1 = y + elt; | |
1578 bottom_shadow[bot_seg2].y2 = y + height - elt - 1; | |
1579 } | |
1580 } | |
1581 | |
1582 XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, | |
1583 ((edges & EDGE_TOP) ? shadow_thickness : 0) | |
1584 + ((edges & EDGE_LEFT) ? shadow_thickness : 0)); | |
1654 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, | 1585 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, |
1655 shadow_thickness * 2); | 1586 ((edges & EDGE_BOTTOM) ? shadow_thickness : 0) |
1587 + ((edges & EDGE_RIGHT) ? shadow_thickness : 0)); | |
1656 } | 1588 } |
1657 | 1589 |
1658 /***************************************************************************** | 1590 /***************************************************************************** |
1659 x_generate_shadow_pixels | 1591 x_generate_shadow_pixels |
1660 | 1592 |
1921 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 1853 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
1922 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, | 1854 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, |
1923 WINDOW_BUFFER (w)); | 1855 WINDOW_BUFFER (w)); |
1924 | 1856 |
1925 int x = xpos; | 1857 int x = xpos; |
1926 int y = dl->ypos - dl->ascent; | 1858 int y = DISPLAY_LINE_YPOS (dl); |
1927 int width = EOL_CURSOR_WIDTH; | 1859 int width = EOL_CURSOR_WIDTH; |
1928 int height = dl->ascent + dl->descent - dl->clip; | 1860 int height = DISPLAY_LINE_HEIGHT (dl); |
1929 int cursor_height, cursor_y; | 1861 int cursor_height, cursor_y; |
1930 int defheight, defascent; | 1862 int defheight, defascent; |
1931 | 1863 |
1932 XSETWINDOW (window, w); | 1864 XSETWINDOW (window, w); |
1933 redisplay_clear_region (window, findex, x, y, width, height); | 1865 redisplay_clear_region (window, findex, x, y, width, height); |
2151 CONSOLE_HAS_METHOD (x, output_begin); | 2083 CONSOLE_HAS_METHOD (x, output_begin); |
2152 CONSOLE_HAS_METHOD (x, output_end); | 2084 CONSOLE_HAS_METHOD (x, output_end); |
2153 CONSOLE_HAS_METHOD (x, flash); | 2085 CONSOLE_HAS_METHOD (x, flash); |
2154 CONSOLE_HAS_METHOD (x, ring_bell); | 2086 CONSOLE_HAS_METHOD (x, ring_bell); |
2155 CONSOLE_HAS_METHOD (x, bevel_area); | 2087 CONSOLE_HAS_METHOD (x, bevel_area); |
2156 } | 2088 CONSOLE_HAS_METHOD (x, output_string); |
2089 CONSOLE_HAS_METHOD (x, output_pixmap); | |
2090 } |