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