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 }