diff options
| author | Jim Blandy | 1993-03-27 18:32:23 +0000 |
|---|---|---|
| committer | Jim Blandy | 1993-03-27 18:32:23 +0000 |
| commit | f211082d1e08fc2efdd7aa996bc19dfc24449de2 (patch) | |
| tree | 8f18d233f5a2f4db1e9611cfd541fcdaa7b83917 /src | |
| parent | 440d350c2fda4add5c37ed0dfd9684c9113197ae (diff) | |
| download | emacs-f211082d1e08fc2efdd7aa996bc19dfc24449de2.tar.gz emacs-f211082d1e08fc2efdd7aa996bc19dfc24449de2.zip | |
*** empty log message ***
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 336 |
1 files changed, 205 insertions, 131 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 8f17bcce7e3..6d946059760 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -1,6 +1,3 @@ | |||
| 1 | /* Must define frame->faces, frame->n_faces, | ||
| 2 | FRAME_NORMAL_FACE, FRAME_MODELINE_FACE. */ | ||
| 3 | |||
| 4 | /* "Face" primitives | 1 | /* "Face" primitives |
| 5 | Copyright (C) 1992, 1993 Free Software Foundation. | 2 | Copyright (C) 1992, 1993 Free Software Foundation. |
| 6 | 3 | ||
| @@ -20,18 +17,7 @@ You should have received a copy of the GNU General Public License | |||
| 20 | along with GNU Emacs; see the file COPYING. If not, write to | 17 | along with GNU Emacs; see the file COPYING. If not, write to |
| 21 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | 18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
| 22 | 19 | ||
| 23 | struct face | 20 | /* This derived from work by Lucid (some parts very loosely so). */ |
| 24 | { | ||
| 25 | unsigned char underline; | ||
| 26 | unsigned char hilited; | ||
| 27 | unsigned char modif; | ||
| 28 | GC facegc; | ||
| 29 | XFontStruct * font; | ||
| 30 | unsigned long foreground; | ||
| 31 | unsigned long background; | ||
| 32 | Pixmap back_pixmap; | ||
| 33 | unsigned int pixmap_w, pixmap_h /* , pixmap_depth */; | ||
| 34 | }; | ||
| 35 | 21 | ||
| 36 | #include <sys/types.h> | 22 | #include <sys/types.h> |
| 37 | #include <sys/stat.h> | 23 | #include <sys/stat.h> |
| @@ -41,9 +27,9 @@ struct face | |||
| 41 | 27 | ||
| 42 | #include "xterm.h" | 28 | #include "xterm.h" |
| 43 | #include "buffer.h" | 29 | #include "buffer.h" |
| 30 | #include "dispextern.h" | ||
| 44 | #include "frame.h" | 31 | #include "frame.h" |
| 45 | #include "window.h" | 32 | /* #include "window.h" */ |
| 46 | #include "indent.h" | ||
| 47 | 33 | ||
| 48 | /* Display Context for the icons */ | 34 | /* Display Context for the icons */ |
| 49 | #include <X11/Intrinsic.h> | 35 | #include <X11/Intrinsic.h> |
| @@ -52,8 +38,8 @@ struct face | |||
| 52 | #include <X11/Xos.h> | 38 | #include <X11/Xos.h> |
| 53 | 39 | ||
| 54 | /* We use face structures in two ways: | 40 | /* We use face structures in two ways: |
| 55 | At the frame level, each frame has a vector of faces. (f->faces). | 41 | At the frame level, each frame has a vector of faces (FRAME_FACES). |
| 56 | Face number 0 is the normal face (for normal text). | 42 | Face number 0 is the default face (for normal text). |
| 57 | Face number 1 is the mode line face. | 43 | Face number 1 is the mode line face. |
| 58 | Higher face numbers have no built-in meaning. | 44 | Higher face numbers have no built-in meaning. |
| 59 | The faces in these vectors are called "frame faces". | 45 | The faces in these vectors are called "frame faces". |
| @@ -81,8 +67,15 @@ int next_face_id; | |||
| 81 | 67 | ||
| 82 | #define FACE_DEFAULT (~0) | 68 | #define FACE_DEFAULT (~0) |
| 83 | 69 | ||
| 70 | #define xfree free | ||
| 71 | |||
| 72 | Lisp_Object Qface, Qwindow, Qpriority; | ||
| 73 | |||
| 84 | static struct face *allocate_face (); | 74 | static struct face *allocate_face (); |
| 85 | static void build_face (); | 75 | static void build_face (); |
| 76 | static int sort_overlays (); | ||
| 77 | static struct face *get_display_face (); | ||
| 78 | static Lisp_Object face_name_id_number (); | ||
| 86 | 79 | ||
| 87 | /* Make a new face that's a copy of an existing one. */ | 80 | /* Make a new face that's a copy of an existing one. */ |
| 88 | 81 | ||
| @@ -95,7 +88,7 @@ copy_face (face) | |||
| 95 | result->font = face->font; | 88 | result->font = face->font; |
| 96 | result->foreground = face->foreground; | 89 | result->foreground = face->foreground; |
| 97 | result->background = face->background; | 90 | result->background = face->background; |
| 98 | result->back_pixmap = face->back_pixmap; | 91 | result->stipple = face->stipple; |
| 99 | result->underline = face->underline; | 92 | result->underline = face->underline; |
| 100 | 93 | ||
| 101 | return result; | 94 | return result; |
| @@ -108,7 +101,7 @@ face_eql (face1, face2) | |||
| 108 | return (face1->font == face2->font | 101 | return (face1->font == face2->font |
| 109 | && face1->foreground == face2->foreground | 102 | && face1->foreground == face2->foreground |
| 110 | && face1->background == face2->background | 103 | && face1->background == face2->background |
| 111 | && face1->back_pixmap == face2->back_pixmap | 104 | && face1->stipple == face2->stipple |
| 112 | && face1->underline == face2->underline); | 105 | && face1->underline == face2->underline); |
| 113 | } | 106 | } |
| 114 | 107 | ||
| @@ -123,6 +116,7 @@ get_cached_face (f, face) | |||
| 123 | struct face *face; | 116 | struct face *face; |
| 124 | { | 117 | { |
| 125 | int i, empty = -1; | 118 | int i, empty = -1; |
| 119 | struct face *result; | ||
| 126 | 120 | ||
| 127 | /* Look for an existing display face that does the job. | 121 | /* Look for an existing display face that does the job. |
| 128 | Also find an empty slot if any. */ | 122 | Also find an empty slot if any. */ |
| @@ -167,14 +161,15 @@ clear_face_vector () | |||
| 167 | { | 161 | { |
| 168 | Lisp_Object rest; | 162 | Lisp_Object rest; |
| 169 | Display *dpy = x_current_display; | 163 | Display *dpy = x_current_display; |
| 164 | int i; | ||
| 170 | 165 | ||
| 171 | BLOCK_INPUT; | 166 | BLOCK_INPUT; |
| 172 | /* Free the display faces in the face_vector. */ | 167 | /* Free the display faces in the face_vector. */ |
| 173 | for (i = 0; i < nfaces; i++) | 168 | for (i = 0; i < nfaces; i++) |
| 174 | { | 169 | { |
| 175 | struct face *face = face_vector[i]; | 170 | struct face *face = face_vector[i]; |
| 176 | if (face->facegc) | 171 | if (face->gc) |
| 177 | XFreeGC (dpy, face->facegc); | 172 | XFreeGC (dpy, face->gc); |
| 178 | xfree (face); | 173 | xfree (face); |
| 179 | } | 174 | } |
| 180 | nfaces = 0; | 175 | nfaces = 0; |
| @@ -182,7 +177,8 @@ clear_face_vector () | |||
| 182 | UNBLOCK_INPUT; | 177 | UNBLOCK_INPUT; |
| 183 | } | 178 | } |
| 184 | 179 | ||
| 185 | /* Make a graphics context for face FACE, which is on frame F. */ | 180 | /* Make a graphics context for face FACE, which is on frame F, |
| 181 | if that can be done. */ | ||
| 186 | 182 | ||
| 187 | static void | 183 | static void |
| 188 | build_face (f, face) | 184 | build_face (f, face) |
| @@ -193,18 +189,27 @@ build_face (f, face) | |||
| 193 | XGCValues xgcv; | 189 | XGCValues xgcv; |
| 194 | unsigned long mask; | 190 | unsigned long mask; |
| 195 | 191 | ||
| 196 | xgcv.foreground = face->foreground; | 192 | if (face->foreground != FACE_DEFAULT) |
| 197 | xgcv.background = face->background; | 193 | xgcv.foreground = face->foreground; |
| 198 | xgcv.font = face->font->fid; | 194 | else |
| 195 | xgcv. foreground = f->display.x->foreground_pixel; | ||
| 196 | if (face->background != FACE_DEFAULT) | ||
| 197 | xgcv.background = face->background; | ||
| 198 | else | ||
| 199 | xgcv. background = f->display.x->background_pixel; | ||
| 200 | if (face->font && (int) face->font != FACE_DEFAULT) | ||
| 201 | xgcv.font = face->font->fid; | ||
| 202 | else | ||
| 203 | xgcv.font = f->display.x->font->fid; | ||
| 199 | xgcv.graphics_exposures = 0; | 204 | xgcv.graphics_exposures = 0; |
| 200 | mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; | 205 | mask = GCForeground | GCBackground | GCFont | GCGraphicsExposures; |
| 201 | gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), | 206 | gc = XCreateGC (x_current_display, FRAME_X_WINDOW (f), |
| 202 | mask, &xgcv); | 207 | mask, &xgcv); |
| 203 | #if 0 | 208 | #if 0 |
| 204 | if (face->back_pixmap && face->back_pixmap != FACE_DEFAULT) | 209 | if (face->stipple && face->stipple != FACE_DEFAULT) |
| 205 | XSetStipple (XtDisplay (f->display.x->widget), gc, face->back_pixmap); | 210 | XSetStipple (x_current_display, gc, face->stipple); |
| 206 | #endif | 211 | #endif |
| 207 | face->facegc = gc; | 212 | face->gc = gc; |
| 208 | } | 213 | } |
| 209 | 214 | ||
| 210 | /* Modify face TO by copying from FROM all properties which have | 215 | /* Modify face TO by copying from FROM all properties which have |
| @@ -222,20 +227,28 @@ merge_faces (from, to) | |||
| 222 | to->foreground = from->foreground; | 227 | to->foreground = from->foreground; |
| 223 | if (from->background != FACE_DEFAULT) | 228 | if (from->background != FACE_DEFAULT) |
| 224 | to->background = from->background; | 229 | to->background = from->background; |
| 225 | if (from->back_pixmap != FACE_DEFAULT) | 230 | if (from->stipple != FACE_DEFAULT) |
| 226 | to->back_pixmap = from->back_pixmap; | 231 | to->stipple = from->stipple; |
| 227 | if (from->underline) | 232 | if (from->underline) |
| 228 | to->underline = from->underline; | 233 | to->underline = from->underline; |
| 229 | } | 234 | } |
| 230 | 235 | ||
| 236 | struct sortvec | ||
| 237 | { | ||
| 238 | Lisp_Object overlay; | ||
| 239 | int beg, end; | ||
| 240 | int priority; | ||
| 241 | }; | ||
| 242 | |||
| 231 | /* Return the display face associated with a buffer position POS. | 243 | /* Return the display face associated with a buffer position POS. |
| 232 | Store into *ENDPTR the position at which a different face is needed. | 244 | Store into *ENDPTR the position at which a different face is needed. |
| 233 | This does not take account of glyphs that specify their own face codes. | 245 | This does not take account of glyphs that specify their own face codes. |
| 234 | F is the frame in use for display. */ | 246 | F is the frame in use for display, and W is the window. */ |
| 235 | 247 | ||
| 236 | struct face * | 248 | struct face * |
| 237 | compute_char_face (f, pos, endptr) | 249 | compute_char_face (f, w, pos, endptr) |
| 238 | struct frame *f; | 250 | struct frame *f; |
| 251 | struct window *w; | ||
| 239 | int pos; | 252 | int pos; |
| 240 | int *endptr; | 253 | int *endptr; |
| 241 | { | 254 | { |
| @@ -247,6 +260,10 @@ compute_char_face (f, pos, endptr) | |||
| 247 | int endpos; | 260 | int endpos; |
| 248 | Lisp_Object *overlay_vec; | 261 | Lisp_Object *overlay_vec; |
| 249 | int len; | 262 | int len; |
| 263 | struct sortvec *sortvec; | ||
| 264 | Lisp_Object frame; | ||
| 265 | |||
| 266 | XSET (frame, Lisp_Frame, f); | ||
| 250 | 267 | ||
| 251 | XFASTINT (position) = pos; | 268 | XFASTINT (position) = pos; |
| 252 | prop = Fget_text_property (position, Qface); | 269 | prop = Fget_text_property (position, Qface); |
| @@ -257,18 +274,21 @@ compute_char_face (f, pos, endptr) | |||
| 257 | 274 | ||
| 258 | /* Optimize the default case. */ | 275 | /* Optimize the default case. */ |
| 259 | if (noverlays == 0 && NILP (prop)) | 276 | if (noverlays == 0 && NILP (prop)) |
| 260 | return FRAME_NORMAL_FACE (f); | 277 | return FRAME_DEFAULT_FACE (f); |
| 261 | 278 | ||
| 262 | bcopy (FRAME_NORMAL_FACE (f), &face, sizeof (struct face)); | 279 | bcopy (FRAME_DEFAULT_FACE (f), &face, sizeof (struct face)); |
| 263 | 280 | ||
| 264 | if (!NILP (prop)) | 281 | if (!NILP (prop)) |
| 265 | { | 282 | { |
| 266 | facecode = Fface_name_id_number (prop); | 283 | facecode = face_name_id_number (frame, prop); |
| 267 | if (facecode >= 0 && facecode < f->n_faces && f->faces[facecode] != 0) | 284 | if (facecode >= 0 && facecode < FRAME_N_FACES (f) |
| 268 | merge_faces (f->faces[facecode], &face); | 285 | && FRAME_FACES (f) [facecode] != 0) |
| 286 | merge_faces (FRAME_FACES (f) [facecode], &face); | ||
| 269 | } | 287 | } |
| 270 | 288 | ||
| 271 | /* Discard invalid overlays from the vector. */ | 289 | /* Put the valid and relevant overlays into sortvec. */ |
| 290 | sortvec = (struct sortvec *) alloca (noverlays * sizeof (struct sortvec)); | ||
| 291 | |||
| 272 | for (i = 0, j = 0; i < noverlays; i++) | 292 | for (i = 0, j = 0; i < noverlays; i++) |
| 273 | { | 293 | { |
| 274 | overlay = overlay_vec[i]; | 294 | overlay = overlay_vec[i]; |
| @@ -276,11 +296,35 @@ compute_char_face (f, pos, endptr) | |||
| 276 | if (OVERLAY_VALID (overlay) | 296 | if (OVERLAY_VALID (overlay) |
| 277 | && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 | 297 | && OVERLAY_POSITION (OVERLAY_START (overlay)) > 0 |
| 278 | && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) | 298 | && OVERLAY_POSITION (OVERLAY_END (overlay)) > 0) |
| 279 | overlay_vec[j++] = overlay; | 299 | { |
| 300 | Lisp_Object window; | ||
| 301 | window = Foverlay_get (overlay, Qwindow); | ||
| 302 | |||
| 303 | /* Also ignore overlays limited to one window | ||
| 304 | if it's not the window we are using. */ | ||
| 305 | if (NILP (window) || XWINDOW (window) == w) | ||
| 306 | { | ||
| 307 | Lisp_Object tem; | ||
| 308 | |||
| 309 | /* This overlay is good and counts: | ||
| 310 | put it in sortvec. */ | ||
| 311 | sortvec[j].overlay = overlay; | ||
| 312 | sortvec[j].beg = OVERLAY_POSITION (OVERLAY_START (overlay)); | ||
| 313 | sortvec[j].end = OVERLAY_POSITION (OVERLAY_END (overlay)); | ||
| 314 | tem = Foverlay_get (overlay, Qpriority); | ||
| 315 | if (INTEGERP (tem)) | ||
| 316 | sortvec[j].priority = XINT (tem); | ||
| 317 | else | ||
| 318 | sortvec[j].priority = 0; | ||
| 319 | j++; | ||
| 320 | } | ||
| 321 | } | ||
| 280 | } | 322 | } |
| 281 | noverlays = j; | 323 | noverlays = j; |
| 282 | 324 | ||
| 283 | /* Sort the overlays into the proper order. */ | 325 | /* Sort the overlays into the proper order: increasing priority. */ |
| 326 | |||
| 327 | qsort (sortvec, noverlays, sizeof (struct sortvec), sort_overlays); | ||
| 284 | 328 | ||
| 285 | /* Now merge the overlay data in that order. */ | 329 | /* Now merge the overlay data in that order. */ |
| 286 | 330 | ||
| @@ -292,10 +336,10 @@ compute_char_face (f, pos, endptr) | |||
| 292 | Lisp_Object oend; | 336 | Lisp_Object oend; |
| 293 | int oendpos; | 337 | int oendpos; |
| 294 | 338 | ||
| 295 | facecode = Fface_name_id_number (prop); | 339 | facecode = face_name_id_number (frame, prop); |
| 296 | if (facecode >= 0 && facecode < f->n_faces | 340 | if (facecode >= 0 && facecode < FRAME_N_FACES (f) |
| 297 | && f->faces[facecode] != 0) | 341 | && FRAME_FACES (f) [facecode] != 0) |
| 298 | merge_faces (f->faces[facecode], &face); | 342 | merge_faces (FRAME_FACES (f) [facecode], &face); |
| 299 | 343 | ||
| 300 | oend = OVERLAY_END (overlay_vec[i]); | 344 | oend = OVERLAY_END (overlay_vec[i]); |
| 301 | oendpos = OVERLAY_POSITION (oend); | 345 | oendpos = OVERLAY_POSITION (oend); |
| @@ -311,6 +355,19 @@ compute_char_face (f, pos, endptr) | |||
| 311 | return get_display_face (f, &face); | 355 | return get_display_face (f, &face); |
| 312 | } | 356 | } |
| 313 | 357 | ||
| 358 | int | ||
| 359 | sort_overlays (s1, s2) | ||
| 360 | struct sortvec *s1, *s2; | ||
| 361 | { | ||
| 362 | if (s1->priority != s2->priority) | ||
| 363 | return s1->priority - s2->priority; | ||
| 364 | if (s1->beg != s2->beg) | ||
| 365 | return s1->beg - s2->beg; | ||
| 366 | if (s1->end != s2->end) | ||
| 367 | return s2->end - s1->end; | ||
| 368 | return 0; | ||
| 369 | } | ||
| 370 | |||
| 314 | /* Return the display face to use to display a special glyph | 371 | /* Return the display face to use to display a special glyph |
| 315 | which selects FACE_CODE as the face ID, | 372 | which selects FACE_CODE as the face ID, |
| 316 | assuming that ordinarily the face would be BASIC_FACE. | 373 | assuming that ordinarily the face would be BASIC_FACE. |
| @@ -326,8 +383,9 @@ compute_glyph_face (f, basic_face, face_code) | |||
| 326 | 383 | ||
| 327 | bcopy (basic_face, &face, sizeof (struct face)); | 384 | bcopy (basic_face, &face, sizeof (struct face)); |
| 328 | 385 | ||
| 329 | if (face_code >= 0 && face_code < f->n_faces && f->faces[face_code] != 0) | 386 | if (face_code >= 0 && face_code < FRAME_N_FACES (f) |
| 330 | merge_faces (f->faces[face_code], &face); | 387 | && FRAME_FACES (f) [face_code] != 0) |
| 388 | merge_faces (FRAME_FACES (f) [face_code], &face); | ||
| 331 | 389 | ||
| 332 | return get_display_face (f, &face); | 390 | return get_display_face (f, &face); |
| 333 | } | 391 | } |
| @@ -343,31 +401,31 @@ get_display_face (f, face) | |||
| 343 | struct face *result; | 401 | struct face *result; |
| 344 | 402 | ||
| 345 | /* Does the face have a GC already? */ | 403 | /* Does the face have a GC already? */ |
| 346 | if (face->facegc) | 404 | if (face->gc) |
| 347 | return face; | 405 | return face; |
| 348 | 406 | ||
| 349 | /* If it's equivalent to the normal face, use that. */ | 407 | /* If it's equivalent to the default face, use that. */ |
| 350 | if (face->font == FRAME_NORMAL_FACE (f)->font | 408 | if (face->font == FRAME_DEFAULT_FACE (f)->font |
| 351 | && face->foreground == FRAME_NORMAL_FACE (f)->foreground | 409 | && face->foreground == FRAME_DEFAULT_FACE (f)->foreground |
| 352 | && face->background == FRAME_NORMAL_FACE (f)->background | 410 | && face->background == FRAME_DEFAULT_FACE (f)->background |
| 353 | && face->back_pixmap == FRAME_NORMAL_FACE (f)->back_pixmap | 411 | && face->stipple == FRAME_DEFAULT_FACE (f)->stipple |
| 354 | && face->underline == FRAME_NORMAL_FACE (f)->underline) | 412 | && face->underline == FRAME_DEFAULT_FACE (f)->underline) |
| 355 | { | 413 | { |
| 356 | if (!FRAME_NORMAL_FACE (f)->framegc) | 414 | if (!FRAME_DEFAULT_FACE (f)->gc) |
| 357 | build_frame (f, FRAME_NORMAL_FACE (f)); | 415 | build_face (f, FRAME_DEFAULT_FACE (f)); |
| 358 | return FRAME_NORMAL_FACE (f); | 416 | return FRAME_DEFAULT_FACE (f); |
| 359 | } | 417 | } |
| 360 | 418 | ||
| 361 | /* If it's equivalent to the mode line face, use that. */ | 419 | /* If it's equivalent to the mode line face, use that. */ |
| 362 | if (face->font == FRAME_MODELINE_FACE (f)->font | 420 | if (face->font == FRAME_MODE_LINE_FACE (f)->font |
| 363 | && face->foreground == FRAME_MODELINE_FACE (f)->foreground | 421 | && face->foreground == FRAME_MODE_LINE_FACE (f)->foreground |
| 364 | && face->background == FRAME_MODELINE_FACE (f)->background | 422 | && face->background == FRAME_MODE_LINE_FACE (f)->background |
| 365 | && face->back_pixmap == FRAME_MODELINE_FACE (f)->back_pixmap | 423 | && face->stipple == FRAME_MODE_LINE_FACE (f)->stipple |
| 366 | && face->underline == FRAME_MODELINE_FACE (f)->underline) | 424 | && face->underline == FRAME_MODE_LINE_FACE (f)->underline) |
| 367 | { | 425 | { |
| 368 | if (!FRAME_MODELINE_FACE (f)->framegc) | 426 | if (!FRAME_MODE_LINE_FACE (f)->gc) |
| 369 | build_frame (f, FRAME_MODELINE_FACE (f)); | 427 | build_face (f, FRAME_MODE_LINE_FACE (f)); |
| 370 | return FRAME_MODELINE_FACE (f); | 428 | return FRAME_MODE_LINE_FACE (f); |
| 371 | } | 429 | } |
| 372 | 430 | ||
| 373 | /* Get a specialized display face. */ | 431 | /* Get a specialized display face. */ |
| @@ -384,7 +442,7 @@ allocate_face () | |||
| 384 | result->font = (XFontStruct *) FACE_DEFAULT; | 442 | result->font = (XFontStruct *) FACE_DEFAULT; |
| 385 | result->foreground = FACE_DEFAULT; | 443 | result->foreground = FACE_DEFAULT; |
| 386 | result->background = FACE_DEFAULT; | 444 | result->background = FACE_DEFAULT; |
| 387 | result->back_pixmap = FACE_DEFAULT; | 445 | result->stipple = FACE_DEFAULT; |
| 388 | return result; | 446 | return result; |
| 389 | } | 447 | } |
| 390 | 448 | ||
| @@ -395,20 +453,25 @@ ensure_face_ready (f, id) | |||
| 395 | struct frame *f; | 453 | struct frame *f; |
| 396 | int id; | 454 | int id; |
| 397 | { | 455 | { |
| 398 | if (f->n_faces <= id) | 456 | if (FRAME_N_FACES (f) <= id) |
| 399 | { | 457 | { |
| 400 | int n = id + 10; | 458 | int n = id + 10; |
| 401 | int i; | 459 | int i; |
| 402 | if (!f->n_faces) | 460 | if (!FRAME_N_FACES (f)) |
| 403 | f->faces = (struct face **) xmalloc (sizeof (struct face *) * n); | 461 | FRAME_FACES (f) |
| 462 | = (struct face **) xmalloc (sizeof (struct face *) * n); | ||
| 404 | else | 463 | else |
| 405 | f->faces | 464 | FRAME_FACES (f) |
| 406 | = (struct face **) xrealloc (f->faces, sizeof (struct face *) * n); | 465 | = (struct face **) xrealloc (FRAME_FACES (f), |
| 466 | sizeof (struct face *) * n); | ||
| 407 | 467 | ||
| 408 | f->n_faces = n; | 468 | bzero (FRAME_FACES (f) + FRAME_N_FACES (f), |
| 469 | (n - FRAME_N_FACES (f)) * sizeof (struct face *)); | ||
| 470 | FRAME_N_FACES (f) = n; | ||
| 409 | } | 471 | } |
| 410 | 472 | ||
| 411 | f->faces[id] = allocate_face (); | 473 | if (FRAME_FACES (f) [id] == 0) |
| 474 | FRAME_FACES (f) [id] = allocate_face (); | ||
| 412 | } | 475 | } |
| 413 | 476 | ||
| 414 | /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ | 477 | /* Allocating, freeing, and duplicating fonts, colors, and pixmaps. */ |
| @@ -459,7 +522,7 @@ load_color (f, name) | |||
| 459 | if (NILP (name)) | 522 | if (NILP (name)) |
| 460 | return FACE_DEFAULT; | 523 | return FACE_DEFAULT; |
| 461 | 524 | ||
| 462 | cmap = DefaultColormapOfScreen (x_screen); | 525 | cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); |
| 463 | 526 | ||
| 464 | CHECK_STRING (name, 0); | 527 | CHECK_STRING (name, 0); |
| 465 | BLOCK_INPUT; | 528 | BLOCK_INPUT; |
| @@ -486,7 +549,7 @@ unload_color (f, pixel) | |||
| 486 | Display *dpy = x_current_display; | 549 | Display *dpy = x_current_display; |
| 487 | if (pixel == FACE_DEFAULT) | 550 | if (pixel == FACE_DEFAULT) |
| 488 | return; | 551 | return; |
| 489 | cmap = DefaultColormapOfScreen (x_screen); | 552 | cmap = DefaultColormapOfScreen (DefaultScreenOfDisplay (x_current_display)); |
| 490 | BLOCK_INPUT; | 553 | BLOCK_INPUT; |
| 491 | XFreeColors (dpy, cmap, &pixel, 1, 0); | 554 | XFreeColors (dpy, cmap, &pixel, 1, 0); |
| 492 | UNBLOCK_INPUT; | 555 | UNBLOCK_INPUT; |
| @@ -499,7 +562,7 @@ unload_color (f, pixel) | |||
| 499 | 562 | ||
| 500 | void | 563 | void |
| 501 | init_frame_faces (f) | 564 | init_frame_faces (f) |
| 502 | struct frame f; | 565 | struct frame *f; |
| 503 | { | 566 | { |
| 504 | struct frame *other_frame = 0; | 567 | struct frame *other_frame = 0; |
| 505 | Lisp_Object rest; | 568 | Lisp_Object rest; |
| @@ -507,7 +570,7 @@ init_frame_faces (f) | |||
| 507 | for (rest = Vframe_list; !NILP (rest); rest = Fcdr (rest)) | 570 | for (rest = Vframe_list; !NILP (rest); rest = Fcdr (rest)) |
| 508 | { | 571 | { |
| 509 | struct frame *f2 = XFRAME (Fcar (rest)); | 572 | struct frame *f2 = XFRAME (Fcar (rest)); |
| 510 | if (f2 != f && FRAME_IS_X (f2)) | 573 | if (f2 != f && FRAME_X_P (f2)) |
| 511 | { | 574 | { |
| 512 | other_frame = f2; | 575 | other_frame = f2; |
| 513 | break; | 576 | break; |
| @@ -517,14 +580,15 @@ init_frame_faces (f) | |||
| 517 | if (other_frame) | 580 | if (other_frame) |
| 518 | { | 581 | { |
| 519 | /* Make sure this frame's face vector is as big as the others. */ | 582 | /* Make sure this frame's face vector is as big as the others. */ |
| 520 | f->n_faces = other_frame->n_faces; | 583 | FRAME_N_FACES (f) = FRAME_N_FACES (other_frame); |
| 521 | f->faces = (struct face **) xmalloc (f->n_faces * sizeof (struct face *)); | 584 | FRAME_FACES (f) |
| 585 | = (struct face **) xmalloc (FRAME_N_FACES (f) * sizeof (struct face *)); | ||
| 522 | 586 | ||
| 523 | /* Make sure the frame has the two basic faces. */ | 587 | /* Make sure the frame has the two basic faces. */ |
| 524 | FRAME_NORMAL_FACE (f) | 588 | FRAME_DEFAULT_FACE (f) |
| 525 | = copy_face (FRAME_NORMAL_FACE (other_frame)); | 589 | = copy_face (FRAME_DEFAULT_FACE (other_frame)); |
| 526 | FRAME_MODELINE_FACE (f) | 590 | FRAME_MODE_LINE_FACE (f) |
| 527 | = copy_face (FRAME_MODELINE_FACE (other_frame)); | 591 | = copy_face (FRAME_MODE_LINE_FACE (other_frame)); |
| 528 | } | 592 | } |
| 529 | } | 593 | } |
| 530 | 594 | ||
| @@ -538,22 +602,24 @@ free_screen_faces (f) | |||
| 538 | Display *dpy = x_current_display; | 602 | Display *dpy = x_current_display; |
| 539 | int i; | 603 | int i; |
| 540 | 604 | ||
| 541 | for (i = 0; i < f->n_faces; i++) | 605 | for (i = 0; i < FRAME_N_FACES (f); i++) |
| 542 | { | 606 | { |
| 543 | struct face *face = f->faces [i]; | 607 | struct face *face = FRAME_FACES (f) [i]; |
| 544 | if (! face) | 608 | if (! face) |
| 545 | continue; | 609 | continue; |
| 546 | if (face->facegc) | 610 | if (face->gc) |
| 547 | XFreeGC (dpy, face->facegc); | 611 | XFreeGC (dpy, face->gc); |
| 548 | unload_font (f, face->font); | 612 | unload_font (f, face->font); |
| 549 | unload_color (f, face->foreground); | 613 | unload_color (f, face->foreground); |
| 550 | unload_color (f, face->background); | 614 | unload_color (f, face->background); |
| 551 | unload_pixmap (f, face->back_pixmap); | 615 | #if 0 |
| 616 | unload_pixmap (f, face->stipple); | ||
| 617 | #endif | ||
| 552 | xfree (face); | 618 | xfree (face); |
| 553 | } | 619 | } |
| 554 | xfree (f->faces); | 620 | xfree (FRAME_FACES (f)); |
| 555 | f->faces = 0; | 621 | FRAME_FACES (f) = 0; |
| 556 | f->n_faces = 0; | 622 | FRAME_N_FACES (f) = 0; |
| 557 | } | 623 | } |
| 558 | 624 | ||
| 559 | 625 | ||
| @@ -587,9 +653,9 @@ DEFUN ("make-face-internal", Fmake_face_internal, Smake_face_internal, 1, 1, 0, | |||
| 587 | Lisp_Object rest; | 653 | Lisp_Object rest; |
| 588 | int id = XINT (face_id); | 654 | int id = XINT (face_id); |
| 589 | 655 | ||
| 590 | CHECK_FIXNUM (face_id, 0); | 656 | CHECK_NUMBER (face_id, 0); |
| 591 | if (id < 0) | 657 | if (id < 0 || id >= next_face_id) |
| 592 | error ("Face id must be nonnegative"); | 658 | error ("Face id out of range"); |
| 593 | 659 | ||
| 594 | for (rest = Vframe_list; !NILP (rest); rest = XCONS (rest)->cdr) | 660 | for (rest = Vframe_list; !NILP (rest); rest = XCONS (rest)->cdr) |
| 595 | { | 661 | { |
| @@ -611,67 +677,47 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal, | |||
| 611 | int id; | 677 | int id; |
| 612 | 678 | ||
| 613 | CHECK_FRAME (frame, 0); | 679 | CHECK_FRAME (frame, 0); |
| 614 | CHECK_FIXNUM (face_id, 0); | 680 | CHECK_NUMBER (face_id, 0); |
| 615 | CHECK_SYMBOL (attr_name, 0); | 681 | CHECK_SYMBOL (attr_name, 0); |
| 616 | 682 | ||
| 617 | f = XFRAME (frame); | 683 | f = XFRAME (frame); |
| 618 | id = XINT (face_id); | 684 | id = XINT (face_id); |
| 619 | if (id < 0) | 685 | if (id < 0 || id >= next_face_id) |
| 620 | Fsignal (Qerror, Fcons (build_string ("invalid face id"), | 686 | error ("Face id out of range"); |
| 621 | Fcons (face_id, Fcons (frame, Qnil)))); | ||
| 622 | 687 | ||
| 623 | ensure_face_ready (f, id); | 688 | ensure_face_ready (f, id); |
| 624 | face = f->faces [XFASTINT (face_id)]; | 689 | face = FRAME_FACES (f) [XFASTINT (face_id)]; |
| 625 | if (! face) abort (); | ||
| 626 | |||
| 627 | magic_p = (NILP (attr_value) && XFASTINT (face_id) <= 1); | ||
| 628 | 690 | ||
| 629 | if (EQ (attr_name, intern ("font"))) | 691 | if (EQ (attr_name, intern ("font"))) |
| 630 | { | 692 | { |
| 631 | #ifdef HAVE_X_WINDOWS | 693 | XFontStruct *font = load_font (f, attr_value); |
| 632 | XFontStruct *font; | ||
| 633 | if (magic_p) | ||
| 634 | error ("font of the `normal' or `modeline' face may not be nil"); | ||
| 635 | font = load_font (f, attr_value); | ||
| 636 | unload_font (f, face->font); | 694 | unload_font (f, face->font); |
| 637 | face->font = font; | 695 | face->font = font; |
| 638 | #endif /* HAVE_X_WINDOWS */ | ||
| 639 | } | 696 | } |
| 640 | else if (EQ (attr_name, intern ("foreground"))) | 697 | else if (EQ (attr_name, intern ("foreground"))) |
| 641 | { | 698 | { |
| 642 | #ifdef HAVE_X_WINDOWS | 699 | unsigned long new_color = load_color (f, attr_value); |
| 643 | unsigned long new_color; | ||
| 644 | if (magic_p) | ||
| 645 | error ("forground color of the `normal' or `modeline' face may not be nil"); | ||
| 646 | new_color = load_color (f, attr_value); | ||
| 647 | unload_color (f, face->foreground); | 700 | unload_color (f, face->foreground); |
| 648 | face->foreground = new_color; | 701 | face->foreground = new_color; |
| 649 | #endif /* HAVE_X_WINDOWS */ | ||
| 650 | } | 702 | } |
| 651 | else if (EQ (attr_name, intern ("background"))) | 703 | else if (EQ (attr_name, intern ("background"))) |
| 652 | { | 704 | { |
| 653 | #ifdef HAVE_X_WINDOWS | 705 | unsigned long new_color = load_color (f, attr_value); |
| 654 | unsigned long new_color; | ||
| 655 | if (magic_p) | ||
| 656 | error ("background color of the `normal' or `modeline' face may not be nil"); | ||
| 657 | new_color = load_color (f, attr_value); | ||
| 658 | unload_color (f, face->background); | 706 | unload_color (f, face->background); |
| 659 | face->background = new_color; | 707 | face->background = new_color; |
| 660 | #endif /* HAVE_X_WINDOWS */ | ||
| 661 | } | 708 | } |
| 662 | #if 0 | 709 | #if 0 |
| 663 | else if (EQ (attr_name, intern ("background-pixmap"))) | 710 | else if (EQ (attr_name, intern ("background-pixmap"))) |
| 664 | { | 711 | { |
| 665 | #ifdef HAVE_X_WINDOWS | ||
| 666 | unsigned int w, h, d; | 712 | unsigned int w, h, d; |
| 667 | unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0); | 713 | unsigned long new_pixmap = load_pixmap (f, attr_value, &w, &h, &d, 0); |
| 668 | unload_pixmap (f, face->back_pixmap); | 714 | unload_pixmap (f, face->stipple); |
| 669 | if (magic_p) new_pixmap = 0; | 715 | if (NILP (attr_value)) |
| 670 | face->back_pixmap = new_pixmap; | 716 | new_pixmap = 0; |
| 717 | face->stipple = new_pixmap; | ||
| 671 | face->pixmap_w = w; | 718 | face->pixmap_w = w; |
| 672 | face->pixmap_h = h; | 719 | face->pixmap_h = h; |
| 673 | /* face->pixmap_depth = d; */ | 720 | /* face->pixmap_depth = d; */ |
| 674 | #endif /* HAVE_X_WINDOWS */ | ||
| 675 | } | 721 | } |
| 676 | #endif /* 0 */ | 722 | #endif /* 0 */ |
| 677 | else if (EQ (attr_name, intern ("underline"))) | 723 | else if (EQ (attr_name, intern ("underline"))) |
| @@ -685,16 +731,18 @@ DEFUN ("set-face-attribute-internal", Fset_face_attribute_internal, | |||
| 685 | if (id == 0) | 731 | if (id == 0) |
| 686 | { | 732 | { |
| 687 | BLOCK_INPUT; | 733 | BLOCK_INPUT; |
| 688 | XFreeGC (dpy, FRAME_NORMAL_FACE (f)->facegc); | 734 | if (FRAME_DEFAULT_FACE (f)->gc != 0) |
| 689 | build_face (f, FRAME_NORMAL_FACE (f)); | 735 | XFreeGC (x_current_display, FRAME_DEFAULT_FACE (f)->gc); |
| 736 | build_face (f, FRAME_DEFAULT_FACE (f)); | ||
| 690 | UNBLOCK_INPUT; | 737 | UNBLOCK_INPUT; |
| 691 | } | 738 | } |
| 692 | 739 | ||
| 693 | if (id == 1) | 740 | if (id == 1) |
| 694 | { | 741 | { |
| 695 | BLOCK_INPUT; | 742 | BLOCK_INPUT; |
| 696 | XFreeGC (dpy, FRAME_NORMAL_FACE (f)->facegc); | 743 | if (FRAME_MODE_LINE_FACE (f)->gc != 0) |
| 697 | build_face (f, FRAME_NORMAL_FACE (f)); | 744 | XFreeGC (x_current_display, FRAME_MODE_LINE_FACE (f)->gc); |
| 745 | build_face (f, FRAME_MODE_LINE_FACE (f)); | ||
| 698 | UNBLOCK_INPUT; | 746 | UNBLOCK_INPUT; |
| 699 | } | 747 | } |
| 700 | 748 | ||
| @@ -707,10 +755,36 @@ DEFUN ("internal-next-face-id", Finternal_next_face_id, Sinternal_next_face_id, | |||
| 707 | { | 755 | { |
| 708 | return make_number (next_face_id++); | 756 | return make_number (next_face_id++); |
| 709 | } | 757 | } |
| 758 | |||
| 759 | /* Return the face id for name NAME on frame FRAME. | ||
| 760 | (It should be the same for all frames, | ||
| 761 | but it's as easy to use the "right" frame to look it up | ||
| 762 | as to use any other one.) */ | ||
| 763 | |||
| 764 | static Lisp_Object | ||
| 765 | face_name_id_number (frame, name) | ||
| 766 | Lisp_Object frame, name; | ||
| 767 | { | ||
| 768 | Lisp_Object tem; | ||
| 769 | |||
| 770 | CHECK_FRAME (frame, 0); | ||
| 771 | tem = Fcdr (Fassq (name, XFRAME (frame)->face_alist)); | ||
| 772 | CHECK_VECTOR (tem, 0); | ||
| 773 | tem = XVECTOR (tem)->contents[2]; | ||
| 774 | CHECK_NUMBER (tem, 0); | ||
| 775 | return XINT (tem); | ||
| 776 | } | ||
| 710 | 777 | ||
| 711 | void | 778 | void |
| 712 | syms_of_faces () | 779 | syms_of_xfaces () |
| 713 | { | 780 | { |
| 781 | Qwindow = intern ("window"); | ||
| 782 | staticpro (&Qwindow); | ||
| 783 | Qface = intern ("face"); | ||
| 784 | staticpro (&Qface); | ||
| 785 | Qpriority = intern ("priority"); | ||
| 786 | staticpro (&Qpriority); | ||
| 787 | |||
| 714 | defsubr (&Sframe_face_alist); | 788 | defsubr (&Sframe_face_alist); |
| 715 | defsubr (&Sset_frame_face_alist); | 789 | defsubr (&Sset_frame_face_alist); |
| 716 | defsubr (&Smake_face_internal); | 790 | defsubr (&Smake_face_internal); |