Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | 501cfd01ee6d |
children | e804706bfb8c |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
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" | |
44 #include "redisplay.h" | 43 #include "redisplay.h" |
45 #include "sysdep.h" | 44 #include "sysdep.h" |
46 #include "window.h" | 45 #include "window.h" |
47 #include <X11/bitmaps/gray> | 46 #include <X11/bitmaps/gray> |
48 | 47 |
52 #include "mule-ccl.h" | 51 #include "mule-ccl.h" |
53 #include "file-coding.h" /* for CCL conversion */ | 52 #include "file-coding.h" /* for CCL conversion */ |
54 #endif | 53 #endif |
55 | 54 |
56 /* Number of pixels below each line. */ | 55 /* Number of pixels below each line. */ |
57 int x_interline_space; /* #### implement me */ | 56 /* #### 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); | |
61 static void x_output_vertical_divider (struct window *w, int clear); | 67 static void x_output_vertical_divider (struct window *w, int clear); |
62 static void x_output_blank (struct window *w, struct display_line *dl, | 68 static void x_output_blank (struct window *w, struct display_line *dl, |
63 struct rune *rb, int start_pixpos, | 69 struct rune *rb, int start_pixpos, |
64 int cursor_start, int cursor_width); | 70 int cursor_start, int cursor_width); |
65 static void x_output_hline (struct window *w, struct display_line *dl, | 71 static void x_output_hline (struct window *w, struct display_line *dl, |
70 int width, int height); | 76 int width, int height); |
71 static void x_output_eol_cursor (struct window *w, struct display_line *dl, | 77 static void x_output_eol_cursor (struct window *w, struct display_line *dl, |
72 int xpos, face_index findex); | 78 int xpos, face_index findex); |
73 static void x_clear_frame (struct frame *f); | 79 static void x_clear_frame (struct frame *f); |
74 static void x_clear_frame_windows (Lisp_Object window); | 80 static void x_clear_frame_windows (Lisp_Object window); |
81 static void x_bevel_modeline (struct window *w, struct display_line *dl); | |
75 | 82 |
76 | 83 |
77 /* Note: We do not use the Xmb*() functions and XFontSets. | 84 /* Note: We do not use the Xmb*() functions and XFontSets. |
78 Those functions are generally losing for a number of reasons: | 85 Those functions are generally losing for a number of reasons: |
79 | 86 |
121 Returns the number of runs actually used. */ | 128 Returns the number of runs actually used. */ |
122 | 129 |
123 static int | 130 static int |
124 separate_textual_runs (unsigned char *text_storage, | 131 separate_textual_runs (unsigned char *text_storage, |
125 struct textual_run *run_storage, | 132 struct textual_run *run_storage, |
126 const Emchar *str, Charcount len) | 133 CONST Emchar *str, Charcount len) |
127 { | 134 { |
128 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a | 135 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a |
129 possible valid charset when | 136 possible valid charset when |
130 MULE is not defined */ | 137 MULE is not defined */ |
131 int runs_so_far = 0; | 138 int runs_so_far = 0; |
186 if (need_ccl_conversion) | 193 if (need_ccl_conversion) |
187 { | 194 { |
188 char_converter.reg[0] = XCHARSET_ID (charset); | 195 char_converter.reg[0] = XCHARSET_ID (charset); |
189 char_converter.reg[1] = byte1; | 196 char_converter.reg[1] = byte1; |
190 char_converter.reg[2] = byte2; | 197 char_converter.reg[2] = byte2; |
191 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); | 198 ccl_driver (&char_converter, 0, 0, 0, 0); |
192 byte1 = char_converter.reg[1]; | 199 byte1 = char_converter.reg[1]; |
193 byte2 = char_converter.reg[2]; | 200 byte2 = char_converter.reg[2]; |
194 } | 201 } |
195 #endif | 202 #endif |
196 *text_storage++ = (unsigned char) byte1; | 203 *text_storage++ = (unsigned char) byte1; |
217 | 224 |
218 static int | 225 static int |
219 x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run) | 226 x_text_width_single_run (struct face_cachel *cachel, struct textual_run *run) |
220 { | 227 { |
221 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); | 228 Lisp_Object font_inst = FACE_CACHEL_FONT (cachel, run->charset); |
222 Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); | 229 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font_inst); |
223 if (!fi->proportional_p) | 230 if (!fi->proportional_p) |
224 return fi->width * run->len; | 231 return fi->width * run->len; |
225 else | 232 else |
226 { | 233 { |
227 if (run->dimension == 2) | 234 if (run->dimension == 2) |
239 Given a string and a face, return the string's length in pixels when | 246 Given a string and a face, return the string's length in pixels when |
240 displayed in the font associated with the face. | 247 displayed in the font associated with the face. |
241 */ | 248 */ |
242 | 249 |
243 static int | 250 static int |
244 x_text_width (struct frame *f, struct face_cachel *cachel, const Emchar *str, | 251 x_text_width (struct frame *f, struct face_cachel *cachel, CONST Emchar *str, |
245 Charcount len) | 252 Charcount len) |
246 { | 253 { |
247 int width_so_far = 0; | 254 int width_so_far = 0; |
248 unsigned char *text_storage = (unsigned char *) alloca (2 * len); | 255 unsigned char *text_storage = (unsigned char *) alloca (2 * len); |
249 struct textual_run *runs = alloca_array (struct textual_run, len); | 256 struct textual_run *runs = alloca_array (struct textual_run, len); |
284 { | 291 { |
285 return EOL_CURSOR_WIDTH; | 292 return EOL_CURSOR_WIDTH; |
286 } | 293 } |
287 | 294 |
288 /***************************************************************************** | 295 /***************************************************************************** |
289 x_window_output_begin | 296 x_output_begin |
290 | 297 |
291 Perform any necessary initialization prior to an update. | 298 Perform any necessary initialization prior to an update. |
292 ****************************************************************************/ | 299 ****************************************************************************/ |
293 static void | 300 static void |
294 x_window_output_begin (struct window *w) | 301 x_output_begin (struct device *d) |
295 { | 302 { |
296 } | 303 } |
297 | 304 |
298 /***************************************************************************** | 305 /***************************************************************************** |
299 x_window_output_end | 306 x_output_end |
300 | 307 |
301 Perform any necessary flushing of queues when an update has completed. | 308 Perform any necessary flushing of queues when an update has completed. |
302 ****************************************************************************/ | 309 ****************************************************************************/ |
303 static void | 310 static void |
304 x_window_output_end (struct window *w) | 311 x_output_end (struct device *d) |
305 { | 312 { |
306 XFlush (DEVICE_X_DISPLAY (WINDOW_XDEVICE (w))); | 313 XFlush (DEVICE_X_DISPLAY (d)); |
307 } | 314 } |
308 | 315 |
309 /***************************************************************************** | 316 /***************************************************************************** |
310 x_output_display_block | 317 x_output_display_block |
311 | 318 |
325 rune_dynarr *rba = db->runes; | 332 rune_dynarr *rba = db->runes; |
326 struct rune *rb; | 333 struct rune *rb; |
327 | 334 |
328 int elt = start; | 335 int elt = start; |
329 face_index findex; | 336 face_index findex; |
330 int xpos, width = 0; | 337 int xpos, width; |
331 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when | 338 Lisp_Object charset = Qunbound; /* Qnil is a valid charset when |
332 MULE is not defined */ | 339 MULE is not defined */ |
333 | 340 |
334 XSETWINDOW (window, w); | 341 XSETWINDOW (window, w); |
335 rb = Dynarr_atp (rba, start); | 342 rb = Dynarr_atp (rba, start); |
336 | 343 |
337 if (!rb) | 344 if (!rb) |
338 /* Nothing to do so don't do anything. */ | 345 { |
339 return; | 346 /* Nothing to do so don't do anything. */ |
340 | 347 return; |
341 findex = rb->findex; | 348 } |
342 xpos = rb->xpos; | 349 else |
343 if (rb->type == RUNE_CHAR) | 350 { |
344 charset = CHAR_CHARSET (rb->object.chr.ch); | 351 findex = rb->findex; |
352 xpos = rb->xpos; | |
353 width = 0; | |
354 if (rb->type == RUNE_CHAR) | |
355 charset = CHAR_CHARSET (rb->object.chr.ch); | |
356 } | |
345 | 357 |
346 if (end < 0) | 358 if (end < 0) |
347 end = Dynarr_length (rba); | 359 end = Dynarr_length (rba); |
348 Dynarr_reset (buf); | 360 Dynarr_reset (buf); |
349 | 361 |
398 elt++; | 410 elt++; |
399 } | 411 } |
400 else if (rb->object.chr.ch == '\n') | 412 else if (rb->object.chr.ch == '\n') |
401 { | 413 { |
402 /* Clear in case a cursor was formerly here. */ | 414 /* Clear in case a cursor was formerly here. */ |
403 redisplay_clear_region (window, findex, xpos, | 415 int height = dl->ascent + dl->descent - dl->clip; |
404 DISPLAY_LINE_YPOS (dl), | 416 |
405 rb->width, | 417 redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent, |
406 DISPLAY_LINE_HEIGHT (dl)); | 418 rb->width, height); |
407 elt++; | 419 elt++; |
408 } | 420 } |
409 } | 421 } |
410 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) | 422 else if (rb->type == RUNE_BLANK || rb->type == RUNE_HLINE) |
411 { | 423 { |
435 } | 447 } |
436 } | 448 } |
437 else if (rb->type == RUNE_DGLYPH) | 449 else if (rb->type == RUNE_DGLYPH) |
438 { | 450 { |
439 Lisp_Object instance; | 451 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); | |
445 | 452 |
446 XSETWINDOW (window, w); | 453 XSETWINDOW (window, w); |
447 instance = glyph_image_instance (rb->object.dglyph.glyph, | 454 instance = glyph_image_instance (rb->object.dglyph.glyph, |
448 window, ERROR_ME_NOT, 1); | 455 window, ERROR_ME_NOT, 1); |
449 findex = rb->findex; | 456 findex = rb->findex; |
450 | 457 |
451 if (IMAGE_INSTANCEP (instance)) | 458 if (IMAGE_INSTANCEP (instance)) |
452 { | 459 switch (XIMAGE_INSTANCE_TYPE (instance)) |
453 switch (XIMAGE_INSTANCE_TYPE (instance)) | 460 { |
461 case IMAGE_TEXT: | |
454 { | 462 { |
455 case IMAGE_MONO_PIXMAP: | 463 /* #### This is way losing. See the comment in |
456 case IMAGE_COLOR_PIXMAP: | 464 add_glyph_rune(). */ |
457 redisplay_output_pixmap (w, instance, &dbox, &dga, findex, | 465 Lisp_Object string = |
458 cursor_start, cursor_width, | 466 XIMAGE_INSTANCE_TEXT_STRING (instance); |
459 cursor_height, 0); | 467 convert_bufbyte_string_into_emchar_dynarr |
460 break; | 468 (XSTRING_DATA (string), XSTRING_LENGTH (string), buf); |
461 | 469 |
462 case IMAGE_WIDGET: | 470 x_output_string (w, dl, buf, xpos, |
463 if (EQ (XIMAGE_INSTANCE_WIDGET_TYPE (instance), | 471 rb->object.dglyph.xoffset, |
464 Qlayout)) | 472 start_pixpos, -1, findex, |
465 { | 473 (rb->cursor_type == CURSOR_ON), |
466 redisplay_output_layout (w, instance, &dbox, &dga, findex, | 474 cursor_start, cursor_width, |
467 cursor_start, cursor_width, | 475 cursor_height); |
468 cursor_height); | 476 Dynarr_reset (buf); |
469 break; | |
470 } | |
471 case IMAGE_SUBWINDOW: | |
472 redisplay_output_subwindow (w, instance, &dbox, &dga, findex, | |
473 cursor_start, cursor_width, | |
474 cursor_height); | |
475 break; | |
476 | |
477 case IMAGE_NOTHING: | |
478 /* nothing is as nothing does */ | |
479 break; | |
480 | |
481 case IMAGE_TEXT: | |
482 case IMAGE_POINTER: | |
483 default: | |
484 abort (); | |
485 } | 477 } |
486 IMAGE_INSTANCE_OPTIMIZE_OUTPUT | 478 break; |
487 (XIMAGE_INSTANCE (instance)) = 0; | 479 |
488 } | 480 case IMAGE_MONO_PIXMAP: |
481 case IMAGE_COLOR_PIXMAP: | |
482 x_output_pixmap (w, dl, instance, xpos, | |
483 rb->object.dglyph.xoffset, start_pixpos, | |
484 rb->width, findex, cursor_start, | |
485 cursor_width, cursor_height); | |
486 break; | |
487 | |
488 case IMAGE_POINTER: | |
489 abort (); | |
490 | |
491 case IMAGE_WIDGET: | |
492 case IMAGE_SUBWINDOW: | |
493 redisplay_output_subwindow (w, dl, instance, xpos, | |
494 rb->object.dglyph.xoffset, start_pixpos, | |
495 rb->width, findex, cursor_start, | |
496 cursor_width, cursor_height); | |
497 | |
498 case IMAGE_NOTHING: | |
499 /* nothing is as nothing does */ | |
500 break; | |
501 | |
502 default: | |
503 abort (); | |
504 } | |
489 | 505 |
490 xpos += rb->width; | 506 xpos += rb->width; |
491 elt++; | 507 elt++; |
492 } | 508 } |
493 else | 509 else |
504 if (dl->modeline | 520 if (dl->modeline |
505 && !EQ (Qzero, w->modeline_shadow_thickness) | 521 && !EQ (Qzero, w->modeline_shadow_thickness) |
506 && (f->clear | 522 && (f->clear |
507 || f->windows_structure_changed | 523 || f->windows_structure_changed |
508 || w->shadow_thickness_changed)) | 524 || w->shadow_thickness_changed)) |
509 bevel_modeline (w, dl); | 525 x_bevel_modeline (w, dl); |
510 | 526 |
511 Dynarr_free (buf); | 527 Dynarr_free (buf); |
512 } | 528 } |
513 | 529 |
514 /***************************************************************************** | 530 /***************************************************************************** |
515 x_bevel_area | 531 x_bevel_modeline |
516 | 532 |
517 Draw a shadows for the given area in the given face. | 533 Draw a 3d border around the modeline on window W. |
518 ****************************************************************************/ | 534 ****************************************************************************/ |
519 static void | 535 static void |
520 x_bevel_area (struct window *w, face_index findex, | 536 x_bevel_modeline (struct window *w, struct display_line *dl) |
521 int x, int y, int width, int height, | |
522 int shadow_thickness, int edges, enum edge_style style) | |
523 { | 537 { |
524 struct frame *f = XFRAME (w->frame); | 538 struct frame *f = XFRAME (w->frame); |
525 struct device *d = XDEVICE (f->device); | 539 struct device *d = XDEVICE (f->device); |
526 | |
527 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
528 Display *dpy = DEVICE_X_DISPLAY (d); | 540 Display *dpy = DEVICE_X_DISPLAY (d); |
529 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); | |
543 GC top_shadow_gc, bottom_shadow_gc, background_gc; | |
530 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; | 544 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; |
545 XColor tmp_color; | |
531 Lisp_Object tmp_pixel; | 546 Lisp_Object tmp_pixel; |
532 XColor tmp_color; | 547 int x, y, width, height; |
533 XGCValues gcv; | 548 XGCValues gcv; |
534 GC top_shadow_gc, bottom_shadow_gc, background_gc; | 549 unsigned long mask; |
535 | |
536 int use_pixmap = 0; | 550 int use_pixmap = 0; |
537 int flip_gcs = 0; | 551 int flip_gcs = 0; |
538 unsigned long mask; | 552 int shadow_thickness; |
539 | 553 |
540 assert (shadow_thickness >=0); | |
541 memset (&gcv, ~0, sizeof (XGCValues)); | 554 memset (&gcv, ~0, sizeof (XGCValues)); |
542 | 555 |
543 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 556 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); |
544 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 557 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
545 | 558 |
546 /* First, get the GC's. */ | 559 /* First, get the GC's. */ |
547 top_shadow_pixel = tmp_color.pixel; | 560 top_shadow_pixel = tmp_color.pixel; |
548 bottom_shadow_pixel = tmp_color.pixel; | 561 bottom_shadow_pixel = tmp_color.pixel; |
549 background_pixel = tmp_color.pixel; | 562 background_pixel = tmp_color.pixel; |
550 | 563 |
551 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel, | 564 x_generate_shadow_pixels (f, &top_shadow_pixel, &bottom_shadow_pixel, |
552 background_pixel, ef->core.background_pixel); | 565 background_pixel, ef->core.background_pixel); |
553 | 566 |
554 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | 567 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX); |
555 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 568 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
556 gcv.background = tmp_color.pixel; | 569 gcv.background = tmp_color.pixel; |
557 gcv.graphics_exposures = False; | 570 gcv.graphics_exposures = False; |
558 mask = GCForeground | GCBackground | GCGraphicsExposures; | 571 mask = GCForeground | GCBackground | GCGraphicsExposures; |
559 | 572 |
560 /* If we can't distinguish one of the shadows (the color is the same as the | |
561 background), it's better to use a pixmap to generate a dithered gray. */ | |
562 if (top_shadow_pixel == background_pixel || | 573 if (top_shadow_pixel == background_pixel || |
563 bottom_shadow_pixel == background_pixel) | 574 bottom_shadow_pixel == background_pixel) |
564 use_pixmap = 1; | 575 use_pixmap = 1; |
565 | 576 |
566 if (use_pixmap) | 577 if (use_pixmap) |
570 DEVICE_X_GRAY_PIXMAP (d) = | 581 DEVICE_X_GRAY_PIXMAP (d) = |
571 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits, | 582 XCreatePixmapFromBitmapData (dpy, x_win, (char *) gray_bits, |
572 gray_width, gray_height, 1, 0, 1); | 583 gray_width, gray_height, 1, 0, 1); |
573 } | 584 } |
574 | 585 |
575 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 586 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, MODELINE_INDEX); |
576 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 587 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
577 gcv.foreground = tmp_color.pixel; | 588 gcv.foreground = tmp_color.pixel; |
578 /* this is needed because the GC draws with a pixmap here */ | |
579 gcv.fill_style = FillOpaqueStippled; | 589 gcv.fill_style = FillOpaqueStippled; |
580 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d); | 590 gcv.stipple = DEVICE_X_GRAY_PIXMAP (d); |
581 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, | 591 top_shadow_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, |
582 (mask | GCStipple | GCFillStyle)); | 592 (mask | GCStipple | GCFillStyle)); |
583 | 593 |
584 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | 594 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, MODELINE_INDEX); |
585 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 595 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
586 bottom_shadow_pixel = tmp_color.pixel; | 596 bottom_shadow_pixel = tmp_color.pixel; |
587 | 597 |
588 flip_gcs = (bottom_shadow_pixel == | 598 flip_gcs = (bottom_shadow_pixel == |
589 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy))); | 599 WhitePixelOfScreen (DefaultScreenOfDisplay (dpy))); |
605 } | 615 } |
606 | 616 |
607 gcv.foreground = background_pixel; | 617 gcv.foreground = background_pixel; |
608 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | 618 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); |
609 | 619 |
610 /* possibly revert the GC's This will give a depressed look to the | 620 if (XINT (w->modeline_shadow_thickness) < 0) |
611 divider */ | |
612 if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN) | |
613 { | 621 { |
614 GC temp; | 622 GC temp; |
615 | 623 |
616 temp = top_shadow_gc; | 624 temp = top_shadow_gc; |
617 top_shadow_gc = bottom_shadow_gc; | 625 top_shadow_gc = bottom_shadow_gc; |
618 bottom_shadow_gc = temp; | 626 bottom_shadow_gc = temp; |
619 } | 627 } |
620 | 628 |
621 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) | 629 shadow_thickness = MODELINE_SHADOW_THICKNESS (w); |
622 shadow_thickness /= 2; | 630 |
623 | 631 x = WINDOW_MODELINE_LEFT (w); |
624 /* Draw the shadows around the divider line */ | 632 width = WINDOW_MODELINE_RIGHT (w) - x; |
625 x_output_shadows (f, x, y, width, height, | 633 y = dl->ypos - dl->ascent - shadow_thickness; |
626 top_shadow_gc, bottom_shadow_gc, | 634 height = dl->ascent + dl->descent + 2 * shadow_thickness; |
627 background_gc, shadow_thickness, edges); | 635 |
628 | 636 x_output_shadows (f, x, y, width, height, top_shadow_gc, bottom_shadow_gc, |
629 if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT) | 637 background_gc, shadow_thickness); |
630 { | |
631 /* Draw the shadows around the divider line */ | |
632 x_output_shadows (f, x + shadow_thickness, y + shadow_thickness, | |
633 width - 2*shadow_thickness, height - 2*shadow_thickness, | |
634 bottom_shadow_gc, top_shadow_gc, | |
635 background_gc, shadow_thickness, edges); | |
636 } | |
637 } | 638 } |
638 | 639 |
639 /***************************************************************************** | 640 /***************************************************************************** |
640 x_get_gc | 641 x_get_gc |
641 | 642 |
668 /* evil kludge! */ | 669 /* evil kludge! */ |
669 if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg)) | 670 if (!NILP (fg) && !COLOR_INSTANCEP (fg) && !INTP (fg)) |
670 { | 671 { |
671 /* #### I fixed once case where this was getting it. It was a | 672 /* #### I fixed once case where this was getting it. It was a |
672 bad macro expansion (compiler bug). */ | 673 bad macro expansion (compiler bug). */ |
673 stderr_out ("Help! x_get_gc got a bogus fg value! fg = "); | 674 fprintf (stderr, "Help! x_get_gc got a bogus fg value! fg = "); |
674 debug_print (fg); | 675 debug_print (fg); |
675 fg = Qnil; | 676 fg = Qnil; |
676 } | 677 } |
677 | 678 |
678 if (!NILP (fg)) | 679 if (!NILP (fg)) |
799 XSETDEVICE (device, d); | 800 XSETDEVICE (device, d); |
800 XSETWINDOW (window, w); | 801 XSETWINDOW (window, w); |
801 | 802 |
802 if (width < 0) | 803 if (width < 0) |
803 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); | 804 width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf)); |
804 height = DISPLAY_LINE_HEIGHT (dl); | 805 height = dl->ascent + dl->descent - dl->clip; |
805 | 806 |
806 /* Regularize the variables passed in. */ | 807 /* Regularize the variables passed in. */ |
807 | 808 |
808 if (clip_start < xpos) | 809 if (clip_start < xpos) |
809 clip_start = xpos; | 810 clip_start = xpos; |
811 if (clip_start >= clip_end) | 812 if (clip_start >= clip_end) |
812 /* It's all clipped out. */ | 813 /* It's all clipped out. */ |
813 return; | 814 return; |
814 | 815 |
815 xpos -= xoffset; | 816 xpos -= xoffset; |
816 | |
817 /* make sure the area we are about to display is subwindow free. */ | |
818 redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl), | |
819 clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl)); | |
820 | 817 |
821 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), | 818 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), |
822 Dynarr_length (buf)); | 819 Dynarr_length (buf)); |
823 | 820 |
824 cursor_clip = (cursor_start >= clip_start && | 821 cursor_clip = (cursor_start >= clip_start && |
860 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, | 857 bgc = x_get_gc (d, Qnil, cachel->foreground, cachel->background, |
861 bg_pmap, Qnil); | 858 bg_pmap, Qnil); |
862 | 859 |
863 if (bgc) | 860 if (bgc) |
864 XFillRectangle (dpy, x_win, bgc, clip_start, | 861 XFillRectangle (dpy, x_win, bgc, clip_start, |
865 DISPLAY_LINE_YPOS (dl), clip_end - clip_start, | 862 dl->ypos - dl->ascent, clip_end - clip_start, |
866 height); | 863 height); |
867 | 864 |
868 for (i = 0; i < nruns; i++) | 865 for (i = 0; i < nruns; i++) |
869 { | 866 { |
870 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | 867 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); |
871 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); | 868 struct Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |
872 int this_width; | 869 int this_width; |
873 int need_clipping; | 870 int need_clipping; |
874 | 871 |
875 if (EQ (font, Vthe_null_font_instance)) | 872 if (EQ (font, Vthe_null_font_instance)) |
876 continue; | 873 continue; |
881 | 878 |
882 /* XDrawImageString only clears the area equal to the height of | 879 /* XDrawImageString only clears the area equal to the height of |
883 the given font. It is possible that a font is being displayed | 880 the given font. It is possible that a font is being displayed |
884 on a line taller than it is, so this would cause us to fail to | 881 on a line taller than it is, so this would cause us to fail to |
885 clear some areas. */ | 882 clear some areas. */ |
886 if ((int) fi->height < (int) (height + dl->clip + dl->top_clip)) | 883 if ((int) fi->height < (int) (height + dl->clip)) |
887 { | 884 { |
888 int clear_start = max (xpos, clip_start); | 885 int clear_start = max (xpos, clip_start); |
889 int clear_end = min (xpos + this_width, clip_end); | 886 int clear_end = min (xpos + this_width, clip_end); |
890 | 887 |
891 if (cursor) | 888 if (cursor) |
892 { | 889 { |
893 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; | 890 int ypos1_line, ypos1_string, ypos2_line, ypos2_string; |
894 | 891 |
895 ypos1_string = dl->ypos - fi->ascent; | 892 ypos1_string = dl->ypos - fi->ascent; |
896 ypos2_string = dl->ypos + fi->descent; | 893 ypos2_string = dl->ypos + fi->descent; |
897 ypos1_line = DISPLAY_LINE_YPOS (dl); | 894 ypos1_line = dl->ypos - dl->ascent; |
898 ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl); | 895 ypos2_line = dl->ypos + dl->descent - dl->clip; |
899 | 896 |
900 /* Make sure we don't clear below the real bottom of the | 897 /* Make sure we don't clear below the real bottom of the |
901 line. */ | 898 line. */ |
902 if (ypos1_string > ypos2_line) | 899 if (ypos1_string > ypos2_line) |
903 ypos1_string = ypos2_line; | 900 ypos1_string = ypos2_line; |
919 } | 916 } |
920 } | 917 } |
921 else | 918 else |
922 { | 919 { |
923 redisplay_clear_region (window, findex, clear_start, | 920 redisplay_clear_region (window, findex, clear_start, |
924 DISPLAY_LINE_YPOS (dl), clear_end - clear_start, | 921 dl->ypos - dl->ascent, clear_end - clear_start, |
925 height); | 922 height); |
926 } | 923 } |
927 } | 924 } |
928 | 925 |
929 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) | 926 if (cursor && cursor_cachel && focus && NILP (bar_cursor_value)) |
952 clip_box[0].x = 0; | 949 clip_box[0].x = 0; |
953 clip_box[0].y = 0; | 950 clip_box[0].y = 0; |
954 clip_box[0].width = clip_end - clip_start; | 951 clip_box[0].width = clip_end - clip_start; |
955 clip_box[0].height = height; | 952 clip_box[0].height = height; |
956 | 953 |
957 XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl), | 954 XSetClipRectangles (dpy, gc, clip_start, dl->ypos - dl->ascent, |
958 clip_box, 1, Unsorted); | 955 clip_box, 1, Unsorted); |
959 } | 956 } |
960 | 957 |
961 if (runs[i].dimension == 1) | 958 if (runs[i].dimension == 1) |
962 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, | 959 (bgc ? XDrawString : XDrawImageString) (dpy, x_win, gc, xpos, |
1052 clip_box[0].x = 0; | 1049 clip_box[0].x = 0; |
1053 clip_box[0].y = 0; | 1050 clip_box[0].y = 0; |
1054 clip_box[0].width = cursor_width; | 1051 clip_box[0].width = cursor_width; |
1055 clip_box[0].height = height; | 1052 clip_box[0].height = height; |
1056 | 1053 |
1057 XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl), | 1054 XSetClipRectangles (dpy, cgc, cursor_start, dl->ypos - dl->ascent, |
1058 clip_box, 1, Unsorted); | 1055 clip_box, 1, Unsorted); |
1059 | 1056 |
1060 if (runs[i].dimension == 1) | 1057 if (runs[i].dimension == 1) |
1061 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, | 1058 XDrawImageString (dpy, x_win, cgc, xpos, dl->ypos, |
1062 (char *) runs[i].ptr, runs[i].len); | 1059 (char *) runs[i].ptr, runs[i].len); |
1112 Qnil, Qnil, Qnil); | 1109 Qnil, Qnil, Qnil); |
1113 } | 1110 } |
1114 | 1111 |
1115 tmp_y = dl->ypos - bogusly_obtained_ascent_value; | 1112 tmp_y = dl->ypos - bogusly_obtained_ascent_value; |
1116 tmp_height = cursor_height; | 1113 tmp_height = cursor_height; |
1117 if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height)) | 1114 if (tmp_y + tmp_height > (int) (dl->ypos - dl->ascent + height)) |
1118 { | 1115 { |
1119 tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height; | 1116 tmp_y = dl->ypos - dl->ascent + height - tmp_height; |
1120 if (tmp_y < (int) DISPLAY_LINE_YPOS (dl)) | 1117 if (tmp_y < (int) (dl->ypos - dl->ascent)) |
1121 tmp_y = DISPLAY_LINE_YPOS (dl); | 1118 tmp_y = dl->ypos - dl->ascent; |
1122 tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y; | 1119 tmp_height = dl->ypos - dl->ascent + height - tmp_y; |
1123 } | 1120 } |
1124 | 1121 |
1125 if (need_clipping) | 1122 if (need_clipping) |
1126 { | 1123 { |
1127 XRectangle clip_box[1]; | 1124 XRectangle clip_box[1]; |
1152 } | 1149 } |
1153 } | 1150 } |
1154 } | 1151 } |
1155 | 1152 |
1156 void | 1153 void |
1157 x_output_x_pixmap (struct frame *f, Lisp_Image_Instance *p, int x, | 1154 x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x, |
1158 int y, int xoffset, int yoffset, | 1155 int y, int clip_x, int clip_y, int clip_width, |
1159 int width, int height, unsigned long fg, unsigned long bg, | 1156 int clip_height, int width, int height, int pixmap_offset, |
1160 GC override_gc) | 1157 unsigned long fg, unsigned long bg, GC override_gc) |
1161 { | 1158 { |
1162 struct device *d = XDEVICE (f->device); | 1159 struct device *d = XDEVICE (f->device); |
1163 Display *dpy = DEVICE_X_DISPLAY (d); | 1160 Display *dpy = DEVICE_X_DISPLAY (d); |
1164 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1161 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1165 | 1162 |
1166 GC gc; | 1163 GC gc; |
1167 XGCValues gcv; | 1164 XGCValues gcv; |
1168 unsigned long pixmap_mask; | 1165 unsigned long pixmap_mask; |
1166 int need_clipping = (clip_x || clip_y); | |
1169 | 1167 |
1170 if (!override_gc) | 1168 if (!override_gc) |
1171 { | 1169 { |
1172 memset (&gcv, ~0, sizeof (XGCValues)); | 1170 memset (&gcv, ~0, sizeof (XGCValues)); |
1173 gcv.graphics_exposures = False; | 1171 gcv.graphics_exposures = False; |
1177 | 1175 |
1178 if (IMAGE_INSTANCE_X_MASK (p)) | 1176 if (IMAGE_INSTANCE_X_MASK (p)) |
1179 { | 1177 { |
1180 gcv.function = GXcopy; | 1178 gcv.function = GXcopy; |
1181 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); | 1179 gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p); |
1182 gcv.clip_x_origin = x - xoffset; | 1180 gcv.clip_x_origin = x; |
1183 gcv.clip_y_origin = y - yoffset; | 1181 gcv.clip_y_origin = y - pixmap_offset; |
1184 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | | 1182 pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin | |
1185 GCClipYOrigin); | 1183 GCClipYOrigin); |
1186 /* Can't set a clip rectangle because we already have a mask. | 1184 /* Can't set a clip rectangle below 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 | 1187 Is it possible to get an equivalent effect by changing the |
1188 args to XCopyArea below rather than messing with a clip box? | 1188 args to XCopyArea below rather than messing with a clip box? |
1189 - dkindred@cs.cmu.edu | 1189 - dkindred@cs.cmu.edu */ |
1190 Yes. We don't clip at all now - andy@xemacs.org | 1190 need_clipping = 0; |
1191 */ | |
1192 } | 1191 } |
1193 | 1192 |
1194 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask); | 1193 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask); |
1195 } | 1194 } |
1196 else | 1195 else |
1197 { | 1196 { |
1198 gc = override_gc; | 1197 gc = override_gc; |
1199 /* override_gc might have a mask already--we don't want to nuke it. | 1198 /* 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 | 1199 Maybe we can insist that override_gc have no mask, or use |
1201 one of the suggestions above. */ | 1200 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); | |
1202 } | 1214 } |
1203 | 1215 |
1204 /* 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 |
1205 XCopyPlane (1 = current foreground color, 0 = background) instead | 1217 XCopyPlane (1 = current foreground color, 0 = background) instead |
1206 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 |
1207 pixel values, instead of symbolic of fg/bg. */ | 1219 pixel values, instead of symbolic of fg/bg. */ |
1208 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) | 1220 if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0) |
1209 { | 1221 { |
1210 XCopyArea (dpy, | 1222 XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, |
1211 IMAGE_INSTANCE_X_PIXMAP_SLICE | 1223 pixmap_offset, width, |
1212 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, xoffset, | |
1213 yoffset, width, | |
1214 height, x, y); | 1224 height, x, y); |
1215 } | 1225 } |
1216 else | 1226 else |
1217 { | 1227 { |
1218 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE | 1228 XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0, |
1219 (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, | 1229 (pixmap_offset < 0 |
1220 xoffset, yoffset, width, height, x, y, 1L); | 1230 ? 0 |
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); | |
1221 } | 1243 } |
1222 } | 1244 } |
1223 | 1245 |
1224 static void | 1246 static void |
1225 x_output_pixmap (struct window *w, Lisp_Object image_instance, | 1247 x_output_pixmap (struct window *w, struct display_line *dl, |
1226 struct display_box *db, struct display_glyph_area *dga, | 1248 Lisp_Object image_instance, int xpos, int xoffset, |
1227 face_index findex, int cursor_start, int cursor_width, | 1249 int start_pixpos, int width, face_index findex, |
1228 int cursor_height, int bg_pixmap) | 1250 int cursor_start, int cursor_width, int cursor_height) |
1229 { | 1251 { |
1230 struct frame *f = XFRAME (w->frame); | 1252 struct frame *f = XFRAME (w->frame); |
1231 struct device *d = XDEVICE (f->device); | 1253 struct device *d = XDEVICE (f->device); |
1232 Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); | 1254 struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance); |
1255 Lisp_Object window; | |
1233 | 1256 |
1234 Display *dpy = DEVICE_X_DISPLAY (d); | 1257 Display *dpy = DEVICE_X_DISPLAY (d); |
1235 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1258 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 } | |
1236 | 1341 |
1237 /* Output the pixmap. */ | 1342 /* Output the pixmap. */ |
1238 { | 1343 { |
1239 Lisp_Object tmp_pixel; | 1344 Lisp_Object tmp_pixel; |
1240 XColor tmp_bcolor, tmp_fcolor; | 1345 XColor tmp_bcolor, tmp_fcolor; |
1242 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); | 1347 tmp_pixel = WINDOW_FACE_CACHEL_FOREGROUND (w, findex); |
1243 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 1348 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1244 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); | 1349 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex); |
1245 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 1350 tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1246 | 1351 |
1247 x_output_x_pixmap (f, p, db->xpos, db->ypos, | 1352 x_output_x_pixmap (f, p, xpos - xoffset, dl->ypos - dl->ascent, clip_x, |
1248 dga->xoffset, dga->yoffset, | 1353 clip_y, clip_width, clip_height, |
1249 dga->width, dga->height, | 1354 pwidth, pheight, pixmap_offset, |
1250 tmp_fcolor.pixel, tmp_bcolor.pixel, 0); | 1355 tmp_fcolor.pixel, tmp_bcolor.pixel, 0); |
1251 } | 1356 } |
1252 | 1357 |
1253 /* Draw a cursor over top of the pixmap. */ | 1358 /* Draw a cursor over top of the pixmap. */ |
1254 if (cursor_width && cursor_height && (cursor_start >= db->xpos) | 1359 if (cursor_width && cursor_height && (cursor_start >= xpos) |
1255 && !NILP (w->text_cursor_visible_p) | 1360 && !NILP (w->text_cursor_visible_p) |
1256 && (cursor_start < db->xpos + dga->width)) | 1361 && (cursor_start < xpos + pwidth)) |
1257 { | 1362 { |
1258 GC gc; | 1363 GC gc; |
1259 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 1364 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
1365 int y = dl->ypos - dl->ascent; | |
1260 struct face_cachel *cursor_cachel = | 1366 struct face_cachel *cursor_cachel = |
1261 WINDOW_FACE_CACHEL (w, | 1367 WINDOW_FACE_CACHEL (w, |
1262 get_builtin_face_cache_index | 1368 get_builtin_face_cache_index |
1263 (w, Vtext_cursor_face)); | 1369 (w, Vtext_cursor_face)); |
1264 | 1370 |
1265 gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil); | 1371 gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil); |
1266 | 1372 |
1267 if (cursor_width > db->xpos + dga->width - cursor_start) | 1373 if (cursor_width > xpos + pwidth - cursor_start) |
1268 cursor_width = db->xpos + dga->width - cursor_start; | 1374 cursor_width = xpos + pwidth - cursor_start; |
1269 | 1375 |
1270 if (focus) | 1376 if (focus) |
1271 { | 1377 { |
1272 XFillRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, | 1378 XFillRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, |
1273 cursor_height); | 1379 cursor_height); |
1274 } | 1380 } |
1275 else | 1381 else |
1276 { | 1382 { |
1277 XDrawRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width, | 1383 XDrawRectangle (dpy, x_win, gc, cursor_start, y, cursor_width, |
1278 cursor_height); | 1384 cursor_height); |
1279 } | 1385 } |
1280 } | 1386 } |
1281 } | 1387 } |
1282 | 1388 |
1289 x_output_vertical_divider (struct window *w, int clear) | 1395 x_output_vertical_divider (struct window *w, int clear) |
1290 { | 1396 { |
1291 struct frame *f = XFRAME (w->frame); | 1397 struct frame *f = XFRAME (w->frame); |
1292 struct device *d = XDEVICE (f->device); | 1398 struct device *d = XDEVICE (f->device); |
1293 | 1399 |
1400 EmacsFrame ef = (EmacsFrame) FRAME_X_TEXT_WIDGET (f); | |
1294 Display *dpy = DEVICE_X_DISPLAY (d); | 1401 Display *dpy = DEVICE_X_DISPLAY (d); |
1295 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1402 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1403 Pixel top_shadow_pixel, bottom_shadow_pixel, background_pixel; | |
1296 Lisp_Object tmp_pixel; | 1404 Lisp_Object tmp_pixel; |
1297 XColor tmp_color; | 1405 XColor tmp_color; |
1298 XGCValues gcv; | 1406 XGCValues gcv; |
1299 GC background_gc; | 1407 GC top_shadow_gc, bottom_shadow_gc, background_gc; |
1300 enum edge_style style; | 1408 |
1301 | 1409 int use_pixmap = 0; |
1410 int flip_gcs = 0; | |
1302 unsigned long mask; | 1411 unsigned long mask; |
1303 int x, y1, y2, width, shadow_thickness, spacing, line_width; | 1412 int x, y1, y2, width, shadow_thickness, spacing, line_width; |
1304 face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); | 1413 face_index div_face = get_builtin_face_cache_index (w, Vvertical_divider_face); |
1305 | 1414 |
1306 width = window_divider_width (w); | 1415 width = window_divider_width (w); |
1315 | 1424 |
1316 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face); | 1425 tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, div_face); |
1317 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 1426 tmp_color = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1318 | 1427 |
1319 /* First, get the GC's. */ | 1428 /* 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)); | |
1320 gcv.background = tmp_color.pixel; | 1438 gcv.background = tmp_color.pixel; |
1321 gcv.foreground = tmp_color.pixel; | |
1322 gcv.graphics_exposures = False; | 1439 gcv.graphics_exposures = False; |
1323 mask = GCForeground | GCBackground | GCGraphicsExposures; | 1440 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; | |
1324 background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask); | 1490 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 } | |
1325 | 1505 |
1326 /* Clear the divider area first. This needs to be done when a | 1506 /* Clear the divider area first. This needs to be done when a |
1327 window split occurs. */ | 1507 window split occurs. */ |
1328 if (clear) | 1508 if (clear) |
1329 XClearArea (dpy, x_win, x, y1, width, y2 - y1, False); | 1509 XClearArea (dpy, x_win, x, y1, width, y2 - y1, False); |
1331 /* Draw the divider line. */ | 1511 /* Draw the divider line. */ |
1332 XFillRectangle (dpy, x_win, background_gc, | 1512 XFillRectangle (dpy, x_win, background_gc, |
1333 x + spacing + shadow_thickness, y1, | 1513 x + spacing + shadow_thickness, y1, |
1334 line_width, y2 - y1); | 1514 line_width, y2 - y1); |
1335 | 1515 |
1336 if (shadow_thickness < 0) | |
1337 { | |
1338 shadow_thickness = -shadow_thickness; | |
1339 style = EDGE_BEVEL_IN; | |
1340 } | |
1341 else | |
1342 { | |
1343 style = EDGE_BEVEL_OUT; | |
1344 } | |
1345 | |
1346 /* Draw the shadows around the divider line */ | 1516 /* Draw the shadows around the divider line */ |
1347 x_bevel_area (w, div_face, x + spacing, y1, | 1517 x_output_shadows (f, x + spacing, y1, |
1348 width - 2 * spacing, y2 - y1, | 1518 width - 2 * spacing, y2 - y1, |
1349 shadow_thickness, EDGE_ALL, style); | 1519 top_shadow_gc, bottom_shadow_gc, |
1520 background_gc, shadow_thickness); | |
1350 } | 1521 } |
1351 | 1522 |
1352 /***************************************************************************** | 1523 /***************************************************************************** |
1353 x_output_blank | 1524 x_output_blank |
1354 | 1525 |
1373 Lisp_Object buffer = WINDOW_BUFFER (w); | 1544 Lisp_Object buffer = WINDOW_BUFFER (w); |
1374 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, | 1545 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, |
1375 buffer); | 1546 buffer); |
1376 | 1547 |
1377 int x = rb->xpos; | 1548 int x = rb->xpos; |
1378 int y = DISPLAY_LINE_YPOS (dl); | 1549 int y = dl->ypos - dl->ascent; |
1379 int width = rb->width; | 1550 int width = rb->width; |
1380 int height = DISPLAY_LINE_HEIGHT (dl); | 1551 int height = dl->ascent + dl->descent - dl->clip; |
1381 | |
1382 /* Unmap all subwindows in the area we are going to blank. */ | |
1383 redisplay_unmap_subwindows_maybe (f, x, y, width, height); | |
1384 | 1552 |
1385 if (start_pixpos > x) | 1553 if (start_pixpos > x) |
1386 { | 1554 { |
1387 if (start_pixpos >= (x + width)) | 1555 if (start_pixpos >= (x + width)) |
1388 return; | 1556 return; |
1416 && (cursor_start + cursor_width > x) | 1584 && (cursor_start + cursor_width > x) |
1417 && cursor_start < (x + width)))) | 1585 && cursor_start < (x + width)))) |
1418 { | 1586 { |
1419 int cursor_height, cursor_y; | 1587 int cursor_height, cursor_y; |
1420 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 1588 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
1421 Lisp_Font_Instance *fi; | 1589 struct Lisp_Font_Instance *fi; |
1422 | 1590 |
1423 fi = XFONT_INSTANCE (FACE_CACHEL_FONT | 1591 fi = XFONT_INSTANCE (FACE_CACHEL_FONT |
1424 (WINDOW_FACE_CACHEL (w, rb->findex), | 1592 (WINDOW_FACE_CACHEL (w, rb->findex), |
1425 Vcharset_ascii)); | 1593 Vcharset_ascii)); |
1426 | 1594 |
1472 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1640 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1473 GC gc; | 1641 GC gc; |
1474 | 1642 |
1475 int x = rb->xpos; | 1643 int x = rb->xpos; |
1476 int width = rb->width; | 1644 int width = rb->width; |
1477 int height = DISPLAY_LINE_HEIGHT (dl); | 1645 int height = dl->ascent + dl->descent - dl->clip; |
1478 int ypos1, ypos2, ypos3, ypos4; | 1646 int ypos1, ypos2, ypos3, ypos4; |
1479 | 1647 |
1480 ypos1 = DISPLAY_LINE_YPOS (dl); | 1648 ypos1 = dl->ypos - dl->ascent; |
1481 ypos2 = ypos1 + rb->object.hline.yoffset; | 1649 ypos2 = ypos1 + rb->object.hline.yoffset; |
1482 ypos3 = ypos2 + rb->object.hline.thickness; | 1650 ypos3 = ypos2 + rb->object.hline.thickness; |
1483 ypos4 = dl->ypos + dl->descent - dl->clip; | 1651 ypos4 = dl->ypos + dl->descent - dl->clip; |
1484 | 1652 |
1485 /* First clear the area not covered by the line. */ | 1653 /* First clear the area not covered by the line. */ |
1514 callers responsibility to set the GC's appropriately. | 1682 callers responsibility to set the GC's appropriately. |
1515 ****************************************************************************/ | 1683 ****************************************************************************/ |
1516 void | 1684 void |
1517 x_output_shadows (struct frame *f, int x, int y, int width, int height, | 1685 x_output_shadows (struct frame *f, int x, int y, int width, int height, |
1518 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, | 1686 GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc, |
1519 int shadow_thickness, int edges) | 1687 int shadow_thickness) |
1520 { | 1688 { |
1521 struct device *d = XDEVICE (f->device); | 1689 struct device *d = XDEVICE (f->device); |
1522 | 1690 |
1523 Display *dpy = DEVICE_X_DISPLAY (d); | 1691 Display *dpy = DEVICE_X_DISPLAY (d); |
1524 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); | 1692 Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f)); |
1536 shadow_thickness = height / 2; | 1704 shadow_thickness = height / 2; |
1537 | 1705 |
1538 for (elt = 0; elt < shadow_thickness; elt++) | 1706 for (elt = 0; elt < shadow_thickness; elt++) |
1539 { | 1707 { |
1540 int seg1 = elt; | 1708 int seg1 = elt; |
1541 int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt; | 1709 int seg2 = elt + shadow_thickness; |
1542 int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt; | 1710 |
1543 | 1711 top_shadow[seg1].x1 = x; |
1544 if (edges & EDGE_TOP) | 1712 top_shadow[seg1].x2 = x + width - elt - 1; |
1545 { | 1713 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; |
1546 top_shadow[seg1].x1 = x + elt; | 1714 |
1547 top_shadow[seg1].x2 = x + width - elt - 1; | 1715 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; |
1548 top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt; | 1716 top_shadow[seg2].y1 = y + shadow_thickness; |
1549 } | 1717 top_shadow[seg2].y2 = y + height - elt - 1; |
1550 if (edges & EDGE_LEFT) | 1718 |
1551 { | 1719 bottom_shadow[seg1].x1 = x + elt + 1; |
1552 top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt; | 1720 bottom_shadow[seg1].x2 = x + width - 1; |
1553 top_shadow[seg2].y1 = y + elt; | 1721 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; |
1554 top_shadow[seg2].y2 = y + height - elt - 1; | 1722 |
1555 } | 1723 bottom_shadow[seg2].x1 = bottom_shadow[seg2].x2 = x + width - elt - 1; |
1556 if (edges & EDGE_BOTTOM) | 1724 bottom_shadow[seg2].y1 = y + elt + 1; |
1557 { | 1725 bottom_shadow[seg2].y2 = y + height - shadow_thickness; |
1558 bottom_shadow[seg1].x1 = x + elt; | 1726 } |
1559 bottom_shadow[seg1].x2 = x + width - elt - 1; | 1727 |
1560 bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1; | 1728 XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, shadow_thickness * 2); |
1561 } | |
1562 if (edges & EDGE_RIGHT) | |
1563 { | |
1564 bottom_shadow[bot_seg2].x1 = bottom_shadow[bot_seg2].x2 = x + width - elt - 1; | |
1565 bottom_shadow[bot_seg2].y1 = y + elt; | |
1566 bottom_shadow[bot_seg2].y2 = y + height - elt - 1; | |
1567 } | |
1568 } | |
1569 | |
1570 XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, | |
1571 ((edges & EDGE_TOP) ? shadow_thickness : 0) | |
1572 + ((edges & EDGE_LEFT) ? shadow_thickness : 0)); | |
1573 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, | 1729 XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow, |
1574 ((edges & EDGE_BOTTOM) ? shadow_thickness : 0) | 1730 shadow_thickness * 2); |
1575 + ((edges & EDGE_RIGHT) ? shadow_thickness : 0)); | |
1576 } | 1731 } |
1577 | 1732 |
1578 /***************************************************************************** | 1733 /***************************************************************************** |
1579 x_generate_shadow_pixels | 1734 x_generate_shadow_pixels |
1580 | 1735 |
1654 if (botc.pixel == background) | 1809 if (botc.pixel == background) |
1655 *top_shadow = core_background; | 1810 *top_shadow = core_background; |
1656 else | 1811 else |
1657 *bottom_shadow = background; | 1812 *bottom_shadow = background; |
1658 } | 1813 } |
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); | |
1659 } | 1862 } |
1660 } | 1863 } |
1661 | 1864 |
1662 /***************************************************************************** | 1865 /***************************************************************************** |
1663 x_redraw_exposed_window | 1866 x_redraw_exposed_window |
1774 /* #### We would rather put these off as well but there is currently | 1977 /* #### We would rather put these off as well but there is currently |
1775 no combination of flags which will force an unchanged toolbar to | 1978 no combination of flags which will force an unchanged toolbar to |
1776 redraw anyhow. */ | 1979 redraw anyhow. */ |
1777 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); | 1980 MAYBE_FRAMEMETH (f, redraw_exposed_toolbars, (f, x, y, width, height)); |
1778 #endif | 1981 #endif |
1779 redraw_exposed_gutters (f, x, y, width, height); | |
1780 | 1982 |
1781 if (!f->window_face_cache_reset) | 1983 if (!f->window_face_cache_reset) |
1782 { | 1984 { |
1783 x_redraw_exposed_windows (f->root_window, x, y, width, height); | 1985 x_redraw_exposed_windows (f->root_window, x, y, width, height); |
1784 | 1986 |
1841 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); | 2043 int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)); |
1842 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, | 2044 Lisp_Object bar_cursor_value = symbol_value_in_buffer (Qbar_cursor, |
1843 WINDOW_BUFFER (w)); | 2045 WINDOW_BUFFER (w)); |
1844 | 2046 |
1845 int x = xpos; | 2047 int x = xpos; |
1846 int y = DISPLAY_LINE_YPOS (dl); | 2048 int y = dl->ypos - dl->ascent; |
1847 int width = EOL_CURSOR_WIDTH; | 2049 int width = EOL_CURSOR_WIDTH; |
1848 int height = DISPLAY_LINE_HEIGHT (dl); | 2050 int height = dl->ascent + dl->descent - dl->clip; |
1849 int cursor_height, cursor_y; | 2051 int cursor_height, cursor_y; |
1850 int defheight, defascent; | 2052 int defheight, defascent; |
1851 | 2053 |
1852 XSETWINDOW (window, w); | 2054 XSETWINDOW (window, w); |
1853 redisplay_clear_region (window, findex, x, y, width, height); | 2055 redisplay_clear_region (window, findex, x, y, width, height); |
1906 { | 2108 { |
1907 x_clear_frame_windows (w->hchild); | 2109 x_clear_frame_windows (w->hchild); |
1908 return; | 2110 return; |
1909 } | 2111 } |
1910 | 2112 |
1911 redisplay_clear_to_window_end (w, WINDOW_TEXT_TOP (w), | 2113 x_clear_to_window_end (w, WINDOW_TEXT_TOP (w), WINDOW_TEXT_BOTTOM (w)); |
1912 WINDOW_TEXT_BOTTOM (w)); | |
1913 } | 2114 } |
1914 | 2115 |
1915 static void | 2116 static void |
1916 x_clear_frame_windows (Lisp_Object window) | 2117 x_clear_frame_windows (Lisp_Object window) |
1917 { | 2118 { |
1969 XColor tmp_fcolor, tmp_bcolor; | 2170 XColor tmp_fcolor, tmp_bcolor; |
1970 Lisp_Object tmp_pixel, frame; | 2171 Lisp_Object tmp_pixel, frame; |
1971 struct frame *f = device_selected_frame (d); | 2172 struct frame *f = device_selected_frame (d); |
1972 struct window *w = XWINDOW (FRAME_ROOT_WINDOW (f)); | 2173 struct window *w = XWINDOW (FRAME_ROOT_WINDOW (f)); |
1973 Widget shell = FRAME_X_SHELL_WIDGET (f); | 2174 Widget shell = FRAME_X_SHELL_WIDGET (f); |
1974 int flash_height; | |
1975 | 2175 |
1976 XSETFRAME (frame, f); | 2176 XSETFRAME (frame, f); |
1977 | 2177 |
1978 tmp_pixel = FACE_FOREGROUND (Vdefault_face, frame); | 2178 tmp_pixel = FACE_FOREGROUND (Vdefault_face, frame); |
1979 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); | 2179 tmp_fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel)); |
1986 gcv.foreground = (tmp_fcolor.pixel ^ tmp_bcolor.pixel); | 2186 gcv.foreground = (tmp_fcolor.pixel ^ tmp_bcolor.pixel); |
1987 gcv.function = GXxor; | 2187 gcv.function = GXxor; |
1988 gcv.graphics_exposures = False; | 2188 gcv.graphics_exposures = False; |
1989 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (XDEVICE (f->device)), &gcv, | 2189 gc = gc_cache_lookup (DEVICE_X_GC_CACHE (XDEVICE (f->device)), &gcv, |
1990 (GCForeground | GCFunction | GCGraphicsExposures)); | 2190 (GCForeground | GCFunction | GCGraphicsExposures)); |
1991 default_face_height_and_width (frame, &flash_height, 0); | 2191 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, |
1992 | 2192 w->pixel_width, w->pixel_height); |
1993 /* If window is tall, flash top and bottom line. */ | |
1994 if (EQ (Vvisible_bell, Qtop_bottom) && w->pixel_height > 3 * flash_height) | |
1995 { | |
1996 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, | |
1997 w->pixel_width, flash_height); | |
1998 XFillRectangle (dpy, win, gc, w->pixel_left, | |
1999 w->pixel_top + w->pixel_height - flash_height, | |
2000 w->pixel_width, flash_height); | |
2001 } | |
2002 else | |
2003 /* If it is short, flash it all. */ | |
2004 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, | |
2005 w->pixel_width, w->pixel_height); | |
2006 | |
2007 XSync (dpy, False); | 2193 XSync (dpy, False); |
2008 | 2194 |
2009 #ifdef HAVE_SELECT | 2195 #ifdef HAVE_SELECT |
2010 { | 2196 { |
2011 int usecs = 100000; | 2197 int usecs = 100000; |
2021 #else /* !HAVE_POLL */ | 2207 #else /* !HAVE_POLL */ |
2022 bite me | 2208 bite me |
2023 #endif /* HAVE_POLL */ | 2209 #endif /* HAVE_POLL */ |
2024 #endif /* HAVE_SELECT */ | 2210 #endif /* HAVE_SELECT */ |
2025 | 2211 |
2026 /* If window is tall, flash top and bottom line. */ | 2212 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, |
2027 if (EQ (Vvisible_bell, Qtop_bottom) && w->pixel_height > 3 * flash_height) | 2213 w->pixel_width, w->pixel_height); |
2028 { | |
2029 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, | |
2030 w->pixel_width, flash_height); | |
2031 XFillRectangle (dpy, win, gc, w->pixel_left, | |
2032 w->pixel_top + w->pixel_height - flash_height, | |
2033 w->pixel_width, flash_height); | |
2034 } | |
2035 else | |
2036 /* If it is short, flash it all. */ | |
2037 XFillRectangle (dpy, win, gc, w->pixel_left, w->pixel_top, | |
2038 w->pixel_width, w->pixel_height); | |
2039 | |
2040 XSync (dpy, False); | 2214 XSync (dpy, False); |
2041 | 2215 |
2042 return 1; | 2216 return 1; |
2043 } | 2217 } |
2044 | 2218 |
2091 CONSOLE_HAS_METHOD (x, text_width); | 2265 CONSOLE_HAS_METHOD (x, text_width); |
2092 CONSOLE_HAS_METHOD (x, output_display_block); | 2266 CONSOLE_HAS_METHOD (x, output_display_block); |
2093 CONSOLE_HAS_METHOD (x, divider_height); | 2267 CONSOLE_HAS_METHOD (x, divider_height); |
2094 CONSOLE_HAS_METHOD (x, eol_cursor_width); | 2268 CONSOLE_HAS_METHOD (x, eol_cursor_width); |
2095 CONSOLE_HAS_METHOD (x, output_vertical_divider); | 2269 CONSOLE_HAS_METHOD (x, output_vertical_divider); |
2270 CONSOLE_HAS_METHOD (x, clear_to_window_end); | |
2096 CONSOLE_HAS_METHOD (x, clear_region); | 2271 CONSOLE_HAS_METHOD (x, clear_region); |
2097 CONSOLE_HAS_METHOD (x, clear_frame); | 2272 CONSOLE_HAS_METHOD (x, clear_frame); |
2098 CONSOLE_HAS_METHOD (x, window_output_begin); | 2273 CONSOLE_HAS_METHOD (x, output_begin); |
2099 CONSOLE_HAS_METHOD (x, window_output_end); | 2274 CONSOLE_HAS_METHOD (x, output_end); |
2100 CONSOLE_HAS_METHOD (x, flash); | 2275 CONSOLE_HAS_METHOD (x, flash); |
2101 CONSOLE_HAS_METHOD (x, ring_bell); | 2276 CONSOLE_HAS_METHOD (x, ring_bell); |
2102 CONSOLE_HAS_METHOD (x, bevel_area); | 2277 } |
2103 CONSOLE_HAS_METHOD (x, output_string); | |
2104 CONSOLE_HAS_METHOD (x, output_pixmap); | |
2105 } |