Mercurial > emacs
comparison src/fringe.c @ 57258:36eef73e00fa
(Vfringe_bitmaps): New variable.
(syms_of_fringe): DEFVAR_LISP it.
(valid_fringe_bitmap_p): Rename from valid_fringe_bitmap_id_p.
Change arg to Lisp_Object and fail if not an integer.
(get_fringe_bitmap_name, resolve_fringe_bitmap)
(destroy_fringe_bitmap): New functions.
(Fdestroy_fringe_bitmap): Change arg to bitmap symbol. Use
destroy_fringe_bitmap. Remove symbol from Vfringe_bitmaps and
clear its fringe property.
(init_fringe_bitmap): Use destroy_fringe_bitmap instead of
Fdestroy_fringe_bitmap.
(Fdefine_fringe_bitmap): Add BITMAP arg specifying new or existing
bitmap symbol; remove WHICH arg. Add symbol to Vfringe_bitmaps
and set fringe property. Signal error if no free slots.
(Fset_fringe_bitmap_face): Change arg to bitmap symbol.
(Ffringe_bitmaps_at_pos): Return bitmap symbols instead of numbers.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Tue, 28 Sep 2004 23:02:53 +0000 |
parents | 36ab9b017a42 |
children | 617e54beffb6 b85b19b8eb65 e23928ac5a97 |
comparison
equal
deleted
inserted
replaced
57257:0869d141e93c | 57258:36eef73e00fa |
---|---|
29 #include "buffer.h" | 29 #include "buffer.h" |
30 #include "blockinput.h" | 30 #include "blockinput.h" |
31 | 31 |
32 #ifdef HAVE_WINDOW_SYSTEM | 32 #ifdef HAVE_WINDOW_SYSTEM |
33 | 33 |
34 extern Lisp_Object Qfringe; | |
34 extern Lisp_Object Qtop, Qbottom, Qcenter; | 35 extern Lisp_Object Qtop, Qbottom, Qcenter; |
35 extern Lisp_Object Qup, Qdown, Qleft, Qright; | 36 extern Lisp_Object Qup, Qdown, Qleft, Qright; |
36 | 37 |
37 /* Non-nil means that newline may flow into the right fringe. */ | 38 /* Non-nil means that newline may flow into the right fringe. */ |
38 | 39 |
39 Lisp_Object Voverflow_newline_into_fringe; | 40 Lisp_Object Voverflow_newline_into_fringe; |
40 | 41 |
42 /* List of known fringe bitmap symbols. | |
43 | |
44 The fringe bitmap number is stored in the `fringe' property on | |
45 those symbols. Names for the built-in bitmaps are installed by | |
46 loading fringe.el. | |
47 */ | |
48 | |
49 Lisp_Object Vfringe_bitmaps; | |
41 | 50 |
42 enum fringe_bitmap_type | 51 enum fringe_bitmap_type |
43 { | 52 { |
44 NO_FRINGE_BITMAP = 0, | 53 NO_FRINGE_BITMAP = 0, |
45 UNDEF_FRINGE_BITMAP, | 54 UNDEF_FRINGE_BITMAP, |
442 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS; | 451 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS; |
443 | 452 |
444 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */ | 453 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */ |
445 | 454 |
446 int | 455 int |
447 valid_fringe_bitmap_id_p (fringe_id) | 456 valid_fringe_bitmap_p (bitmap) |
448 int fringe_id; | 457 Lisp_Object bitmap; |
449 { | 458 { |
450 return (fringe_id >= NO_FRINGE_BITMAP | 459 int bn; |
451 && fringe_id < max_used_fringe_bitmap | 460 |
452 && (fringe_id < MAX_STANDARD_FRINGE_BITMAPS | 461 if (!INTEGERP (bitmap)) |
453 || fringe_bitmaps[fringe_id] != NULL)); | 462 return 0; |
454 } | 463 |
464 bn = XINT (bitmap); | |
465 return (bn >= NO_FRINGE_BITMAP | |
466 && bn < max_used_fringe_bitmap | |
467 && (bn < MAX_STANDARD_FRINGE_BITMAPS | |
468 || fringe_bitmaps[bn] != NULL)); | |
469 } | |
470 | |
471 /* Get fringe bitmap name for bitmap number BN. | |
472 | |
473 Found by traversing Vfringe_bitmaps comparing BN to the | |
474 fringe property for each symbol. | |
475 | |
476 Return BN if not found in Vfringe_bitmaps. */ | |
477 | |
478 static Lisp_Object | |
479 get_fringe_bitmap_name (bn) | |
480 int bn; | |
481 { | |
482 Lisp_Object bitmaps; | |
483 Lisp_Object num; | |
484 | |
485 /* Zero means no bitmap -- return nil. */ | |
486 if (bn <= 0) | |
487 return Qnil; | |
488 | |
489 bitmaps = Vfringe_bitmaps; | |
490 num = make_number (bn); | |
491 | |
492 while (CONSP (bitmaps)) | |
493 { | |
494 Lisp_Object bitmap = XCAR (bitmaps); | |
495 if (EQ (num, Fget (bitmap, Qfringe))) | |
496 return bitmap; | |
497 bitmaps = XCDR (bitmaps); | |
498 } | |
499 | |
500 return num; | |
501 } | |
502 | |
503 | |
504 /* Resolve a BITMAP parameter. | |
505 | |
506 An INTEGER, corresponding to a bitmap number. | |
507 A STRING which is interned to a symbol. | |
508 A SYMBOL which has a fringe property which is a bitmap number. | |
509 */ | |
510 | |
511 static int | |
512 resolve_fringe_bitmap (bitmap, namep) | |
513 Lisp_Object bitmap; | |
514 Lisp_Object *namep; | |
515 { | |
516 if (namep) | |
517 *namep = Qnil; | |
518 | |
519 if (STRINGP (bitmap)) | |
520 bitmap = intern (SDATA (bitmap)); | |
521 | |
522 if (SYMBOLP (bitmap)) | |
523 { | |
524 if (namep) | |
525 *namep = bitmap; | |
526 bitmap = Fget (bitmap, Qfringe); | |
527 } | |
528 | |
529 if (valid_fringe_bitmap_p (bitmap)) | |
530 { | |
531 if (namep && NILP (*namep)) | |
532 *namep = get_fringe_bitmap_name (XINT (bitmap)); | |
533 return XINT (bitmap); | |
534 } | |
535 | |
536 return -1; | |
537 } | |
538 | |
455 | 539 |
456 /* Draw the bitmap WHICH in one of the left or right fringes of | 540 /* Draw the bitmap WHICH in one of the left or right fringes of |
457 window W. ROW is the glyph row for which to display the bitmap; it | 541 window W. ROW is the glyph row for which to display the bitmap; it |
458 determines the vertical position at which the bitmap has to be | 542 determines the vertical position at which the bitmap has to be |
459 drawn. | 543 drawn. |
981 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) || | 1065 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) || |
982 o_cols != FRAME_FRINGE_COLS (f)) | 1066 o_cols != FRAME_FRINGE_COLS (f)) |
983 redraw_frame (f); | 1067 redraw_frame (f); |
984 } | 1068 } |
985 | 1069 |
986 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap, | 1070 |
987 1, 1, 0, | 1071 void |
988 doc: /* Destroy fringe bitmap WHICH. | 1072 destroy_fringe_bitmap (n) |
989 If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */) | 1073 int n; |
990 (which) | 1074 { |
991 Lisp_Object which; | |
992 { | |
993 int n; | |
994 struct fringe_bitmap **fbp; | 1075 struct fringe_bitmap **fbp; |
995 | |
996 CHECK_NUMBER (which); | |
997 if (n = XINT (which), n >= max_used_fringe_bitmap) | |
998 return Qnil; | |
999 | 1076 |
1000 fringe_faces[n] = FRINGE_FACE_ID; | 1077 fringe_faces[n] = FRINGE_FACE_ID; |
1001 | 1078 |
1002 fbp = &fringe_bitmaps[n]; | 1079 fbp = &fringe_bitmaps[n]; |
1003 if (*fbp && (*fbp)->dynamic) | 1080 if (*fbp && (*fbp)->dynamic) |
1009 } | 1086 } |
1010 | 1087 |
1011 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS | 1088 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS |
1012 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL) | 1089 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL) |
1013 max_used_fringe_bitmap--; | 1090 max_used_fringe_bitmap--; |
1014 | 1091 } |
1092 | |
1093 | |
1094 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap, | |
1095 1, 1, 0, | |
1096 doc: /* Destroy fringe bitmap BITMAP. | |
1097 If BITMAP overrides a standard fringe bitmap, the original bitmap is restored. */) | |
1098 (bitmap) | |
1099 Lisp_Object bitmap; | |
1100 { | |
1101 int n; | |
1102 Lisp_Object sym; | |
1103 | |
1104 n = resolve_fringe_bitmap (bitmap, &sym); | |
1105 if (n < 0) | |
1106 return Qnil; | |
1107 | |
1108 destroy_fringe_bitmap (n); | |
1109 | |
1110 if (SYMBOLP (sym)) | |
1111 { | |
1112 Vfringe_bitmaps = Fdelq (sym, Vfringe_bitmaps); | |
1113 /* It would be better to remove the fringe property. */ | |
1114 Fput (sym, Qfringe, Qnil); | |
1115 } | |
1015 return Qnil; | 1116 return Qnil; |
1016 } | 1117 } |
1017 | 1118 |
1018 | 1119 |
1019 /* Initialize bitmap bit. | 1120 /* Initialize bitmap bit. |
1080 #endif /* MAC_OS && WORDS_BIG_ENDIAN */ | 1181 #endif /* MAC_OS && WORDS_BIG_ENDIAN */ |
1081 } | 1182 } |
1082 | 1183 |
1083 if (!once_p) | 1184 if (!once_p) |
1084 { | 1185 { |
1085 Fdestroy_fringe_bitmap (make_number (which)); | 1186 destroy_fringe_bitmap (which); |
1086 | 1187 |
1087 if (rif->define_fringe_bitmap) | 1188 if (rif->define_fringe_bitmap) |
1088 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width); | 1189 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width); |
1089 | 1190 |
1090 fringe_bitmaps[which] = fb; | 1191 fringe_bitmaps[which] = fb; |
1093 } | 1194 } |
1094 } | 1195 } |
1095 | 1196 |
1096 | 1197 |
1097 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap, | 1198 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap, |
1098 1, 5, 0, | 1199 2, 5, 0, |
1099 doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH. | 1200 doc: /* Define fringe bitmap BITMAP from BITS of size HEIGHT x WIDTH. |
1201 BITMAP is a symbol or string naming the new fringe bitmap. | |
1100 BITS is either a string or a vector of integers. | 1202 BITS is either a string or a vector of integers. |
1101 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS. | 1203 HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS. |
1102 WIDTH must be an integer between 1 and 16, or nil which defaults to 8. | 1204 WIDTH must be an integer between 1 and 16, or nil which defaults to 8. |
1103 Optional fourth arg ALIGN may be one of `top', `center', or `bottom', | 1205 Optional fifth arg ALIGN may be one of `top', `center', or `bottom', |
1104 indicating the positioning of the bitmap relative to the rows where it | 1206 indicating the positioning of the bitmap relative to the rows where it |
1105 is used; the default is to center the bitmap. Fourth arg may also be a | 1207 is used; the default is to center the bitmap. Fourth arg may also be a |
1106 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap | 1208 list (ALIGN PERIODIC) where PERIODIC non-nil specifies that the bitmap |
1107 should be repeated. | 1209 should be repeated. |
1108 Optional fifth argument WHICH is bitmap number to redefine. | 1210 If BITMAP already exists, the existing definition is replaced. */) |
1109 Return new bitmap number, or nil of no more free bitmap slots. */) | 1211 (bitmap, bits, height, width, align) |
1110 (bits, height, width, align, which) | 1212 Lisp_Object bitmap, bits, height, width, align; |
1111 Lisp_Object bits, height, width, align, which; | |
1112 { | 1213 { |
1113 Lisp_Object len; | 1214 Lisp_Object len; |
1114 int n, h, i, j; | 1215 int n, h, i, j; |
1115 unsigned short *b; | 1216 unsigned short *b; |
1116 struct fringe_bitmap fb, *xfb; | 1217 struct fringe_bitmap fb, *xfb; |
1117 int fill1 = 0, fill2 = 0; | 1218 int fill1 = 0, fill2 = 0; |
1219 Lisp_Object sym; | |
1220 | |
1221 n = resolve_fringe_bitmap (bitmap, &sym); | |
1222 | |
1223 if (NILP (sym) || INTEGERP (sym)) | |
1224 sym = wrong_type_argument (Qsymbolp, bitmap); | |
1118 | 1225 |
1119 if (!STRINGP (bits) && !VECTORP (bits)) | 1226 if (!STRINGP (bits) && !VECTORP (bits)) |
1120 bits = wrong_type_argument (Qstringp, bits); | 1227 bits = wrong_type_argument (Qstringp, bits); |
1121 | 1228 |
1122 len = Flength (bits); | 1229 len = Flength (bits); |
1165 else if (EQ (align, Qbottom)) | 1272 else if (EQ (align, Qbottom)) |
1166 fb.align = ALIGN_BITMAP_BOTTOM; | 1273 fb.align = ALIGN_BITMAP_BOTTOM; |
1167 else if (!NILP (align) && !EQ (align, Qcenter)) | 1274 else if (!NILP (align) && !EQ (align, Qcenter)) |
1168 error ("Bad align argument"); | 1275 error ("Bad align argument"); |
1169 | 1276 |
1170 if (NILP (which)) | 1277 if (n < 0) |
1171 { | 1278 { |
1172 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS) | 1279 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS) |
1173 n = max_used_fringe_bitmap++; | 1280 n = max_used_fringe_bitmap++; |
1174 else | 1281 else |
1175 { | 1282 { |
1177 n < MAX_FRINGE_BITMAPS; | 1284 n < MAX_FRINGE_BITMAPS; |
1178 n++) | 1285 n++) |
1179 if (fringe_bitmaps[n] == NULL) | 1286 if (fringe_bitmaps[n] == NULL) |
1180 break; | 1287 break; |
1181 if (n == MAX_FRINGE_BITMAPS) | 1288 if (n == MAX_FRINGE_BITMAPS) |
1182 return Qnil; | 1289 error ("Cannot define more fringe bitmaps"); |
1183 } | 1290 } |
1184 which = make_number (n); | 1291 |
1185 } | 1292 Vfringe_bitmaps = Fcons (sym, Vfringe_bitmaps); |
1186 else | 1293 Fput (sym, Qfringe, make_number (n)); |
1187 { | |
1188 CHECK_NUMBER (which); | |
1189 n = XINT (which); | |
1190 if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS) | |
1191 error ("Invalid fringe bitmap number"); | |
1192 } | 1294 } |
1193 | 1295 |
1194 fb.dynamic = 1; | 1296 fb.dynamic = 1; |
1195 | 1297 |
1196 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb | 1298 xfb = (struct fringe_bitmap *) xmalloc (sizeof fb |
1214 | 1316 |
1215 *xfb = fb; | 1317 *xfb = fb; |
1216 | 1318 |
1217 init_fringe_bitmap (n, xfb, 0); | 1319 init_fringe_bitmap (n, xfb, 0); |
1218 | 1320 |
1219 return which; | 1321 return sym; |
1220 } | 1322 } |
1221 | 1323 |
1222 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face, | 1324 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face, |
1223 1, 2, 0, | 1325 1, 2, 0, |
1224 doc: /* Set face for fringe bitmap FRINGE-ID to FACE. | 1326 doc: /* Set face for fringe bitmap BITMAP to FACE. |
1225 If FACE is nil, reset face to default fringe face. */) | 1327 If FACE is nil, reset face to default fringe face. */) |
1226 (fringe_id, face) | 1328 (bitmap, face) |
1227 Lisp_Object fringe_id, face; | 1329 Lisp_Object bitmap, face; |
1228 { | 1330 { |
1331 int bn; | |
1229 int face_id; | 1332 int face_id; |
1230 | 1333 |
1231 CHECK_NUMBER (fringe_id); | 1334 bn = resolve_fringe_bitmap (bitmap, 0); |
1232 if (!valid_fringe_bitmap_id_p (XINT (fringe_id))) | 1335 if (bn < 0) |
1233 error ("Invalid fringe id"); | 1336 error ("Undefined fringe bitmap"); |
1234 | 1337 |
1235 if (!NILP (face)) | 1338 if (!NILP (face)) |
1236 { | 1339 { |
1237 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A'); | 1340 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A'); |
1238 if (face_id < 0) | 1341 if (face_id < 0) |
1239 error ("No such face"); | 1342 error ("No such face"); |
1240 } | 1343 } |
1241 else | 1344 else |
1242 face_id = FRINGE_FACE_ID; | 1345 face_id = FRINGE_FACE_ID; |
1243 | 1346 |
1244 fringe_faces [XINT (fringe_id)] = face_id; | 1347 fringe_faces [bn] = face_id; |
1245 | 1348 |
1246 return Qnil; | 1349 return Qnil; |
1247 } | 1350 } |
1248 | 1351 |
1249 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos, | 1352 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos, |
1278 textpos = XMARKER (w->pointm)->charpos; | 1381 textpos = XMARKER (w->pointm)->charpos; |
1279 | 1382 |
1280 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | 1383 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); |
1281 row = row_containing_pos (w, textpos, row, NULL, 0); | 1384 row = row_containing_pos (w, textpos, row, NULL, 0); |
1282 if (row) | 1385 if (row) |
1283 return Fcons ((row->left_fringe_bitmap == NO_FRINGE_BITMAP | 1386 return Fcons (get_fringe_bitmap_name (row->left_fringe_bitmap), |
1284 ? Qnil : make_number (row->left_fringe_bitmap)), | 1387 get_fringe_bitmap_name (row->right_fringe_bitmap)); |
1285 (row->right_fringe_bitmap == NO_FRINGE_BITMAP | |
1286 ? Qnil : make_number (row->right_fringe_bitmap))); | |
1287 else | 1388 else |
1288 return Qnil; | 1389 return Qnil; |
1289 } | 1390 } |
1290 | 1391 |
1291 | 1392 |
1294 ***********************************************************************/ | 1395 ***********************************************************************/ |
1295 | 1396 |
1296 void | 1397 void |
1297 syms_of_fringe () | 1398 syms_of_fringe () |
1298 { | 1399 { |
1299 | |
1300 defsubr (&Sdestroy_fringe_bitmap); | 1400 defsubr (&Sdestroy_fringe_bitmap); |
1301 defsubr (&Sdefine_fringe_bitmap); | 1401 defsubr (&Sdefine_fringe_bitmap); |
1302 defsubr (&Sfringe_bitmaps_at_pos); | 1402 defsubr (&Sfringe_bitmaps_at_pos); |
1303 defsubr (&Sset_fringe_bitmap_face); | 1403 defsubr (&Sset_fringe_bitmap_face); |
1304 | 1404 |
1309 showing (or hiding) the final newline in the right fringe; when point | 1409 showing (or hiding) the final newline in the right fringe; when point |
1310 is at the final newline, the cursor is shown in the right fringe. | 1410 is at the final newline, the cursor is shown in the right fringe. |
1311 If nil, also continue lines which are exactly as wide as the window. */); | 1411 If nil, also continue lines which are exactly as wide as the window. */); |
1312 Voverflow_newline_into_fringe = Qt; | 1412 Voverflow_newline_into_fringe = Qt; |
1313 | 1413 |
1414 DEFVAR_LISP ("fringe-bitmaps", &Vfringe_bitmaps, | |
1415 doc: /* List of fringe bitmap symbols. | |
1416 You must (require 'fringe) to use fringe bitmap symbols in your programs." */); | |
1417 Vfringe_bitmaps = Qnil; | |
1314 } | 1418 } |
1315 | 1419 |
1316 /* Initialize this module when Emacs starts. */ | 1420 /* Initialize this module when Emacs starts. */ |
1317 | 1421 |
1318 void | 1422 void |