diff options
| author | Richard M. Stallman | 1994-10-17 07:01:39 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-10-17 07:01:39 +0000 |
| commit | cd0bb842f6b515dd9fa6c27fca3740c271767248 (patch) | |
| tree | 6668ab33f961a1948bcb1b212f4b7690d8502ba6 /src | |
| parent | f1c7b5a673dfbbc4b3b718b2aaa29e250b535a86 (diff) | |
| download | emacs-cd0bb842f6b515dd9fa6c27fca3740c271767248.tar.gz emacs-cd0bb842f6b515dd9fa6c27fca3740c271767248.zip | |
(intern_face): Set the fill_style.
(copy_face, merge_faces): Copy the pixmap_h and pixmap_w.
(intern_face): Store the stipple in the GC.
(unload_color): Really do free the color.
(free_frame_faces): Call unload_pixmap.
(Fset_face_attribute_internal): Handle background pixmap.
Destroy old pixmap when necessary.
(free_frame_faces): Destroy pixmaps.
(load_pixmap): New function.
(Fpixmap_spec_p): New function.
(syms_of_xfaces): Set up Lisp function pixmap-spec-p.
Set up Qpixmap_spec_p.
(compute_base_face): Don't set cached_index field.
(compute_base_face): Use FRAME_FOREGROUND_PIXEL,
FRAME_BACKGROUND_PIXEL, FRAME_FONT.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 250732aaefe..e1240de30ad 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -106,6 +106,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 106 | characters. Elements 0 and 1 of computed_faces always describe the | 106 | characters. Elements 0 and 1 of computed_faces always describe the |
| 107 | default and mode-line faces. | 107 | default and mode-line faces. |
| 108 | 108 | ||
| 109 | Each computed face belongs to a particular frame. | ||
| 110 | |||
| 109 | Computed faces have graphics contexts some of the time. | 111 | Computed faces have graphics contexts some of the time. |
| 110 | intern_face builds a GC for a specified computed face | 112 | intern_face builds a GC for a specified computed face |
| 111 | if it doesn't have one already. | 113 | if it doesn't have one already. |
| @@ -147,6 +149,7 @@ int region_face; | |||
| 147 | #define FACE_DEFAULT (~0) | 149 | #define FACE_DEFAULT (~0) |
| 148 | 150 | ||
| 149 | Lisp_Object Qface, Qmouse_face; | 151 | Lisp_Object Qface, Qmouse_face; |
| 152 | Lisp_Object Qpixmap_spec_p; | ||
| 150 | 153 | ||
| 151 | int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ ); | 154 | int face_name_id_number ( /* FRAME_PTR, Lisp_Object name */ ); |
| 152 | 155 | ||
| @@ -183,6 +186,8 @@ copy_face (face) | |||
| 183 | result->background = face->background; | 186 | result->background = face->background; |
| 184 | result->stipple = face->stipple; | 187 | result->stipple = face->stipple; |
| 185 | result->underline = face->underline; | 188 | result->underline = face->underline; |
| 189 | result->pixmap_h = face->pixmap_h; | ||
| 190 | result->pixmap_w = face->pixmap_w; | ||
| 186 | 191 | ||
| 187 | return result; | 192 | return result; |
| 188 | } | 193 | } |
| @@ -234,13 +239,14 @@ intern_face (f, face) | |||
| 234 | xgcv.graphics_exposures = 0; | 239 | xgcv.graphics_exposures = 0; |
| 235 | 240 | ||
| 236 | mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; | 241 | mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; |
| 242 | if (face->stipple && face->stipple != FACE_DEFAULT) | ||
| 243 | xgcv.fill_style = FillStippled; | ||
| 244 | |||
| 237 | gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 245 | gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), |
| 238 | mask, &xgcv); | 246 | mask, &xgcv); |
| 239 | 247 | ||
| 240 | #if 0 | ||
| 241 | if (face->stipple && face->stipple != FACE_DEFAULT) | 248 | if (face->stipple && face->stipple != FACE_DEFAULT) |
| 242 | XSetStipple (FRAME_X_DISPLAY (f), gc, face->stipple); | 249 | XSetStipple (FRAME_X_DISPLAY (f), gc, x_bitmap_pixmap (f, face->stipple)); |
| 243 | #endif | ||
| 244 | 250 | ||
| 245 | face->gc = gc; | 251 | face->gc = gc; |
| 246 | 252 | ||
| @@ -281,7 +287,11 @@ clear_face_cache () | |||
| 281 | UNBLOCK_INPUT; | 287 | UNBLOCK_INPUT; |
| 282 | } | 288 | } |
| 283 | 289 | ||
| 284 | /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ | 290 | /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. |
| 291 | |||
| 292 | These functions operate on param faces only. | ||
| 293 | Computed faces get their fonts, colors and pixmaps | ||
| 294 | by merging param faces. */ | ||
| 285 | 295 | ||
| 286 | static XFontStruct * | 296 | static XFontStruct * |
| 287 | load_font (f, name) | 297 | load_font (f, name) |
| @@ -353,13 +363,6 @@ unload_color (f, pixel) | |||
| 353 | struct frame *f; | 363 | struct frame *f; |
| 354 | unsigned long pixel; | 364 | unsigned long pixel; |
| 355 | { | 365 | { |
| 356 | /* Since faces get built by copying parameters from other faces, the | ||
| 357 | allocation counts for the colors get all screwed up. I don't see | ||
| 358 | any solution that will take less than 10 minutes, and it's better | ||
| 359 | to have a color leak than a crash, so I'm just dyking this out. | ||
| 360 | This isn't really a color leak, anyway - if we ask for it again, | ||
| 361 | we'll get the same pixel. */ | ||
| 362 | #if 0 | ||
| 363 | Colormap cmap; | 366 | Colormap cmap; |
| 364 | Display *dpy = FRAME_X_DISPLAY (f); | 367 | Display *dpy = FRAME_X_DISPLAY (f); |
| 365 | if (pixel == FACE_DEFAULT | 368 | if (pixel == FACE_DEFAULT |
| @@ -370,7 +373,85 @@ unload_color (f, pixel) | |||
| 370 | BLOCK_INPUT; | 373 | BLOCK_INPUT; |
| 371 | XFreeColors (dpy, cmap, &pixel, 1, 0); | 374 | XFreeColors (dpy, cmap, &pixel, 1, 0); |
| 372 | UNBLOCK_INPUT; | 375 | UNBLOCK_INPUT; |
| 373 | #endif | 376 | } |
| 377 | |||
| 378 | DEFUN ("pixmap-spec-p", Fpixmap_spec_p, Spixmap_spec_p, 1, 1, 0, | ||
| 379 | "Return t if ARG is a valid pixmap specification.") | ||
| 380 | (arg) | ||
| 381 | Lisp_Object arg; | ||
| 382 | { | ||
| 383 | Lisp_Object height, width; | ||
| 384 | |||
| 385 | return ((STRINGP (arg) | ||
| 386 | || (CONSP (arg) | ||
| 387 | && CONSP (Fcdr (arg)) | ||
| 388 | && CONSP (Fcdr (Fcdr (arg))) | ||
| 389 | && NILP (Fcdr (Fcdr (Fcdr (arg)))) | ||
| 390 | && INTEGERP (width = Fcar (arg)) | ||
| 391 | && INTEGERP (height = Fcar (Fcdr (arg))) | ||
| 392 | && STRINGP (Fcar (Fcdr (Fcdr (arg)))) | ||
| 393 | && XINT (width) > 0 | ||
| 394 | && XINT (height) > 0 | ||
| 395 | /* The string must have enough bits for width * height. */ | ||
| 396 | && (XINT (width) * XINT (height) | ||
| 397 | <= (XSTRING (Fcar (Fcdr (Fcdr (arg))))->size | ||
| 398 | * (INTBITS / sizeof (int)))))) | ||
| 399 | ? Qt : Qnil); | ||
| 400 | } | ||
| 401 | |||
| 402 | /* Load a bitmap according to NAME (which is either a file name | ||
| 403 | or a pixmap spec). Return the bitmap_id (see xfns.c) | ||
| 404 | or get an error if NAME is invalid. | ||
| 405 | |||
| 406 | Store the bitmap width in *W_PTR and height in *H_PTR. */ | ||
| 407 | |||
| 408 | static long | ||
| 409 | load_pixmap (f, name, w_ptr, h_ptr) | ||
| 410 | FRAME_PTR *f; | ||
| 411 | Lisp_Object name; | ||
| 412 | unsigned int *w_ptr, *h_ptr; | ||
| 413 | { | ||
| 414 | int bitmap_id; | ||
| 415 | Lisp_Object tem; | ||
| 416 | |||
| 417 | if (NILP (name)) | ||
| 418 | return FACE_DEFAULT; | ||
| 419 | |||
| 420 | tem = Fpixmap_spec_p (name); | ||
| 421 | if (NILP (tem)) | ||
| 422 | wrong_type_argument (Qpixmap_spec_p, name); | ||
| 423 | |||
| 424 | BLOCK_INPUT; | ||
| 425 | |||
| 426 | if (CONSP (name)) | ||
| 427 | { | ||
| 428 | /* Decode a bitmap spec into a bitmap. */ | ||
| 429 | |||
| 430 | int h, w; | ||
| 431 | Lisp_Object bits; | ||
| 432 | |||
| 433 | w = XINT (Fcar (name)); | ||
| 434 | h = XINT (Fcar (Fcdr (name))); | ||
| 435 | bits = Fcar (Fcdr (Fcdr (name))); | ||
| 436 | |||
| 437 | bitmap_id = x_create_bitmap_from_data (f, XSTRING (bits)->data, | ||
| 438 | w, h); | ||
| 439 | } | ||
| 440 | else | ||
| 441 | { | ||
| 442 | /* It must be a string -- a file name. */ | ||
| 443 | bitmap_id = x_create_bitmap_from_file (f, name); | ||
| 444 | } | ||
| 445 | UNBLOCK_INPUT; | ||
| 446 | |||
| 447 | if (! bitmap_id) | ||
| 448 | Fsignal (Qerror, Fcons (build_string ("undefined bitmap"), | ||
| 449 | Fcons (name, Qnil))); | ||
| 450 | |||
| 451 | *w_ptr = x_bitmap_width (f, bitmap_id); | ||
| 452 | *h_ptr = x_bitmap_height (f, bitmap_id); | ||
| 453 | |||
| 454 | return bitmap_id; | ||
| 374 | } | 455 | } |
| 375 | 456 | ||
| 376 | /* Managing parameter face arrays for frames. */ | 457 | /* Managing parameter face arrays for frames. */ |
| @@ -421,6 +502,7 @@ init_frame_faces (f) | |||
| 421 | 502 | ||
| 422 | 503 | ||
| 423 | /* Called from Fdelete_frame. */ | 504 | /* Called from Fdelete_frame. */ |
| 505 | |||
| 424 | void | 506 | void |
| 425 | free_frame_faces (f) | 507 | free_frame_faces (f) |
| 426 | struct frame *f; | 508 | struct frame *f; |
| @@ -438,9 +520,7 @@ free_frame_faces (f) | |||
| 438 | unload_font (f, face->font); | 520 | unload_font (f, face->font); |
| 439 | unload_color (f, face->foreground); | 521 | unload_color (f, face->foreground); |
| 440 | unload_color (f, face->background); | 522 | unload_color (f, face->background); |
| 441 | #if 0 | 523 | x_destroy_bitmap (f, face->stipple); |
| 442 | unload_pixmap (f, face->stipple); | ||
| 443 | #endif | ||
| 444 | xfree (face); | 524 | xfree (face); |
| 445 | } | 525 | } |
| 446 | } | 526 | } |
| @@ -604,7 +684,11 @@ merge_faces (from, to) | |||
| 604 | if (from->background != FACE_DEFAULT) | 684 | if (from->background != FACE_DEFAULT) |
| 605 | to->background = from->background; | 685 | to->background = from->background; |
| 606 | if (from->stipple != FACE_DEFAULT) | 686 | if (from->stipple != FACE_DEFAULT) |
| 607 | to->stipple = from->stipple; | 687 | { |
| 688 | to->stipple = from->stipple; | ||
| 689 | to->pixmap_h = from->pixmap_h; | ||
| 690 | to->pixmap_w = from->pixmap_w; | ||
| 691 | } | ||
| 608 | if (from->underline) | 692 | if (from->underline) |
| 609 | to->underline = from->underline; | 693 | to->underline = from->underline; |
| 610 | } | 694 | } |
| @@ -617,17 +701,12 @@ compute_base_face (f, face) | |||
| 617 | FRAME_PTR f; | 701 | FRAME_PTR f; |
| 618 | struct face *face; | 702 | struct face *face; |
| 619 | { | 703 | { |
| 620 | struct x_display *d = f->display.x; | ||
| 621 | |||
| 622 | face->gc = 0; | 704 | face->gc = 0; |
| 623 | face->foreground = d->foreground_pixel; | 705 | face->foreground = FRAME_FOREGROUND_PIXEL (f); |
| 624 | face->background = d->background_pixel; | 706 | face->background = FRAME_BACKGROUND_PIXEL (f); |
| 625 | face->font = d->font; | 707 | face->font = FRAME_FONT (f); |
| 626 | face->stipple = 0; | 708 | face->stipple = 0; |
| 627 | face->underline = 0; | 709 | face->underline = 0; |
| 628 | |||
| 629 | /* Avoid a face comparison by making this invalid. */ | ||
| 630 | face->cached_index = -1; | ||
| 631 | } | 710 | } |
| 632 | 711 | ||
| 633 | /* Return the face ID to use to display a special glyph which selects | 712 | /* Return the face ID to use to display a special glyph which selects |
| @@ -990,20 +1069,16 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal, | |||
| 990 | face->background = new_color; | 1069 | face->background = new_color; |
| 991 | garbaged = 1; | 1070 | garbaged = 1; |
| 992 | } | 1071 | } |
| 993 | #if 0 | ||
| 994 | else if (EQ (attr_name, intern ("background-pixmap"))) | 1072 | else if (EQ (attr_name, intern ("background-pixmap"))) |
| 995 | { | 1073 | { |
| 996 | unsigned int w, h, d; | 1074 | unsigned int w, h; |
| 997 | unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0); | 1075 | unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h); |
| 998 | unload_pixmap (f, face->stipple); | 1076 | x_destroy_bitmap (f, face->stipple); |
| 999 | if (NILP (attr_value)) | ||
| 1000 | new_pixmap = 0; | ||
| 1001 | face->stipple = new_pixmap; | 1077 | face->stipple = new_pixmap; |
| 1002 | face->pixmap_w = w; | 1078 | face->pixmap_w = w; |
| 1003 | face->pixmap_h = h; | 1079 | face->pixmap_h = h; |
| 1004 | /* face->pixmap_depth = d; */ | 1080 | garbaged = 1; |
| 1005 | } | 1081 | } |
| 1006 | #endif /* 0 */ | ||
| 1007 | else if (EQ (attr_name, intern ("underline"))) | 1082 | else if (EQ (attr_name, intern ("underline"))) |
| 1008 | { | 1083 | { |
| 1009 | int new = !NILP (attr_value); | 1084 | int new = !NILP (attr_value); |
| @@ -1063,12 +1138,15 @@ syms_of_xfaces () | |||
| 1063 | staticpro (&Qface); | 1138 | staticpro (&Qface); |
| 1064 | Qmouse_face = intern ("mouse-face"); | 1139 | Qmouse_face = intern ("mouse-face"); |
| 1065 | staticpro (&Qmouse_face); | 1140 | staticpro (&Qmouse_face); |
| 1141 | Qpixmap_spec_p = intern ("pixmap-spec-p"); | ||
| 1142 | staticpro (&Qpixmap_spec_p); | ||
| 1066 | 1143 | ||
| 1067 | DEFVAR_INT ("region-face", ®ion_face, | 1144 | DEFVAR_INT ("region-face", ®ion_face, |
| 1068 | "Face number to use to highlight the region\n\ | 1145 | "Face number to use to highlight the region\n\ |
| 1069 | The region is highlighted with this face\n\ | 1146 | The region is highlighted with this face\n\ |
| 1070 | when Transient Mark mode is enabled and the mark is active."); | 1147 | when Transient Mark mode is enabled and the mark is active."); |
| 1071 | 1148 | ||
| 1149 | defsubr (&Spixmap_spec_p); | ||
| 1072 | defsubr (&Sframe_face_alist); | 1150 | defsubr (&Sframe_face_alist); |
| 1073 | defsubr (&Sset_frame_face_alist); | 1151 | defsubr (&Sset_frame_face_alist); |
| 1074 | defsubr (&Smake_face_internal); | 1152 | defsubr (&Smake_face_internal); |