comparison src/redisplay-x.c @ 398:74fd4e045ea6 r21-2-29

Import from CVS: tag r21-2-29
author cvs
date Mon, 13 Aug 2007 11:13:30 +0200
parents bbff43aa5eb7
children 2f8bb876ab1d
comparison
equal deleted inserted replaced
397:f4aeb21a5bad 398:74fd4e045ea6
38 38
39 #include "buffer.h" 39 #include "buffer.h"
40 #include "debug.h" 40 #include "debug.h"
41 #include "faces.h" 41 #include "faces.h"
42 #include "frame.h" 42 #include "frame.h"
43 #include "gutter.h"
43 #include "redisplay.h" 44 #include "redisplay.h"
44 #include "sysdep.h" 45 #include "sysdep.h"
45 #include "window.h" 46 #include "window.h"
46 #include <X11/bitmaps/gray> 47 #include <X11/bitmaps/gray>
47 48
51 #include "mule-ccl.h" 52 #include "mule-ccl.h"
52 #include "file-coding.h" /* for CCL conversion */ 53 #include "file-coding.h" /* for CCL conversion */
53 #endif 54 #endif
54 55
55 /* Number of pixels below each line. */ 56 /* Number of pixels below each line. */
56 /* #### implement me */ 57 int x_interline_space; /* #### implement me */
57 int x_interline_space;
58 58
59 #define EOL_CURSOR_WIDTH 5 59 #define EOL_CURSOR_WIDTH 5
60 60
61 static void x_output_pixmap (struct window *w, struct display_line *dl,
62 Lisp_Object image_instance, int xpos,
63 int xoffset,
64 int start_pixpos, int width, face_index findex,
65 int cursor_start, int cursor_width,
66 int cursor_height);
67 static void x_output_vertical_divider (struct window *w, int clear); 61 static void x_output_vertical_divider (struct window *w, int clear);
68 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,
69 struct rune *rb, int start_pixpos, 63 struct rune *rb, int start_pixpos,
70 int cursor_start, int cursor_width); 64 int cursor_start, int cursor_width);
71 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,
76 int width, int height); 70 int width, int height);
77 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,
78 int xpos, face_index findex); 72 int xpos, face_index findex);
79 static void x_clear_frame (struct frame *f); 73 static void x_clear_frame (struct frame *f);
80 static void x_clear_frame_windows (Lisp_Object window); 74 static void x_clear_frame_windows (Lisp_Object window);
81 static void x_bevel_modeline (struct window *w, struct display_line *dl);
82 75
83 76
84 /* Note: We do not use the Xmb*() functions and XFontSets. 77 /* Note: We do not use the Xmb*() functions and XFontSets.
85 Those functions are generally losing for a number of reasons: 78 Those functions are generally losing for a number of reasons:
86 79
128 Returns the number of runs actually used. */ 121 Returns the number of runs actually used. */
129 122
130 static int 123 static int
131 separate_textual_runs (unsigned char *text_storage, 124 separate_textual_runs (unsigned char *text_storage,
132 struct textual_run *run_storage, 125 struct textual_run *run_storage,
133 CONST Emchar *str, Charcount len) 126 const Emchar *str, Charcount len)
134 { 127 {
135 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a 128 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a
136 possible valid charset when 129 possible valid charset when
137 MULE is not defined */ 130 MULE is not defined */
138 int runs_so_far = 0; 131 int runs_so_far = 0;
193 if (need_ccl_conversion) 186 if (need_ccl_conversion)
194 { 187 {
195 char_converter.reg[0] = XCHARSET_ID (charset); 188 char_converter.reg[0] = XCHARSET_ID (charset);
196 char_converter.reg[1] = byte1; 189 char_converter.reg[1] = byte1;
197 char_converter.reg[2] = byte2; 190 char_converter.reg[2] = byte2;
198 ccl_driver (&char_converter, 0, 0, 0, 0); 191 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING);
199 byte1 = char_converter.reg[1]; 192 byte1 = char_converter.reg[1];
200 byte2 = char_converter.reg[2]; 193 byte2 = char_converter.reg[2];
201 } 194 }
202 #endif 195 #endif
203 *text_storage++ = (unsigned char) byte1; 196 *text_storage++ = (unsigned char) byte1;
224 217
225 static int 218 static int
226 x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run) 219 x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run)
227 { 220 {
228 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); 221 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset);
229 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); 222 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst);
230 if (!fi->proportional_p) 223 if (!fi->proportional_p)
231 return fi->width * run->len; 224 return fi->width * run->len;
232 else 225 else
233 { 226 {
234 if (run->dimension == 2) 227 if (run->dimension == 2)
246 Given a string and a face, return the string's length in pixels when 239 Given a string and a face, return the string's length in pixels when
247 displayed in the font associated with the face. 240 displayed in the font associated with the face.
248 */ 241 */
249 242
250 static int 243 static int
251 x_text_width (struct frame *f, struct face_cachel *cachel, CONST Emchar *str, 244 x_text_width (struct frame *f, struct face_cachel *cachel, const Emchar *str,
252 Charcount len) 245 Charcount len)
253 { 246 {
254 int width_so_far = 0; 247 int width_so_far = 0;
255 unsigned char *text_storage = (unsigned char *) alloca (2 * len); 248 unsigned char *text_storage = (unsigned char *) alloca (2 * len);
256 struct textual_run *runs = alloca_array (struct textual_run, len); 249 struct textual_run *runs = alloca_array (struct textual_run, len);
332 rune_dynarr *rba = db->runes; 325 rune_dynarr *rba = db->runes;
333 struct rune *rb; 326 struct rune *rb;
334 327
335 int elt = start; 328 int elt = start;
336 face_index findex; 329 face_index findex;
337 int xpos, width; 330 int xpos, width = 0;
338 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when 331 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when
339 MULE is not defined */ 332 MULE is not defined */
340 333
341 XSETWINDOW (window, w); 334 XSETWINDOW (window, w);
342 rb = Dynarr_atp (rba, start); 335 rb = Dynarr_atp (rba, start);
343 336
344 if (!rb) 337 if (!rb)
345 { 338 /* Nothing to do so don't do anything. */
346 /* Nothing to do so don't do anything. */ 339 return;
347 return; 340
348 } 341 findex = rb->findex;
349 else 342 xpos = rb->xpos;
350 { 343 if (rb->type == RUNE_CHAR)
351 findex = rb->findex; 344 charset = CHAR_CHARSET (rb->object.chr.ch);
352 xpos = rb->xpos;
353 width = 0;
354 if (rb->type == RUNE_CHAR)
355 charset = CHAR_CHARSET (rb->object.chr.ch);
356 }
357 345
358 if (end < 0) 346 if (end < 0)
359 end = Dynarr_length (rba); 347 end = Dynarr_length (rba);
360 Dynarr_reset (buf); 348 Dynarr_reset (buf);
361 349
410 elt++; 398 elt++;
411 } 399 }
412 else if (rb->object.chr.ch == '\n') 400 else if (rb->object.chr.ch == '\n')
413 { 401 {
414 /* Clear in case a cursor was formerly here. */ 402 /* Clear in case a cursor was formerly here. */
415 int height = dl->ascent + dl->descent - dl->clip; 403 redisplay_clear_region (window, findex, xpos,
416 404 DISPLAY_LINE_YPOS (dl),
417 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, 405 rb->width,
418 rb->width, height); 406 DISPLAY_LINE_HEIGHT (dl));
419 elt++; 407 elt++;
420 } 408 }
421 } 409 }
422 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) 410 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE)
423 { 411 {
447 } 435 }
448 } 436 }
449 else if (rb->type == RUNE_DGLYPH) 437 else if (rb->type == RUNE_DGLYPH)
450 { 438 {
451 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);
452 445
453 XSETWINDOW (window, w); 446 XSETWINDOW (window, w);
454 instance = glyph_image_instance (rb->object.dglyph.glyph, 447 instance = glyph_image_instance (rb->object.dglyph.glyph,
455 window, ERROR_ME_NOT, 1); 448 window, ERROR_ME_NOT, 1);
456 findex = rb->findex; 449 findex = rb->findex;
477 } 470 }
478 break; 471 break;
479 472
480 case IMAGE_MONO_PIXMAP: 473 case IMAGE_MONO_PIXMAP:
481 case IMAGE_COLOR_PIXMAP: 474 case IMAGE_COLOR_PIXMAP:
482 x_output_pixmap (w, dl, instance, xpos, 475 redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
483 rb->object.dglyph.xoffset, start_pixpos, 476 cursor_start, cursor_width,
484 rb->width, findex, cursor_start, 477 cursor_height, 0);
485 cursor_width, cursor_height);
486 break; 478 break;
487
488 case IMAGE_POINTER:
489 abort ();
490 479
491 case IMAGE_WIDGET: 480 case IMAGE_WIDGET:
492 case IMAGE_SUBWINDOW: 481 case IMAGE_SUBWINDOW:
493 redisplay_output_subwindow (w, dl, instance, xpos, 482 redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
494 rb->object.dglyph.xoffset, start_pixpos, 483 cursor_start, cursor_width,
495 rb->width, findex, cursor_start, 484 cursor_height);
496 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;
497 492
498 case IMAGE_NOTHING: 493 case IMAGE_NOTHING:
499 /* nothing is as nothing does */ 494 /* nothing is as nothing does */
500 break; 495 break;
501 496
497 case IMAGE_POINTER:
502 default: 498 default:
503 abort (); 499 abort ();
504 } 500 }
505 501
506 xpos += rb->width; 502 xpos += rb->width;
520 if (dl->modeline 516 if (dl->modeline
521 && !EQ (Qzero, w->modeline_shadow_thickness) 517 && !EQ (Qzero, w->modeline_shadow_thickness)
522 && (f->clear 518 && (f->clear
523 || f->windows_structure_changed 519 || f->windows_structure_changed
524 || w->shadow_thickness_changed)) 520 || w->shadow_thickness_changed))
525 x_bevel_modeline (w, dl); 521 bevel_modeline (w, dl);
526 522
527 Dynarr_free (buf); 523 Dynarr_free (buf);
528 } 524 }
529 525
530 /***************************************************************************** 526 /*****************************************************************************
531 x_bevel_modeline 527 x_bevel_area
532 528
533 Draw a 3d border around the modeline on window W. 529 Draw a shadows for the given area in the given face.
534 ****************************************************************************/ 530 ****************************************************************************/
535 static void 531 static void
536 x_bevel_modeline (struct window *w, struct display_line *dl) 532 x_bevel_area (struct window *w, face_index findex,
533 int x, int y, int width, int height,
534 int shadow_thickness, int edges, enum edge_style style)
537 { 535 {
538 struct frame *f = XFRAME (w->frame); 536 struct frame *f = XFRAME (w->frame);
539 struct device *d = XDEVICE (f->device); 537 struct device *d = XDEVICE (f->device);
538
539 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
540 Display *dpy = DEVICE_X_DISPLAY (d); 540 Display *dpy = DEVICE_X_DISPLAY (d);
541 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 541 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
542 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); 542 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel;
543 Lisp_Object tmp_pixel;
544 XColor tmp_color;
545 XGCValues gcv;
543 GC top_shadow_gc, bottom_shadow_gc, background_gc; 546 GC top_shadow_gc, bottom_shadow_gc, background_gc;
544 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; 547
545 XColor tmp_color;
546 Lisp_Object tmp_pixel;
547 int x, y, width, height;
548 XGCValues gcv;
549 unsigned long mask;
550 int use_pixmap = 0; 548 int use_pixmap = 0;
551 int flip_gcs = 0; 549 int flip_gcs = 0;
552 int shadow_thickness; 550 unsigned long mask;
553 551
552 assert (shadow_thickness >=0);
554 memset (&gcv, ~0, sizeof (XGCValues)); 553 memset (&gcv, ~0, sizeof (XGCValues));
555 554
556 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); 555 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
557 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 556 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
558 557
559 /* First, get the GC's. */ 558 /* First, get the GC's. */
560 top_shadow_pixel = tmp_color.pixel; 559 top_shadow_pixel = tmp_color.pixel;
561 bottom_shadow_pixel = tmp_color.pixel; 560 bottom_shadow_pixel = tmp_color.pixel;
562 background_pixel = tmp_color.pixel; 561 background_pixel = tmp_color.pixel;
563 562
564 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel, 563 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel,
565 background_pixel, ef->core.background_pixel); 564 background_pixel, ef->core.background_pixel);
566 565
567 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX); 566 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
568 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 567 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
569 gcv.background = tmp_color.pixel; 568 gcv.background = tmp_color.pixel;
570 gcv.graphics_exposures = False; 569 gcv.graphics_exposures = False;
571 mask = GCForeground | GCBackground | GCGraphicsExposures; 570 mask = GCForeground | GCBackground | GCGraphicsExposures;
572 571
572 /* If we can't distinguish one of the shadows (the color is the same as the
573 background), it's better to use a pixmap to generate a dithered gray. */
573 if (top_shadow_pixel == background_pixel || 574 if (top_shadow_pixel == background_pixel ||
574 bottom_shadow_pixel == background_pixel) 575 bottom_shadow_pixel == background_pixel)
575 use_pixmap = 1; 576 use_pixmap = 1;
576 577
577 if (use_pixmap) 578 if (use_pixmap)
581 DEVICE_X_GRAY_PIXMAP (d) = 582 DEVICE_X_GRAY_PIXMAP (d) =
582 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits, 583 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits,
583 gray_width, gray_height, 1, 0, 1); 584 gray_width, gray_height, 1, 0, 1);
584 } 585 }
585 586
586 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); 587 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
587 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 588 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
588 gcv.foreground = tmp_color.pixel; 589 gcv.foreground = tmp_color.pixel;
590 /* this is needed because the GC draws with a pixmap here */
589 gcv.fill_style = FillOpaqueStippled; 591 gcv.fill_style = FillOpaqueStippled;
590 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d); 592 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d);
591 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, 593 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv,
592 (mask | GCStipple | GCFillStyle)); 594 (mask | GCStipple | GCFillStyle));
593 595
594 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX); 596 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
595 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 597 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
596 bottom_shadow_pixel = tmp_color.pixel; 598 bottom_shadow_pixel = tmp_color.pixel;
597 599
598 flip_gcs = (bottom_shadow_pixel == 600 flip_gcs = (bottom_shadow_pixel ==
599 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy))); 601 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy)));
615 } 617 }
616 618
617 gcv.foreground = background_pixel; 619 gcv.foreground = background_pixel;
618 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);
619 621
620 if (XINT (w->modeline_shadow_thickness) < 0) 622 /* possibly revert the GC's This will give a depressed look to the
623 divider */
624 if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN)
621 { 625 {
622 GC temp; 626 GC temp;
623 627
624 temp = top_shadow_gc; 628 temp = top_shadow_gc;
625 top_shadow_gc = bottom_shadow_gc; 629 top_shadow_gc = bottom_shadow_gc;
626 bottom_shadow_gc = temp; 630 bottom_shadow_gc = temp;
627 } 631 }
628 632
629 shadow_thickness = MODELINE_SHADOW_THICKNESS (w); 633 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT)
630 634 shadow_thickness /= 2;
631 x = WINDOW_MODELINE_LEFT (w); 635
632 width = WINDOW_MODELINE_RIGHT (w) - x; 636 /* Draw the shadows around the divider line */
633 y = dl->ypos - dl->ascent - shadow_thickness; 637 x_output_shadows (f, x, y, width, height,
634 height = dl->ascent + dl->descent + 2 * shadow_thickness; 638 top_shadow_gc, bottom_shadow_gc,
635 639 background_gc, shadow_thickness, edges);
636 x_output_shadows (f, x, y, width, height, top_shadow_gc, bottom_shadow_gc, 640
637 background_gc, shadow_thickness); 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 }
638 } 649 }
639 650
640 /***************************************************************************** 651 /*****************************************************************************
641 x_get_gc 652 x_get_gc
642 653
800 XSETDEVICE (device, d); 811 XSETDEVICE (device, d);
801 XSETWINDOW (window, w); 812 XSETWINDOW (window, w);
802 813
803 if (width < 0) 814 if (width < 0)
804 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));
805 height = dl->ascent + dl->descent - dl->clip; 816 height = DISPLAY_LINE_HEIGHT (dl);
806 817
807 /* Regularize the variables passed in. */ 818 /* Regularize the variables passed in. */
808 819
809 if (clip_start < xpos) 820 if (clip_start < xpos)
810 clip_start = xpos; 821 clip_start = xpos;
812 if (clip_start >= clip_end) 823 if (clip_start >= clip_end)
813 /* It's all clipped out. */ 824 /* It's all clipped out. */
814 return; 825 return;
815 826
816 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));
817 832
818 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), 833 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0),
819 Dynarr_length (buf)); 834 Dynarr_length (buf));
820 835
821 cursor_clip = (cursor_start >= clip_start && 836 cursor_clip = (cursor_start >= clip_start &&
857 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, 872 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background,
858 bg_pmap, Qnil); 873 bg_pmap, Qnil);
859 874
860 if (bgc) 875 if (bgc)
861 XFillRectangle (dpy, x_win, bgc, clip_start, 876 XFillRectangle (dpy, x_win, bgc, clip_start,
862 dl->ypos - dl->ascent, clip_end - clip_start, 877 DISPLAY_LINE_YPOS (dl), clip_end - clip_start,
863 height); 878 height);
864 879
865 for (i = 0; i < nruns; i++) 880 for (i = 0; i < nruns; i++)
866 { 881 {
867 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); 882 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset);
868 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); 883 Lisp_Font_Instance *fi = XFONT_INSTANCE (font);
869 int this_width; 884 int this_width;
870 int need_clipping; 885 int need_clipping;
871 886
872 if (EQ (font, Vthe_null_font_instance)) 887 if (EQ (font, Vthe_null_font_instance))
873 continue; 888 continue;
878 893
879 /* XDrawImageString only clears the area equal to the height of 894 /* XDrawImageString only clears the area equal to the height of
880 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
881 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
882 clear some areas. */ 897 clear some areas. */
883 if ((int) fi->height < (int) (height + dl->clip)) 898 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip))
884 { 899 {
885 int clear_start = max (xpos, clip_start); 900 int clear_start = max (xpos, clip_start);
886 int clear_end = min (xpos + this_width, clip_end); 901 int clear_end = min (xpos + this_width, clip_end);
887 902
888 if (cursor) 903 if (cursor)
889 { 904 {
890 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; 905 int ypos1_line, ypos1_string, ypos2_line, ypos2_string;
891 906
892 ypos1_string = dl->ypos - fi->ascent; 907 ypos1_string = dl->ypos - fi->ascent;
893 ypos2_string = dl->ypos + fi->descent; 908 ypos2_string = dl->ypos + fi->descent;
894 ypos1_line = dl->ypos - dl->ascent; 909 ypos1_line = DISPLAY_LINE_YPOS (dl);
895 ypos2_line = dl->ypos + dl->descent - dl->clip; 910 ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl);
896 911
897 /* 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
898 line. */ 913 line. */
899 if (ypos1_string > ypos2_line) 914 if (ypos1_string > ypos2_line)
900 ypos1_string = ypos2_line; 915 ypos1_string = ypos2_line;
916 } 931 }
917 } 932 }
918 else 933 else
919 { 934 {
920 redisplay_clear_region (window, findex, clear_start, 935 redisplay_clear_region (window, findex, clear_start,
921 dl->ypos - dl->ascent, clear_end - clear_start, 936 DISPLAY_LINE_YPOS (dl), clear_end - clear_start,
922 height); 937 height);
923 } 938 }
924 } 939 }
925 940
926 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) 941 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value))
949 clip_box[0].x = 0; 964 clip_box[0].x = 0;
950 clip_box[0].y = 0; 965 clip_box[0].y = 0;
951 clip_box[0].width = clip_end - clip_start; 966 clip_box[0].width = clip_end - clip_start;
952 clip_box[0].height = height; 967 clip_box[0].height = height;
953 968
954 XSetClipRectangles (dpy, gc, clip_start, dl->ypos - dl->ascent, 969 XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl),
955 clip_box, 1, Unsorted); 970 clip_box, 1, Unsorted);
956 } 971 }
957 972
958 if (runs[i].dimension == 1) 973 if (runs[i].dimension == 1)
959 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, 974 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos,
1049 clip_box[0].x = 0; 1064 clip_box[0].x = 0;
1050 clip_box[0].y = 0; 1065 clip_box[0].y = 0;
1051 clip_box[0].width = cursor_width; 1066 clip_box[0].width = cursor_width;
1052 clip_box[0].height = height; 1067 clip_box[0].height = height;
1053 1068
1054 XSetClipRectangles (dpy, cgc, cursor_start, dl->ypos - dl->ascent, 1069 XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl),
1055 clip_box, 1, Unsorted); 1070 clip_box, 1, Unsorted);
1056 1071
1057 if (runs[i].dimension == 1) 1072 if (runs[i].dimension == 1)
1058 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, 1073 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos,
1059 (char *) runs[i].ptr, runs[i].len); 1074 (char *) runs[i].ptr, runs[i].len);
1109 Qnil, Qnil, Qnil); 1124 Qnil, Qnil, Qnil);
1110 } 1125 }
1111 1126
1112 tmp_y = dl->ypos - bogusly_obtained_ascent_value; 1127 tmp_y = dl->ypos - bogusly_obtained_ascent_value;
1113 tmp_height = cursor_height; 1128 tmp_height = cursor_height;
1114 if (tmp_y + tmp_height > (int) (dl->ypos - dl->ascent + height)) 1129 if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height))
1115 { 1130 {
1116 tmp_y = dl->ypos - dl->ascent + height - tmp_height; 1131 tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height;
1117 if (tmp_y < (int) (dl->ypos - dl->ascent)) 1132 if (tmp_y < (int) DISPLAY_LINE_YPOS (dl))
1118 tmp_y = dl->ypos - dl->ascent; 1133 tmp_y = DISPLAY_LINE_YPOS (dl);
1119 tmp_height = dl->ypos - dl->ascent + height - tmp_y; 1134 tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y;
1120 } 1135 }
1121 1136
1122 if (need_clipping) 1137 if (need_clipping)
1123 { 1138 {
1124 XRectangle clip_box[1]; 1139 XRectangle clip_box[1];
1149 } 1164 }
1150 } 1165 }
1151 } 1166 }
1152 1167
1153 void 1168 void
1154 x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x, 1169 x_output_x_pixmap (struct frame *f, Lisp_Image_Instance *p, int x,
1155 int y, int clip_x, int clip_y, int clip_width, 1170 int y, int xoffset, int yoffset,
1156 int clip_height, int width, int height, int pixmap_offset, 1171 int width, int height, unsigned long fg, unsigned long bg,
1157 unsigned long fg, unsigned long bg, GC override_gc) 1172 GC override_gc)
1158 { 1173 {
1159 struct device *d = XDEVICE (f->device); 1174 struct device *d = XDEVICE (f->device);
1160 Display *dpy = DEVICE_X_DISPLAY (d); 1175 Display *dpy = DEVICE_X_DISPLAY (d);
1161 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 1176 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
1162 1177
1163 GC gc; 1178 GC gc;
1164 XGCValues gcv; 1179 XGCValues gcv;
1165 unsigned long pixmap_mask; 1180 unsigned long pixmap_mask;
1166 int need_clipping = (clip_x || clip_y);
1167 1181
1168 if (!override_gc) 1182 if (!override_gc)
1169 { 1183 {
1170 memset (&gcv, ~0, sizeof (XGCValues)); 1184 memset (&gcv, ~0, sizeof (XGCValues));
1171 gcv.graphics_exposures = False; 1185 gcv.graphics_exposures = False;
1175 1189
1176 if (IMAGE_INSTANCE_X_MASK (p)) 1190 if (IMAGE_INSTANCE_X_MASK (p))
1177 { 1191 {
1178 gcv.function = GXcopy; 1192 gcv.function = GXcopy;
1179 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); 1193 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p);
1180 gcv.clip_x_origin = x; 1194 gcv.clip_x_origin = x - xoffset;
1181 gcv.clip_y_origin = y - pixmap_offset; 1195 gcv.clip_y_origin = y - yoffset;
1182 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | 1196 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin |
1183 GCClipYOrigin); 1197 GCClipYOrigin);
1184 /* 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.
1185 We could conceivably create a new clipmask by zeroing out
1186 everything outside the clip region. Is it worth it?
1187 Is it possible to get an equivalent effect by changing the 1199 Is it possible to get an equivalent effect by changing the
1188 args to XCopyArea below rather than messing with a clip box? 1200 args to XCopyArea below rather than messing with a clip box?
1189 - dkindred@cs.cmu.edu */ 1201 - dkindred@cs.cmu.edu
1190 need_clipping = 0; 1202 Yes. We don't clip at all now - andy@xemacs.org
1203 */
1191 } 1204 }
1192 1205
1193 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);
1194 } 1207 }
1195 else 1208 else
1196 { 1209 {
1197 gc = override_gc; 1210 gc = override_gc;
1198 /* 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.
1199 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
1200 one of the suggestions above. */ 1213 one of the suggestions above. */
1201 need_clipping = 0;
1202 }
1203
1204 if (need_clipping)
1205 {
1206 XRectangle clip_box[1];
1207
1208 clip_box[0].x = clip_x;
1209 clip_box[0].y = clip_y;
1210 clip_box[0].width = clip_width;
1211 clip_box[0].height = clip_height;
1212
1213 XSetClipRectangles (dpy, gc, x, y, clip_box, 1, Unsorted);
1214 } 1214 }
1215 1215
1216 /* 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
1217 XCopyPlane (1 = current foreground color, 0 = background) instead 1217 XCopyPlane (1 = current foreground color, 0 = background) instead
1218 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
1219 pixel values, instead of symbolic of fg/bg. */ 1219 pixel values, instead of symbolic of fg/bg. */
1220 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) 1220 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0)
1221 { 1221 {
1222 XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, 1222 XCopyArea (dpy,
1223 pixmap_offset, width, 1223 IMAGE_INSTANCE_X_PIXMAP_SLICE
1224 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, xoffset,
1225 yoffset, width,
1224 height, x, y); 1226 height, x, y);
1225 } 1227 }
1226 else 1228 else
1227 { 1229 {
1228 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, 1230 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE
1229 (pixmap_offset < 0 1231 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc,
1230 ? 0 1232 xoffset, yoffset, width, height, x, y, 1L);
1231 : pixmap_offset),
1232 width, height, x,
1233 (pixmap_offset < 0
1234 ? y - pixmap_offset
1235 : y),
1236 1L);
1237 }
1238
1239 if (need_clipping)
1240 {
1241 XSetClipMask (dpy, gc, None);
1242 XSetClipOrigin (dpy, gc, 0, 0);
1243 } 1233 }
1244 } 1234 }
1245 1235
1246 static void 1236 static void
1247 x_output_pixmap (struct window *w, struct display_line *dl, 1237 x_output_pixmap (struct window *w, Lisp_Object image_instance,
1248 Lisp_Object image_instance, int xpos, int xoffset, 1238 struct display_box *db, struct display_glyph_area *dga,
1249 int start_pixpos, int width, face_index findex, 1239 face_index findex, int cursor_start, int cursor_width,
1250 int cursor_start, int cursor_width, int cursor_height) 1240 int cursor_height, int bg_pixmap)
1251 { 1241 {
1252 struct frame *f = XFRAME (w->frame); 1242 struct frame *f = XFRAME (w->frame);
1253 struct device *d = XDEVICE (f->device); 1243 struct device *d = XDEVICE (f->device);
1254 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); 1244 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
1255 Lisp_Object window;
1256 1245
1257 Display *dpy = DEVICE_X_DISPLAY (d); 1246 Display *dpy = DEVICE_X_DISPLAY (d);
1258 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 1247 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
1259 int lheight = dl->ascent + dl->descent - dl->clip;
1260 int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight :
1261 IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
1262 int pwidth = min (width + xoffset, (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p));
1263 int clip_x, clip_y, clip_width, clip_height;
1264
1265 /* The pixmap_offset is used to center the pixmap on lines which are
1266 shorter than it is. This results in odd effects when scrolling
1267 pixmaps off of the bottom. Let's try not using it. */
1268 #if 0
1269 int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2;
1270 #else
1271 int pixmap_offset = 0;
1272 #endif
1273
1274 XSETWINDOW (window, w);
1275
1276 if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset)
1277 {
1278 if (start_pixpos > xpos && start_pixpos > xpos + width)
1279 return;
1280
1281 clip_x = xoffset;
1282 clip_width = width;
1283 if (start_pixpos > xpos)
1284 {
1285 clip_x += (start_pixpos - xpos);
1286 clip_width -= (start_pixpos - xpos);
1287 }
1288 }
1289 else
1290 {
1291 clip_x = 0;
1292 clip_width = 0;
1293 }
1294
1295 /* Place markers for possible future functionality (clipping the top
1296 half instead of the bottom half; think pixel scrolling). */
1297 clip_y = 0;
1298 clip_height = pheight;
1299
1300 /* Clear the area the pixmap is going into. The pixmap itself will
1301 always take care of the full width. We don't want to clear where
1302 it is going to go in order to avoid flicker. So, all we have to
1303 take care of is any area above or below the pixmap. */
1304 /* #### We take a shortcut for now. We know that since we have
1305 pixmap_offset hardwired to 0 that the pixmap is against the top
1306 edge so all we have to worry about is below it. */
1307 /* #### Unless the pixmap has a mask in which case we have to clear
1308 the whole damn thing since we can't yet clear just the area not
1309 included in the mask. */
1310 if (((int) (dl->ypos - dl->ascent + pheight) <
1311 (int) (dl->ypos + dl->descent - dl->clip))
1312 || IMAGE_INSTANCE_X_MASK (p))
1313 {
1314 int clear_x, clear_y, clear_width, clear_height;
1315
1316 if (IMAGE_INSTANCE_X_MASK (p))
1317 {
1318 clear_y = dl->ypos - dl->ascent;
1319 clear_height = lheight;
1320 }
1321 else
1322 {
1323 clear_y = dl->ypos - dl->ascent + pheight;
1324 clear_height = lheight - pheight;
1325 }
1326
1327 if (start_pixpos >= 0 && start_pixpos > xpos)
1328 {
1329 clear_x = start_pixpos;
1330 clear_width = xpos + width - start_pixpos;
1331 }
1332 else
1333 {
1334 clear_x = xpos;
1335 clear_width = width;
1336 }
1337
1338 redisplay_clear_region (window, findex, clear_x, clear_y,
1339 clear_width, clear_height);
1340 }
1341 1248
1342 /* Output the pixmap. */ 1249 /* Output the pixmap. */
1343 { 1250 {
1344 Lisp_Object tmp_pixel; 1251 Lisp_Object tmp_pixel;
1345 XColor tmp_bcolor, tmp_fcolor; 1252 XColor tmp_bcolor, tmp_fcolor;
1347 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); 1254 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
1348 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 1255 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1349 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); 1256 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
1350 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 1257 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1351 1258
1352 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,
1353 clip_y, clip_width, clip_height, 1260 dga->xoffset, dga->yoffset,
1354 pwidth, pheight, pixmap_offset, 1261 dga->width, dga->height,
1355 tmp_fcolor.pixel, tmp_bcolor.pixel, 0); 1262 tmp_fcolor.pixel, tmp_bcolor.pixel, 0);
1356 } 1263 }
1357 1264
1358 /* Draw a cursor over top of the pixmap. */ 1265 /* Draw a cursor over top of the pixmap. */
1359 if (cursor_width && cursor_height && (cursor_start >= xpos) 1266 if (cursor_width && cursor_height && (cursor_start >= db->xpos)
1360 && !NILP (w->text_cursor_visible_p) 1267 && !NILP (w->text_cursor_visible_p)
1361 && (cursor_start < xpos + pwidth)) 1268 && (cursor_start < db->xpos + dga->width))
1362 { 1269 {
1363 GC gc; 1270 GC gc;
1364 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 1271 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
1365 int y = dl->ypos - dl->ascent;
1366 struct face_cachel *cursor_cachel = 1272 struct face_cachel *cursor_cachel =
1367 WINDOW_FACE_CACHEL (w, 1273 WINDOW_FACE_CACHEL (w,
1368 get_builtin_face_cache_index 1274 get_builtin_face_cache_index
1369 (w, Vtext_cursor_face)); 1275 (w, Vtext_cursor_face));
1370 1276
1371 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);
1372 1278
1373 if (cursor_width > xpos + pwidth - cursor_start) 1279 if (cursor_width > db->xpos + dga->width - cursor_start)
1374 cursor_width = xpos + pwidth - cursor_start; 1280 cursor_width = db->xpos + dga->width - cursor_start;
1375 1281
1376 if (focus) 1282 if (focus)
1377 { 1283 {
1378 XFillRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, 1284 XFillRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width,
1379 cursor_height); 1285 cursor_height);
1380 } 1286 }
1381 else 1287 else
1382 { 1288 {
1383 XDrawRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, 1289 XDrawRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width,
1384 cursor_height); 1290 cursor_height);
1385 } 1291 }
1386 } 1292 }
1387 } 1293 }
1388 1294
1395 x_output_vertical_divider (struct window *w, int clear) 1301 x_output_vertical_divider (struct window *w, int clear)
1396 { 1302 {
1397 struct frame *f = XFRAME (w->frame); 1303 struct frame *f = XFRAME (w->frame);
1398 struct device *d = XDEVICE (f->device); 1304 struct device *d = XDEVICE (f->device);
1399 1305
1400 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f);
1401 Display *dpy = DEVICE_X_DISPLAY (d); 1306 Display *dpy = DEVICE_X_DISPLAY (d);
1402 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 1307 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
1403 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel;
1404 Lisp_Object tmp_pixel; 1308 Lisp_Object tmp_pixel;
1405 XColor tmp_color; 1309 XColor tmp_color;
1406 XGCValues gcv; 1310 XGCValues gcv;
1407 GC top_shadow_gc, bottom_shadow_gc, background_gc; 1311 GC background_gc;
1408 1312 enum edge_style style;
1409 int use_pixmap = 0; 1313
1410 int flip_gcs = 0;
1411 unsigned long mask; 1314 unsigned long mask;
1412 int x, y1, y2, width, shadow_thickness, spacing, line_width; 1315 int x, y1, y2, width, shadow_thickness, spacing, line_width;
1413 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);
1414 1317
1415 width = window_divider_width (w); 1318 width = window_divider_width (w);
1416 shadow_thickness = XINT (w->vertical_divider_shadow_thickness); 1319 shadow_thickness = XINT (w->vertical_divider_shadow_thickness);
1417 spacing = XINT (w->vertical_divider_spacing); 1320 spacing = XINT (w->vertical_divider_spacing);
1418 line_width = XINT (w->vertical_divider_line_width); 1321 line_width = XINT (w->vertical_divider_line_width);
1419 x = WINDOW_RIGHT (w) - width; 1322 x = WINDOW_RIGHT (w) - width;
1420 y1 = WINDOW_TOP (w); 1323 y1 = WINDOW_TOP (w) + FRAME_TOP_GUTTER_BOUNDS (f);
1421 y2 = WINDOW_BOTTOM (w); 1324 y2 = WINDOW_BOTTOM (w) + FRAME_BOTTOM_GUTTER_BOUNDS (f);
1422 1325
1423 memset (&gcv, ~0, sizeof (XGCValues)); 1326 memset (&gcv, ~0, sizeof (XGCValues));
1424 1327
1425 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face); 1328 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face);
1426 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); 1329 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1427 1330
1428 /* First, get the GC's. */ 1331 /* First, get the GC's. */
1429 top_shadow_pixel = tmp_color.pixel;
1430 bottom_shadow_pixel = tmp_color.pixel;
1431 background_pixel = tmp_color.pixel;
1432
1433 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel,
1434 background_pixel, ef->core.background_pixel);
1435
1436 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, div_face);
1437 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1438 gcv.background = tmp_color.pixel; 1332 gcv.background = tmp_color.pixel;
1333 gcv.foreground = tmp_color.pixel;
1439 gcv.graphics_exposures = False; 1334 gcv.graphics_exposures = False;
1440 mask = GCForeground | GCBackground | GCGraphicsExposures; 1335 mask = GCForeground | GCBackground | GCGraphicsExposures;
1441
1442 /* If we can't distinguish one of the shadows (the color is the same as the
1443 background), it's better to use a pixmap to generate a dithered gray. */
1444 if (top_shadow_pixel == background_pixel ||
1445 bottom_shadow_pixel == background_pixel)
1446 use_pixmap = 1;
1447
1448 if (use_pixmap)
1449 {
1450 if (DEVICE_X_GRAY_PIXMAP (d) == None)
1451 {
1452 DEVICE_X_GRAY_PIXMAP (d) =
1453 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits,
1454 gray_width, gray_height, 1, 0, 1);
1455 }
1456
1457 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face);
1458 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1459 gcv.foreground = tmp_color.pixel;
1460 /* this is needed because the GC draws with a pixmap here */
1461 gcv.fill_style = FillOpaqueStippled;
1462 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d);
1463 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv,
1464 (mask | GCStipple | GCFillStyle));
1465
1466 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, div_face);
1467 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
1468 bottom_shadow_pixel = tmp_color.pixel;
1469
1470 flip_gcs = (bottom_shadow_pixel ==
1471 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy)));
1472 }
1473 else
1474 {
1475 gcv.foreground = top_shadow_pixel;
1476 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask);
1477 }
1478
1479 gcv.foreground = bottom_shadow_pixel;
1480 bottom_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask);
1481
1482 if (use_pixmap && flip_gcs)
1483 {
1484 GC tmp_gc = bottom_shadow_gc;
1485 bottom_shadow_gc = top_shadow_gc;
1486 top_shadow_gc = tmp_gc;
1487 }
1488
1489 gcv.foreground = background_pixel;
1490 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); 1336 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask);
1491
1492 /* possibly revert the GC's in case the shadow thickness is < 0.
1493 This will give a depressed look to the divider */
1494 if (shadow_thickness < 0)
1495 {
1496 GC temp;
1497
1498 temp = top_shadow_gc;
1499 top_shadow_gc = bottom_shadow_gc;
1500 bottom_shadow_gc = temp;
1501
1502 /* better avoid a Bad Address XLib error ;-) */
1503 shadow_thickness = - shadow_thickness;
1504 }
1505 1337
1506 /* Clear the divider area first. This needs to be done when a 1338 /* Clear the divider area first. This needs to be done when a
1507 window split occurs. */ 1339 window split occurs. */
1508 if (clear) 1340 if (clear)
1509 XClearArea (dpy, x_win, x, y1, width, y2 - y1, False); 1341 XClearArea (dpy, x_win, x, y1, width, y2 - y1, False);
1511 /* Draw the divider line. */ 1343 /* Draw the divider line. */
1512 XFillRectangle (dpy, x_win, background_gc, 1344 XFillRectangle (dpy, x_win, background_gc,
1513 x + spacing + shadow_thickness, y1, 1345 x + spacing + shadow_thickness, y1,
1514 line_width, y2 - y1); 1346 line_width, y2 - y1);
1515 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
1516 /* Draw the shadows around the divider line */ 1358 /* Draw the shadows around the divider line */
1517 x_output_shadows (f, x + spacing, y1, 1359 x_bevel_area (w, div_face, x + spacing, y1,
1518 width - 2 * spacing, y2 - y1, 1360 width - 2 * spacing, y2 - y1,
1519 top_shadow_gc, bottom_shadow_gc, 1361 shadow_thickness, EDGE_ALL, style);
1520 background_gc, shadow_thickness);
1521 } 1362 }
1522 1363
1523 /***************************************************************************** 1364 /*****************************************************************************
1524 x_output_blank 1365 x_output_blank
1525 1366
1544 Lisp_Object buffer = WINDOW_BUFFER (w); 1385 Lisp_Object buffer = WINDOW_BUFFER (w);
1545 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, 1386 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor,
1546 buffer); 1387 buffer);
1547 1388
1548 int x = rb->xpos; 1389 int x = rb->xpos;
1549 int y = dl->ypos - dl->ascent; 1390 int y = DISPLAY_LINE_YPOS (dl);
1550 int width = rb->width; 1391 int width = rb->width;
1551 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);
1552 1396
1553 if (start_pixpos > x) 1397 if (start_pixpos > x)
1554 { 1398 {
1555 if (start_pixpos >= (x + width)) 1399 if (start_pixpos >= (x + width))
1556 return; 1400 return;
1584 && (cursor_start + cursor_width > x) 1428 && (cursor_start + cursor_width > x)
1585 && cursor_start < (x + width)))) 1429 && cursor_start < (x + width))))
1586 { 1430 {
1587 int cursor_height, cursor_y; 1431 int cursor_height, cursor_y;
1588 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 1432 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
1589 struct Lisp_Font_Instance *fi; 1433 Lisp_Font_Instance *fi;
1590 1434
1591 fi = XFONT_INSTANCE (FACE_CACHEL_FONT 1435 fi = XFONT_INSTANCE (FACE_CACHEL_FONT
1592 (WINDOW_FACE_CACHEL (w, rb->findex), 1436 (WINDOW_FACE_CACHEL (w, rb->findex),
1593 Vcharset_ascii)); 1437 Vcharset_ascii));
1594 1438
1640 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 1484 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
1641 GC gc; 1485 GC gc;
1642 1486
1643 int x = rb->xpos; 1487 int x = rb->xpos;
1644 int width = rb->width; 1488 int width = rb->width;
1645 int height = dl->ascent + dl->descent - dl->clip; 1489 int height = DISPLAY_LINE_HEIGHT (dl);
1646 int ypos1, ypos2, ypos3, ypos4; 1490 int ypos1, ypos2, ypos3, ypos4;
1647 1491
1648 ypos1 = dl->ypos - dl->ascent; 1492 ypos1 = DISPLAY_LINE_YPOS (dl);
1649 ypos2 = ypos1 + rb->object.hline.yoffset; 1493 ypos2 = ypos1 + rb->object.hline.yoffset;
1650 ypos3 = ypos2 + rb->object.hline.thickness; 1494 ypos3 = ypos2 + rb->object.hline.thickness;
1651 ypos4 = dl->ypos + dl->descent - dl->clip; 1495 ypos4 = dl->ypos + dl->descent - dl->clip;
1652 1496
1653 /* First clear the area not covered by the line. */ 1497 /* First clear the area not covered by the line. */
1682 callers responsibility to set the GC's appropriately. 1526 callers responsibility to set the GC's appropriately.
1683 ****************************************************************************/ 1527 ****************************************************************************/
1684 void 1528 void
1685 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,
1686 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, 1530 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc,
1687 int shadow_thickness) 1531 int shadow_thickness, int edges)
1688 { 1532 {
1689 struct device *d = XDEVICE (f->device); 1533 struct device *d = XDEVICE (f->device);
1690 1534
1691 Display *dpy = DEVICE_X_DISPLAY (d); 1535 Display *dpy = DEVICE_X_DISPLAY (d);
1692 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); 1536 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
1704 shadow_thickness = height / 2; 1548 shadow_thickness = height / 2;
1705 1549
1706 for (elt = 0; elt < shadow_thickness; elt++) 1550 for (elt = 0; elt < shadow_thickness; elt++)
1707 { 1551 {
1708 int seg1 = elt; 1552 int seg1 = elt;
1709 int seg2 = elt + shadow_thickness; 1553 int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt;
1710 1554 int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt;
1711 top_shadow[seg1].x1 = x; 1555
1712 top_shadow[seg1].x2 = x + width - elt - 1; 1556 if (edges & EDGE_TOP)
1713 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; 1557 {
1714 1558 top_shadow[seg1].x1 = x + elt;
1715 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; 1559 top_shadow[seg1].x2 = x + width - elt - 1;
1716 top_shadow[seg2].y1 = y + shadow_thickness; 1560 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt;
1717 top_shadow[seg2].y2 = y + height - elt - 1; 1561 }
1718 1562 if (edges & EDGE_LEFT)
1719 bottom_shadow[seg1].x1 = x + elt + 1; 1563 {
1720 bottom_shadow[seg1].x2 = x + width - 1; 1564 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt;
1721 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; 1565 top_shadow[seg2].y1 = y + elt;
1722 1566 top_shadow[seg2].y2 = y + height - elt - 1;
1723 bottom_shadow[seg2].x1 = bottom_shadow[seg2].x2 = x + width - elt - 1; 1567 }
1724 bottom_shadow[seg2].y1 = y + elt + 1; 1568 if (edges & EDGE_BOTTOM)
1725 bottom_shadow[seg2].y2 = y + height - shadow_thickness; 1569 {
1726 } 1570 bottom_shadow[seg1].x1 = x + elt;
1727 1571 bottom_shadow[seg1].x2 = x + width - elt - 1;
1728 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));
1729 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, 1585 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow,
1730 shadow_thickness * 2); 1586 ((edges & EDGE_BOTTOM) ? shadow_thickness : 0)
1587 + ((edges & EDGE_RIGHT) ? shadow_thickness : 0));
1731 } 1588 }
1732 1589
1733 /***************************************************************************** 1590 /*****************************************************************************
1734 x_generate_shadow_pixels 1591 x_generate_shadow_pixels
1735 1592
1809 if (botc.pixel == background) 1666 if (botc.pixel == background)
1810 *top_shadow = core_background; 1667 *top_shadow = core_background;
1811 else 1668 else
1812 *bottom_shadow = background; 1669 *bottom_shadow = background;
1813 } 1670 }
1814 }
1815 }
1816
1817 /*****************************************************************************
1818 x_clear_to_window_end
1819
1820 Clear the area between ypos1 and ypos2. Each margin area and the
1821 text area is handled separately since they may each have their own
1822 background color.
1823 ****************************************************************************/
1824 static void
1825 x_clear_to_window_end (struct window *w, int ypos1, int ypos2)
1826 {
1827 int height = ypos2 - ypos1;
1828
1829 if (height)
1830 {
1831 struct frame *f = XFRAME (w->frame);
1832 Lisp_Object window;
1833 int bflag = (window_needs_vertical_divider (w) ? 0 : 1);
1834 layout_bounds bounds;
1835
1836 bounds = calculate_display_line_boundaries (w, bflag);
1837 XSETWINDOW (window, w);
1838
1839 if (window_is_leftmost (w))
1840 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
1841 ypos1, FRAME_BORDER_WIDTH (f), height);
1842
1843 if (bounds.left_in - bounds.left_out > 0)
1844 redisplay_clear_region (window,
1845 get_builtin_face_cache_index (w, Vleft_margin_face),
1846 bounds.left_out, ypos1,
1847 bounds.left_in - bounds.left_out, height);
1848
1849 if (bounds.right_in - bounds.left_in > 0)
1850 redisplay_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
1851 bounds.right_in - bounds.left_in, height);
1852
1853 if (bounds.right_out - bounds.right_in > 0)
1854 redisplay_clear_region (window,
1855 get_builtin_face_cache_index (w, Vright_margin_face),
1856 bounds.right_in, ypos1,
1857 bounds.right_out - bounds.right_in, height);
1858
1859 if (window_is_rightmost (w))
1860 redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
1861 ypos1, FRAME_BORDER_WIDTH (f), height);
1862 } 1671 }
1863 } 1672 }
1864 1673
1865 /***************************************************************************** 1674 /*****************************************************************************
1866 x_redraw_exposed_window 1675 x_redraw_exposed_window
1977 /* #### We would rather put these off as well but there is currently 1786 /* #### We would rather put these off as well but there is currently
1978 no combination of flags which will force an unchanged toolbar to 1787 no combination of flags which will force an unchanged toolbar to
1979 redraw anyhow. */ 1788 redraw anyhow. */
1980 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); 1789 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height));
1981 #endif 1790 #endif
1791 redraw_exposed_gutters (f, x, y, width, height);
1982 1792
1983 if (!f->window_face_cache_reset) 1793 if (!f->window_face_cache_reset)
1984 { 1794 {
1985 x_redraw_exposed_windows (f->root_window, x, y, width, height); 1795 x_redraw_exposed_windows (f->root_window, x, y, width, height);
1986 1796
2043 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); 1853 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
2044 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, 1854 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor,
2045 WINDOW_BUFFER (w)); 1855 WINDOW_BUFFER (w));
2046 1856
2047 int x = xpos; 1857 int x = xpos;
2048 int y = dl->ypos - dl->ascent; 1858 int y = DISPLAY_LINE_YPOS (dl);
2049 int width = EOL_CURSOR_WIDTH; 1859 int width = EOL_CURSOR_WIDTH;
2050 int height = dl->ascent + dl->descent - dl->clip; 1860 int height = DISPLAY_LINE_HEIGHT (dl);
2051 int cursor_height, cursor_y; 1861 int cursor_height, cursor_y;
2052 int defheight, defascent; 1862 int defheight, defascent;
2053 1863
2054 XSETWINDOW (window, w); 1864 XSETWINDOW (window, w);
2055 redisplay_clear_region (window, findex, x, y, width, height); 1865 redisplay_clear_region (window, findex, x, y, width, height);
2108 { 1918 {
2109 x_clear_frame_windows (w->hchild); 1919 x_clear_frame_windows (w->hchild);
2110 return; 1920 return;
2111 } 1921 }
2112 1922
2113 x_clear_to_window_end (w, WINDOW_TEXT_TOP (w), WINDOW_TEXT_BOTTOM (w)); 1923 redisplay_clear_to_window_end (w, WINDOW_TEXT_TOP (w),
1924 WINDOW_TEXT_BOTTOM (w));
2114 } 1925 }
2115 1926
2116 static void 1927 static void
2117 x_clear_frame_windows (Lisp_Object window) 1928 x_clear_frame_windows (Lisp_Object window)
2118 { 1929 {
2265 CONSOLE_HAS_METHOD (x, text_width); 2076 CONSOLE_HAS_METHOD (x, text_width);
2266 CONSOLE_HAS_METHOD (x, output_display_block); 2077 CONSOLE_HAS_METHOD (x, output_display_block);
2267 CONSOLE_HAS_METHOD (x, divider_height); 2078 CONSOLE_HAS_METHOD (x, divider_height);
2268 CONSOLE_HAS_METHOD (x, eol_cursor_width); 2079 CONSOLE_HAS_METHOD (x, eol_cursor_width);
2269 CONSOLE_HAS_METHOD (x, output_vertical_divider); 2080 CONSOLE_HAS_METHOD (x, output_vertical_divider);
2270 CONSOLE_HAS_METHOD (x, clear_to_window_end);
2271 CONSOLE_HAS_METHOD (x, clear_region); 2081 CONSOLE_HAS_METHOD (x, clear_region);
2272 CONSOLE_HAS_METHOD (x, clear_frame); 2082 CONSOLE_HAS_METHOD (x, clear_frame);
2273 CONSOLE_HAS_METHOD (x, output_begin); 2083 CONSOLE_HAS_METHOD (x, output_begin);
2274 CONSOLE_HAS_METHOD (x, output_end); 2084 CONSOLE_HAS_METHOD (x, output_end);
2275 CONSOLE_HAS_METHOD (x, flash); 2085 CONSOLE_HAS_METHOD (x, flash);
2276 CONSOLE_HAS_METHOD (x, ring_bell); 2086 CONSOLE_HAS_METHOD (x, ring_bell);
2277 } 2087 CONSOLE_HAS_METHOD (x, bevel_area);
2088 CONSOLE_HAS_METHOD (x, output_string);
2089 CONSOLE_HAS_METHOD (x, output_pixmap);
2090 }