Mercurial > emacs
comparison src/xterm.c @ 2732:8b55aa587d3c
* xdisp.c (display_text_line): Apply faces to characters
according to overlays and text properties; use
compute_char_face and compute_glyph_face to figure out what
face to use, and where a new face starts.
* xterm.c (dumpglyphs): Use the upper bits of the glyphs to decide
which frame face to use. Call GLYPH_FOLLOW_ALIASES to make sure
we're implementing the glyph table properly. If we're not using
the default or mode line face, call intern_face to find a display
face for the frame face selected by the glyph code. Implement
underlining. Remove the `font' argument; we have to derive this
from the frame and face anyway. Change all callers.
* disptab.h (GLYPH_FOLLOW_ALIASES): New macro.
* xterm.c (x_destroy_window): Call free_frame_faces.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Mon, 10 May 1993 00:26:32 +0000 |
parents | 77f1457d000e |
children | 55e9c556bbf8 |
comparison
equal
deleted
inserted
replaced
2731:267d29b9490b | 2732:8b55aa587d3c |
---|---|
393 | 393 |
394 /* Display a sequence of N glyphs found at GP. | 394 /* Display a sequence of N glyphs found at GP. |
395 WINDOW is the x-window to output to. LEFT and TOP are starting coords. | 395 WINDOW is the x-window to output to. LEFT and TOP are starting coords. |
396 HL is 1 if this text is highlighted, 2 if the cursor is on it. | 396 HL is 1 if this text is highlighted, 2 if the cursor is on it. |
397 | 397 |
398 FONT is the default font to use (for glyphs whose font-code is 0). */ | 398 FONT is the default font to use (for glyphs whose font-code is 0). |
399 | |
400 Since the display generation code is responsible for calling | |
401 compute_char_face and compute_glyph_face on everything it puts in | |
402 the display structure, we can assume that the face code on each | |
403 glyph is a valid index into FRAME_FACES (f), and the one to which | |
404 we can actually apply intern_face. */ | |
405 | |
406 #if 1 | |
407 /* This is the multi-face code. */ | |
408 | |
409 static void | |
410 dumpglyphs (f, left, top, gp, n, hl) | |
411 struct frame *f; | |
412 int left, top; | |
413 register GLYPH *gp; /* Points to first GLYPH. */ | |
414 register int n; /* Number of glyphs to display. */ | |
415 int hl; | |
416 { | |
417 /* Holds characters to be displayed. */ | |
418 char *buf = (char *) alloca (f->width * sizeof (*buf)); | |
419 register char *cp; /* Steps through buf[]. */ | |
420 register int tlen = GLYPH_TABLE_LENGTH; | |
421 register Lisp_Object *tbase = GLYPH_TABLE_BASE; | |
422 Window window = FRAME_X_WINDOW (f); | |
423 | |
424 extern struct face *intern_face (/* FRAME_PTR, struct face * */); | |
425 | |
426 while (n > 0) | |
427 { | |
428 /* Get the face-code of the next GLYPH. */ | |
429 int cf, len; | |
430 int g = *gp; | |
431 | |
432 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | |
433 cf = GLYPH_FACE (g); | |
434 | |
435 /* Find the run of consecutive glyphs with the same face-code. | |
436 Extract their character codes into BUF. */ | |
437 cp = buf; | |
438 while (n > 0) | |
439 { | |
440 g = *gp; | |
441 GLYPH_FOLLOW_ALIASES (tbase, tlen, g); | |
442 if (GLYPH_FACE (g) != cf) | |
443 break; | |
444 | |
445 *cp++ = GLYPH_CHAR (g); | |
446 --n; | |
447 ++gp; | |
448 } | |
449 | |
450 /* LEN gets the length of the run. */ | |
451 len = cp - buf; | |
452 | |
453 /* Now output this run of chars, with the font and pixel values | |
454 determined by the face code CF. */ | |
455 { | |
456 struct face *face = FRAME_DEFAULT_FACE (f); | |
457 FONT_TYPE *font = FACE_FONT (face); | |
458 GC gc = FACE_GC (face); | |
459 | |
460 if (cf != 0) | |
461 { | |
462 /* The face codes on the glyphs must be valid indices into the | |
463 frame's face table. */ | |
464 if (cf < 0 || cf >= FRAME_N_FACES (f)) | |
465 abort (); | |
466 | |
467 if (cf == 1) | |
468 face = FRAME_MODE_LINE_FACE (f); | |
469 else | |
470 face = intern_face (FRAME_FACES (f) [cf]); | |
471 font = FACE_FONT (face); | |
472 gc = FACE_GC (face); | |
473 } | |
474 else if (hl == 0) | |
475 ; | |
476 else if (hl == 1) | |
477 { | |
478 face = FRAME_MODE_LINE_FACE (f); | |
479 font = FACE_FONT (face); | |
480 gc = FACE_GC (face); | |
481 } | |
482 else if (hl == 2) | |
483 { | |
484 gc = (f->display.x->cursor_gc); | |
485 } | |
486 | |
487 XDrawImageString (x_current_display, window, gc, | |
488 left, top + FONT_BASE (font), buf, len); | |
489 left += len * FONT_WIDTH (font); | |
490 | |
491 /* We should probably check for XA_UNDERLINE_POSITION and | |
492 XA_UNDERLINE_THICKNESS properties on the font, but let's | |
493 just get the thing working, and come back to that. */ | |
494 { | |
495 int underline_position = 2; | |
496 | |
497 if (font->descent < underline_position) | |
498 underline_position = font->descent; | |
499 | |
500 if (face->underline) | |
501 XFillRectangle (x_current_display, FRAME_X_WINDOW (f), | |
502 FACE_GC (face), | |
503 left, (top | |
504 + FONT_BASE (font) | |
505 + underline_position), | |
506 len * FONT_WIDTH (font), 1); | |
507 } | |
508 | |
509 left += len * FONT_WIDTH (font); | |
510 } | |
511 } | |
512 } | |
513 #endif /* 1 */ | |
514 | |
515 #if 0 | |
516 /* This is the old single-face code. */ | |
399 | 517 |
400 static void | 518 static void |
401 dumpglyphs (f, left, top, gp, n, hl, font) | 519 dumpglyphs (f, left, top, gp, n, hl, font) |
402 struct frame *f; | 520 struct frame *f; |
403 int left, top; | 521 int left, top; |
421 else | 539 else |
422 /* What size of glyph ARE you using? And does X have a function to | 540 /* What size of glyph ARE you using? And does X have a function to |
423 draw them? */ | 541 draw them? */ |
424 abort (); | 542 abort (); |
425 } | 543 } |
426 | 544 #endif |
427 #if 0 | |
428 static void | |
429 dumpglyphs (f, left, top, gp, n, hl, font) | |
430 struct frame *f; | |
431 int left, top; | |
432 register GLYPH *gp; /* Points to first GLYPH. */ | |
433 register int n; /* Number of glyphs to display. */ | |
434 int hl; | |
435 FONT_TYPE *font; | |
436 { | |
437 char buf[f->width]; /* Holds characters to be displayed. */ | |
438 register char *cp; /* Steps through buf[]. */ | |
439 register int tlen = GLYPH_TABLE_LENGTH; | |
440 register Lisp_Object *tbase = GLYPH_TABLE_BASE; | |
441 Window window = FRAME_X_WINDOW (f); | |
442 int cursor_pixel = f->display.x->cursor_pixel; | |
443 int fg_pixel = f->display.x->foreground_pixel; | |
444 int bg_pixel = f->display.x->background_pixel; | |
445 int intborder = f->display.x->internal_border_width; | |
446 | |
447 while (n) | |
448 { | |
449 /* Get the face-code of the next GLYPH. */ | |
450 int cf, len; | |
451 int g = *gp; | |
452 | |
453 while (GLYPH_ALIAS_P (tbase, tlen, g)) | |
454 g = GLYPH_ALIAS (tbase, g); | |
455 | |
456 cf = g >> 8; | |
457 | |
458 /* Find the run of consecutive glyphs with the same face-code. | |
459 Extract their character codes into BUF. */ | |
460 cp = buf; | |
461 while (n > 0) | |
462 { | |
463 g = *gp; | |
464 while (GLYPH_ALIAS_P (tbase, tlen, g)) | |
465 g = GLYPH_ALIAS (tbase, g); | |
466 if ((g >> 8) != cf) | |
467 break; | |
468 | |
469 *cp++ = 0377 & g; | |
470 --n; | |
471 ++gp; | |
472 } | |
473 | |
474 /* LEN gets the length of the run. */ | |
475 len = cp - buf; | |
476 | |
477 /* Now output this run of chars, with the font and pixel values | |
478 determined by the face code CF. */ | |
479 if (cf == 0) | |
480 { | |
481 #ifdef HAVE_X11 | |
482 GC GC_cursor = f->display.x->cursor_gc; | |
483 GC GC_reverse = f->display.x->reverse_gc; | |
484 GC GC_normal = f->display.x->normal_gc; | |
485 | |
486 XDrawImageString (x_current_display, window, | |
487 (hl == 2 | |
488 ? GC_cursor | |
489 : (hl ? GC_reverse : GC_normal)), | |
490 left, top + FONT_BASE (font), buf, len); | |
491 #else /* ! defined (HAVE_X11) */ | |
492 XText (window, left, top, | |
493 buf, | |
494 len, | |
495 font->id, | |
496 (hl == 2 | |
497 ? (cursor_pixel == fg_pixel ? bg_pixel : fg_pixel) | |
498 : hl ? bg_pixel : fg_pixel), | |
499 (hl == 2 ? cursor_pixel | |
500 : hl ? fg_pixel : bg_pixel)); | |
501 #endif /* ! defined (HAVE_X11) */ | |
502 } | |
503 else | |
504 { | |
505 #ifdef HAVE_X11 | |
506 if (FACE_IS_FONT (cf)) | |
507 XDrawImageString (x_current_display, FRAME_X_WINDOW (f), | |
508 FACE_GC (cf), | |
509 left, top + FONT_BASE (FACE_FONT (cf)), | |
510 buf, len); | |
511 else if (FACE_IS_IMAGE (cf)) | |
512 XCopyPlane (x_current_display, FACE_IMAGE (cf), | |
513 FRAME_X_WINDOW (f), | |
514 f->display.x->normal_gc, | |
515 0, 0, | |
516 FACE_IMAGE_WIDTH (cf), | |
517 FACE_IMAGE_HEIGHT (cf), left, top); | |
518 else | |
519 abort (); | |
520 #else /* ! defined (HAVE_X11) */ | |
521 register struct face *fp = x_face_table[cf]; | |
522 | |
523 XText (window, left, top, | |
524 buf, | |
525 len, | |
526 fp->font->id, | |
527 (hl == 2 | |
528 ? (cursor_pixel == fp->fg ? fp->bg : fp->fg) | |
529 : hl ? fp->bg : fp->fg), | |
530 (hl == 2 ? cursor_pixel | |
531 : hl ? fp->fg : fp->bg)); | |
532 #endif /* ! defined (HAVE_X11) */ | |
533 } | |
534 left += len * FONT_WIDTH (font); | |
535 } | |
536 } | |
537 #endif /* ! 0 */ | |
538 | 545 |
539 /* Output some text at the nominal frame cursor position. | 546 /* Output some text at the nominal frame cursor position. |
540 Advance the cursor over the text. | 547 Advance the cursor over the text. |
541 Output LEN glyphs at START. | 548 Output LEN glyphs at START. |
542 | 549 |
565 } | 572 } |
566 | 573 |
567 dumpglyphs (f, | 574 dumpglyphs (f, |
568 CHAR_TO_PIXEL_COL (f, curs_x), | 575 CHAR_TO_PIXEL_COL (f, curs_x), |
569 CHAR_TO_PIXEL_ROW (f, curs_y), | 576 CHAR_TO_PIXEL_ROW (f, curs_y), |
570 start, len, highlight, f->display.x->font); | 577 start, len, highlight); |
571 | 578 |
572 /* If we drew on top of the cursor, note that it is turned off. */ | 579 /* If we drew on top of the cursor, note that it is turned off. */ |
573 if (curs_y == f->phys_cursor_y | 580 if (curs_y == f->phys_cursor_y |
574 && curs_x <= f->phys_cursor_x | 581 && curs_x <= f->phys_cursor_x |
575 && curs_x + len > f->phys_cursor_x) | 582 && curs_x + len > f->phys_cursor_x) |
1079 | 1086 |
1080 dumpglyphs (f, | 1087 dumpglyphs (f, |
1081 CHAR_TO_PIXEL_COL (f, left), | 1088 CHAR_TO_PIXEL_COL (f, left), |
1082 CHAR_TO_PIXEL_ROW (f, y), | 1089 CHAR_TO_PIXEL_ROW (f, y), |
1083 line, min (cols, active_frame->used[y] - left), | 1090 line, min (cols, active_frame->used[y] - left), |
1084 active_frame->highlight[y], f->display.x->font); | 1091 active_frame->highlight[y]); |
1085 } | 1092 } |
1086 | 1093 |
1087 /* Turn the cursor on if we turned it off. */ | 1094 /* Turn the cursor on if we turned it off. */ |
1088 | 1095 |
1089 if (cursor_cleared) | 1096 if (cursor_cleared) |
3310 int highlight; | 3317 int highlight; |
3311 { | 3318 { |
3312 dumpglyphs (f, | 3319 dumpglyphs (f, |
3313 CHAR_TO_PIXEL_COL (f, column), | 3320 CHAR_TO_PIXEL_COL (f, column), |
3314 CHAR_TO_PIXEL_ROW (f, row), | 3321 CHAR_TO_PIXEL_ROW (f, row), |
3315 &glyph, 1, highlight, f->display.x->font); | 3322 &glyph, 1, highlight); |
3316 } | 3323 } |
3317 | 3324 |
3318 static void | 3325 static void |
3319 x_display_bar_cursor (f, on) | 3326 x_display_bar_cursor (f, on) |
3320 struct frame *f; | 3327 struct frame *f; |
4276 BLOCK_INPUT; | 4283 BLOCK_INPUT; |
4277 | 4284 |
4278 if (f->display.x->icon_desc != 0) | 4285 if (f->display.x->icon_desc != 0) |
4279 XDestroyWindow (XDISPLAY f->display.x->icon_desc); | 4286 XDestroyWindow (XDISPLAY f->display.x->icon_desc); |
4280 XDestroyWindow (XDISPLAY f->display.x->window_desc); | 4287 XDestroyWindow (XDISPLAY f->display.x->window_desc); |
4288 free_frame_faces (f); | |
4281 XFlushQueue (); | 4289 XFlushQueue (); |
4282 | 4290 |
4283 xfree (f->display.x); | 4291 xfree (f->display.x); |
4284 f->display.x = 0; | 4292 f->display.x = 0; |
4285 if (f == x_focus_frame) | 4293 if (f == x_focus_frame) |