This source file includes following definitions.
- lookup_fringe_bitmap
- get_fringe_bitmap_name
- get_fringe_bitmap_data
- draw_fringe_bitmap_1
- get_logical_cursor_bitmap
- get_logical_fringe_bitmap
- draw_fringe_bitmap
- draw_row_fringe_bitmaps
- draw_window_fringes
- update_window_fringes
- destroy_fringe_bitmap
- DEFUN
- init_fringe_bitmap
- syms_of_fringe
- mark_fringe_data
- init_fringe_once
- init_fringe_once_for_pdumper
- init_fringe
- gui_init_fringe
- gui_define_fringe_bitmap
- w32_reset_fringes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include <byteswap.h>
23
24 #include "lisp.h"
25 #include "frame.h"
26 #include "window.h"
27 #include "dispextern.h"
28 #include "buffer.h"
29 #include "blockinput.h"
30 #include "termhooks.h"
31 #include "pdumper.h"
32
33 #ifdef HAVE_PGTK
34 # include "pgtkterm.h"
35 #endif
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 enum fringe_bitmap_align
72 {
73 ALIGN_BITMAP_CENTER = 0,
74 ALIGN_BITMAP_TOP,
75 ALIGN_BITMAP_BOTTOM
76 };
77
78 struct fringe_bitmap
79 {
80 unsigned short *bits;
81 unsigned height : 8;
82 unsigned width : 8;
83 unsigned period : 8;
84 unsigned align : 2;
85 bool_bf dynamic : 1;
86 };
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106 static unsigned short question_mark_bits[] = {
107 0x3c, 0x7e, 0xc3, 0xc3, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18};
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 static unsigned short exclamation_mark_bits[] = {
123 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18};
124
125
126
127
128
129
130
131
132
133
134
135
136 static unsigned short left_arrow_bits[] = {
137 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18};
138
139
140
141
142
143
144
145
146
147
148
149
150
151 static unsigned short right_arrow_bits[] = {
152 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18};
153
154
155
156
157
158
159
160
161
162
163
164
165
166 static unsigned short up_arrow_bits[] = {
167 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18};
168
169
170
171
172
173
174
175
176
177
178
179
180
181 static unsigned short down_arrow_bits[] = {
182 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18};
183
184
185
186
187
188
189
190
191
192
193
194
195 static unsigned short left_curly_arrow_bits[] = {
196 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c};
197
198
199
200
201
202
203
204
205
206
207
208
209 static unsigned short right_curly_arrow_bits[] = {
210 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e};
211
212
213
214
215
216
217
218
219
220
221
222
223 static unsigned short large_circle_bits[] = {
224 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c};
225
226
227
228
229
230
231
232
233
234
235
236
237 static unsigned short left_triangle_bits[] = {
238 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03};
239
240
241
242
243
244
245
246
247
248
249
250
251 static unsigned short right_triangle_bits[] = {
252 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0};
253
254
255
256
257
258
259
260
261
262
263
264
265 static unsigned short top_left_angle_bits[] = {
266 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00};
267
268
269
270
271
272
273
274
275
276
277
278
279 static unsigned short top_right_angle_bits[] = {
280 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00};
281
282
283
284
285
286
287
288
289
290
291
292
293 static unsigned short bottom_left_angle_bits[] = {
294 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
295
296
297
298
299
300
301
302
303
304
305
306
307 static unsigned short bottom_right_angle_bits[] = {
308 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 static unsigned short left_bracket_bits[] = {
324 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc};
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339 static unsigned short right_bracket_bits[] = {
340 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f};
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358 static unsigned short filled_rectangle_bits[] = {
359 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377 static unsigned short hollow_rectangle_bits[] = {
378 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe};
379
380
381
382
383
384
385
386
387
388
389 static unsigned short hollow_square_bits[] = {
390 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e};
391
392
393
394
395
396
397
398
399
400
401 static unsigned short filled_square_bits[] = {
402 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e};
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 static unsigned short vertical_bar_bits[] = {
421 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0};
422
423
424
425
426
427
428 static unsigned short horizontal_bar_bits[] = {
429 0xfe, 0xfe};
430
431
432
433
434
435
436
437
438
439
440
441
442 static unsigned short empty_line_bits[] = {
443 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
444 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
445 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
446 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
447 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
448 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
449 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00,
450 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00};
451
452
453 #define BYTES_PER_BITMAP_ROW (sizeof (unsigned short))
454 #define STANDARD_BITMAP_HEIGHT(bits) (sizeof (bits)/BYTES_PER_BITMAP_ROW)
455 #define FRBITS(bits) bits, STANDARD_BITMAP_HEIGHT (bits)
456
457
458
459
460 static struct fringe_bitmap standard_bitmaps[] =
461 {
462 { NULL, 0, 0, 0, 0, 0 },
463 { FRBITS (question_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
464 { FRBITS (exclamation_mark_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
465 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
466 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
467 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
468 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
469 { FRBITS (left_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
470 { FRBITS (right_curly_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
471 { FRBITS (large_circle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
472 { FRBITS (left_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
473 { FRBITS (right_triangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
474 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
475 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 },
476 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
477 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
478 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
479 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
480 { FRBITS (filled_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
481 { FRBITS (hollow_rectangle_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
482 { FRBITS (filled_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
483 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
484 { FRBITS (vertical_bar_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 },
485 { FRBITS (horizontal_bar_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 },
486 { FRBITS (empty_line_bits), 8, 3, ALIGN_BITMAP_TOP, 0 },
487 };
488
489 #define NO_FRINGE_BITMAP 0
490 #define UNDEF_FRINGE_BITMAP 1
491 #define MAX_STANDARD_FRINGE_BITMAPS ARRAYELTS (standard_bitmaps)
492
493 static struct fringe_bitmap **fringe_bitmaps;
494 static Lisp_Object *fringe_faces;
495 static int max_fringe_bitmaps;
496
497 int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS;
498
499
500
501
502
503 int
504 lookup_fringe_bitmap (Lisp_Object bitmap)
505 {
506 EMACS_INT bn;
507
508 bitmap = Fget (bitmap, Qfringe);
509 if (!FIXNUMP (bitmap))
510 return 0;
511
512 bn = XFIXNUM (bitmap);
513 if (bn > NO_FRINGE_BITMAP
514 && bn < max_used_fringe_bitmap
515 && (bn < MAX_STANDARD_FRINGE_BITMAPS
516 || fringe_bitmaps[bn] != NULL))
517 return bn;
518
519 return 0;
520 }
521
522
523
524
525
526
527
528
529 static Lisp_Object
530 get_fringe_bitmap_name (int bn)
531 {
532 Lisp_Object bitmaps;
533 Lisp_Object num;
534
535
536 if (bn <= 0)
537 return Qnil;
538
539 bitmaps = Vfringe_bitmaps;
540 num = make_fixnum (bn);
541
542 while (CONSP (bitmaps))
543 {
544 Lisp_Object bitmap = XCAR (bitmaps);
545 if (EQ (num, Fget (bitmap, Qfringe)))
546 return bitmap;
547 bitmaps = XCDR (bitmaps);
548 }
549
550 return num;
551 }
552
553
554
555 static struct fringe_bitmap *
556 get_fringe_bitmap_data (int bn)
557 {
558 struct fringe_bitmap *fb;
559
560 fb = fringe_bitmaps[bn];
561 if (fb == NULL)
562 fb = &standard_bitmaps[bn < MAX_STANDARD_FRINGE_BITMAPS
563 ? bn : UNDEF_FRINGE_BITMAP];
564
565 return fb;
566 }
567
568
569
570
571
572
573
574
575 static void
576 draw_fringe_bitmap_1 (struct window *w, struct glyph_row *row, int left_p, int overlay, int which)
577 {
578 struct frame *f = XFRAME (WINDOW_FRAME (w));
579 struct draw_fringe_bitmap_params p;
580 struct fringe_bitmap *fb;
581 int period;
582 int face_id = DEFAULT_FACE_ID;
583 int offset, header_line_height;
584
585 p.overlay_p = (overlay & 1) == 1;
586 p.cursor_p = (overlay & 2) == 2;
587
588 if (which != NO_FRINGE_BITMAP)
589 {
590 offset = 0;
591 }
592 else if (left_p)
593 {
594 which = row->left_fringe_bitmap;
595 face_id = row->left_fringe_face_id;
596 offset = row->left_fringe_offset;
597 }
598 else
599 {
600 which = row->right_fringe_bitmap;
601 face_id = row->right_fringe_face_id;
602 offset = row->right_fringe_offset;
603 }
604
605 if (face_id == DEFAULT_FACE_ID)
606 {
607 Lisp_Object face = fringe_faces[which];
608 face_id = NILP (face) ? lookup_named_face (w, f, Qfringe, false)
609 : lookup_derived_face (w, f, face, FRINGE_FACE_ID, 0);
610 if (face_id < 0)
611 face_id = FRINGE_FACE_ID;
612 }
613
614 fb = get_fringe_bitmap_data (which);
615
616 period = fb->period;
617
618
619 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y) + offset;
620
621 p.which = which;
622 p.bits = fb->bits;
623 p.wd = fb->width;
624
625 p.h = fb->height;
626 p.dh = (period > 0 ? (p.y % period) : 0);
627 p.h -= p.dh;
628
629
630 switch (fb->align)
631 {
632 case ALIGN_BITMAP_CENTER:
633 p.y += (row->height - p.h) / 2;
634 break;
635 case ALIGN_BITMAP_BOTTOM:
636 p.y += (row->visible_height - p.h);
637 break;
638 case ALIGN_BITMAP_TOP:
639 break;
640 }
641
642 p.face = FACE_FROM_ID_OR_NULL (f, face_id);
643 if (p.face == NULL)
644 {
645
646
647 return;
648 }
649
650 prepare_face_for_display (f, p.face);
651
652
653
654 p.bx = -1;
655 header_line_height = WINDOW_TAB_LINE_HEIGHT (w)
656 + WINDOW_HEADER_LINE_HEIGHT (w);
657 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y));
658 p.ny = row->visible_height;
659 if (left_p)
660 {
661 int wd = WINDOW_LEFT_FRINGE_WIDTH (w);
662 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
663 ? LEFT_MARGIN_AREA
664 : TEXT_AREA));
665 if (p.wd > wd)
666 p.wd = wd;
667 p.x = x - p.wd - (wd - p.wd) / 2;
668
669 if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
670 {
671
672 wd -= ((!WINDOW_LEFTMOST_P (w)
673
674
675
676 && !FRAME_RIGHT_DIVIDER_WIDTH (f)
677 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
678
679
680
681
682
683
684 && w->left_margin_cols == 0)
685 ? 1 : 0);
686 p.bx = x - wd;
687 p.nx = wd;
688 }
689 }
690 else
691 {
692 int x = window_box_right (w,
693 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
694 ? RIGHT_MARGIN_AREA
695 : TEXT_AREA));
696 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w);
697 if (p.wd > wd)
698 p.wd = wd;
699 p.x = x + (wd - p.wd) / 2;
700
701
702 if (p.wd < wd || p.y > p.by || p.y + p.h < p.by + p.ny)
703 {
704 p.bx = x;
705 p.nx = wd;
706 }
707 }
708
709 if (p.x >= WINDOW_BOX_LEFT_EDGE_X (w)
710 && (p.x + p.wd) <= WINDOW_BOX_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w))
711 FRAME_RIF (f)->draw_fringe_bitmap (w, row, &p);
712 }
713
714 static int
715 get_logical_cursor_bitmap (struct window *w, Lisp_Object cursor)
716 {
717 Lisp_Object cmap, bm = Qnil;
718
719 if ((cmap = BVAR (XBUFFER (w->contents), fringe_cursor_alist)), !NILP (cmap))
720 {
721 bm = Fassq (cursor, cmap);
722 if (CONSP (bm))
723 {
724 if ((bm = XCDR (bm)), NILP (bm))
725 return NO_FRINGE_BITMAP;
726 return lookup_fringe_bitmap (bm);
727 }
728 }
729 if (EQ (cmap, BVAR (&buffer_defaults, fringe_cursor_alist)))
730 return NO_FRINGE_BITMAP;
731 bm = Fassq (cursor, BVAR (&buffer_defaults, fringe_cursor_alist));
732 if (!CONSP (bm) || ((bm = XCDR (bm)), NILP (bm)))
733 return NO_FRINGE_BITMAP;
734 return lookup_fringe_bitmap (bm);
735 }
736
737 static int
738 get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p)
739 {
740 Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
741 ptrdiff_t ln1 = 0, ln2 = 0;
742 int ix1 = right_p;
743 int ix2 = ix1 + (partial_p ? 2 : 0);
744
745
746
747
748
749
750
751
752
753
754
755
756 if ((cmap = BVAR (XBUFFER (w->contents), fringe_indicator_alist)), !NILP (cmap))
757 {
758 bm1 = Fassq (bitmap, cmap);
759 if (CONSP (bm1))
760 {
761 if ((bm1 = XCDR (bm1)), NILP (bm1))
762 return NO_FRINGE_BITMAP;
763 if (CONSP (bm1))
764 {
765 ln1 = list_length (bm1);
766 if (partial_p)
767 {
768 if (ln1 > ix2)
769 {
770 bm = Fnth (make_fixnum (ix2), bm1);
771 if (!EQ (bm, Qt))
772 goto found;
773 }
774 }
775 else
776 {
777 if (ln1 > ix1)
778 {
779 bm = Fnth (make_fixnum (ix1), bm1);
780 if (!EQ (bm, Qt))
781 goto found;
782 }
783 }
784 }
785 else if ((bm = bm1, !EQ (bm, Qt)))
786 goto found;
787 }
788 }
789
790 if (!EQ (cmap, BVAR (&buffer_defaults, fringe_indicator_alist))
791 && !NILP (BVAR (&buffer_defaults, fringe_indicator_alist)))
792 {
793 bm2 = Fassq (bitmap, BVAR (&buffer_defaults, fringe_indicator_alist));
794 if (CONSP (bm2))
795 {
796 if ((bm2 = XCDR (bm2)), !NILP (bm2))
797 {
798 if (CONSP (bm2))
799 {
800 ln2 = list_length (bm2);
801 if (partial_p)
802 {
803 if (ln2 > ix2)
804 {
805 bm = Fnth (make_fixnum (ix2), bm2);
806 if (!EQ (bm, Qt))
807 goto found;
808 }
809 }
810 }
811 }
812 }
813 }
814
815 if (ln1 > ix1)
816 {
817 bm = Fnth (make_fixnum (ix1), bm1);
818 if (!EQ (bm, Qt))
819 goto found;
820 }
821
822 if (ln2 > ix1)
823 {
824 bm = Fnth (make_fixnum (ix1), bm2);
825 if (!EQ (bm, Qt))
826 goto found;
827 return NO_FRINGE_BITMAP;
828 }
829 else if ((bm = bm2, NILP (bm)))
830 return NO_FRINGE_BITMAP;
831
832 found:
833 return lookup_fringe_bitmap (bm);
834 }
835
836
837 void
838 draw_fringe_bitmap (struct window *w, struct glyph_row *row, int left_p)
839 {
840 int overlay = 0;
841
842 if (left_p == row->reversed_p && row->cursor_in_fringe_p)
843 {
844 Lisp_Object cursor = Qnil;
845
846 switch (w->phys_cursor_type)
847 {
848 case HOLLOW_BOX_CURSOR:
849 if (row->visible_height >= STANDARD_BITMAP_HEIGHT (hollow_rectangle_bits))
850 cursor = Qhollow;
851 else
852 cursor = Qhollow_small;
853 break;
854 case FILLED_BOX_CURSOR:
855 cursor = Qbox;
856 break;
857 case BAR_CURSOR:
858 cursor = Qbar;
859 break;
860 case HBAR_CURSOR:
861 cursor = Qhbar;
862 break;
863 case NO_CURSOR:
864 default:
865 w->phys_cursor_on_p = 0;
866 row->cursor_in_fringe_p = 0;
867 break;
868 }
869 if (!NILP (cursor))
870 {
871 int bm = get_logical_cursor_bitmap (w, cursor);
872 if (bm != NO_FRINGE_BITMAP)
873 {
874 draw_fringe_bitmap_1 (w, row, left_p, 2, bm);
875 overlay = EQ (cursor, Qbox) ? 3 : 1;
876 }
877 }
878 }
879
880 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP);
881
882 if (left_p && row->overlay_arrow_bitmap != NO_FRINGE_BITMAP)
883 draw_fringe_bitmap_1 (w, row, 1, 1, row->overlay_arrow_bitmap);
884 }
885
886
887
888
889
890 void
891 draw_row_fringe_bitmaps (struct window *w, struct glyph_row *row)
892 {
893 eassert (input_blocked_p ());
894
895
896
897 if (row->visible_height <= 0)
898 return;
899
900 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0)
901 draw_fringe_bitmap (w, row, 1);
902
903 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0)
904 draw_fringe_bitmap (w, row, 0);
905 }
906
907
908
909
910
911
912
913
914
915
916
917
918
919 bool
920 draw_window_fringes (struct window *w, bool no_fringe_p)
921 {
922 struct glyph_row *row;
923 int yb = window_text_bottom_y (w);
924 int nrows = w->current_matrix->nrows;
925 int y, rn;
926 bool updated_p = 0;
927
928 if (w->pseudo_window_p)
929 return updated_p;
930
931
932
933 Lisp_Object window_buffer = w->contents;
934 struct buffer *oldbuf = current_buffer;
935 set_buffer_internal_1 (XBUFFER (window_buffer));
936
937
938 if (no_fringe_p
939 && (WINDOW_LEFT_FRINGE_WIDTH (w) == 0
940 || WINDOW_RIGHT_FRINGE_WIDTH (w) == 0))
941 updated_p = 1;
942
943 for (y = w->vscroll, rn = 0, row = w->current_matrix->rows;
944 y < yb && rn < nrows;
945 y += row->height, ++row, ++rn)
946 {
947 if (!row->redraw_fringe_bitmaps_p)
948 continue;
949 draw_row_fringe_bitmaps (w, row);
950 row->redraw_fringe_bitmaps_p = 0;
951 updated_p = 1;
952 }
953
954 set_buffer_internal_1 (oldbuf);
955
956 return updated_p;
957 }
958
959
960
961
962
963
964
965 bool
966 update_window_fringes (struct window *w, bool keep_current_p)
967 {
968 struct glyph_row *row, *cur = 0;
969 int yb = window_text_bottom_y (w);
970 int rn, nrows = w->current_matrix->nrows;
971 int y;
972 bool redraw_p = 0;
973 Lisp_Object boundary_top = Qnil, boundary_bot = Qnil;
974 Lisp_Object arrow_top = Qnil, arrow_bot = Qnil;
975 Lisp_Object empty_pos;
976 Lisp_Object ind = Qnil;
977 #define MAX_BITMAP_CACHE (8*4)
978 int bitmap_cache[MAX_BITMAP_CACHE];
979 int top_ind_rn, bot_ind_rn;
980 int top_ind_min_y, bot_ind_max_y;
981
982
983
984
985
986 int top_row_ends_at_zv_p UNINIT, bot_row_ends_at_zv_p UNINIT;
987
988 if (w->pseudo_window_p)
989 return 0;
990
991 specpdl_ref count = SPECPDL_INDEX ();
992
993
994
995
996
997 specbind (Qinhibit_quit, Qt);
998
999 if (!MINI_WINDOW_P (w)
1000 && (ind = BVAR (XBUFFER (w->contents), indicate_buffer_boundaries), !NILP (ind)))
1001 {
1002 if (EQ (ind, Qleft) || EQ (ind, Qright))
1003 boundary_top = boundary_bot = arrow_top = arrow_bot = ind;
1004 else if (CONSP (ind) && CONSP (XCAR (ind)))
1005 {
1006 Lisp_Object pos;
1007 if (pos = Fassq (Qt, ind), !NILP (pos))
1008 boundary_top = boundary_bot = arrow_top = arrow_bot = XCDR (pos);
1009 if (pos = Fassq (Qtop, ind), !NILP (pos))
1010 boundary_top = XCDR (pos);
1011 if (pos = Fassq (Qbottom, ind), !NILP (pos))
1012 boundary_bot = XCDR (pos);
1013 if (pos = Fassq (Qup, ind), !NILP (pos))
1014 arrow_top = XCDR (pos);
1015 if (pos = Fassq (Qdown, ind), !NILP (pos))
1016 arrow_bot = XCDR (pos);
1017 }
1018 else
1019
1020 boundary_top = boundary_bot = Qleft;
1021 }
1022
1023 top_ind_rn = bot_ind_rn = -1;
1024 if (!NILP (ind))
1025 {
1026 for (y = w->vscroll, rn = 0;
1027 y < yb && rn < nrows;
1028 y += row->height, ++rn)
1029 {
1030 row = w->desired_matrix->rows + rn;
1031 if (!row->enabled_p)
1032 row = w->current_matrix->rows + rn;
1033
1034 row->indicate_bob_p = row->indicate_top_line_p = 0;
1035 row->indicate_eob_p = row->indicate_bottom_line_p = 0;
1036
1037 if (!row->mode_line_p)
1038 {
1039 if (top_ind_rn < 0 && row->visible_height > 0)
1040 {
1041 if (MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->contents))
1042 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
1043 row->indicate_bob_p = !NILP (boundary_top);
1044 else
1045 row->indicate_top_line_p = !NILP (arrow_top);
1046 top_ind_rn = rn;
1047 }
1048
1049 if (bot_ind_rn < 0)
1050 {
1051 if (MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->contents))
1052 && !MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row))
1053 row->indicate_eob_p = !NILP (boundary_bot), bot_ind_rn = rn;
1054 else if (y + row->height >= yb)
1055 row->indicate_bottom_line_p = !NILP (arrow_bot), bot_ind_rn = rn;
1056 }
1057 }
1058 }
1059 }
1060
1061 empty_pos = BVAR (XBUFFER (w->contents), indicate_empty_lines);
1062 if (!NILP (empty_pos) && !EQ (empty_pos, Qright))
1063 empty_pos = WINDOW_LEFT_FRINGE_WIDTH (w) == 0 ? Qright : Qleft;
1064
1065 for (y = 0; y < MAX_BITMAP_CACHE; y++)
1066 bitmap_cache[y] = -1;
1067
1068 #define LEFT_FRINGE(cache, which, partial_p) \
1069 (bitmap_cache[cache*4+partial_p] >= 0 \
1070 ? bitmap_cache[cache*4+partial_p] \
1071 : (bitmap_cache[cache*4+partial_p] = \
1072 get_logical_fringe_bitmap (w, which, 0, partial_p)))
1073
1074 #define RIGHT_FRINGE(cache, which, partial_p) \
1075 (bitmap_cache[cache*4+2+partial_p] >= 0 \
1076 ? bitmap_cache[cache*4+2+partial_p] \
1077 : (bitmap_cache[cache*4+2+partial_p] = \
1078 get_logical_fringe_bitmap (w, which, 1, partial_p)))
1079
1080
1081
1082
1083 top_ind_min_y = bot_ind_max_y = -1;
1084 if (top_ind_rn >= 0)
1085 {
1086 int bn = NO_FRINGE_BITMAP;
1087
1088 row = w->desired_matrix->rows + top_ind_rn;
1089 if (!row->enabled_p)
1090 row = w->current_matrix->rows + top_ind_rn;
1091
1092 top_row_ends_at_zv_p = row->ends_at_zv_p;
1093 if (row->indicate_bob_p)
1094 {
1095 if (EQ (boundary_top, Qleft))
1096 bn = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1097 ? LEFT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1098 : LEFT_FRINGE (2, Qtop, 0));
1099 else
1100 bn = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1101 ? RIGHT_FRINGE (1, Qtop_bottom, row->ends_at_zv_p)
1102 : RIGHT_FRINGE (2, Qtop, 0));
1103 }
1104 else if (row->indicate_top_line_p)
1105 {
1106 if (EQ (arrow_top, Qleft))
1107 bn = LEFT_FRINGE (6, Qup, 0);
1108 else
1109 bn = RIGHT_FRINGE (6, Qup, 0);
1110 }
1111
1112 if (bn != NO_FRINGE_BITMAP)
1113 {
1114 struct fringe_bitmap *fb = get_fringe_bitmap_data (bn);
1115
1116 if (fb->align == ALIGN_BITMAP_TOP && fb->period == 0)
1117 {
1118 struct glyph_row *row1;
1119 int top_ind_max_y;
1120
1121 top_ind_min_y = WINDOW_TAB_LINE_HEIGHT (w)
1122 + WINDOW_HEADER_LINE_HEIGHT (w);
1123 top_ind_max_y = top_ind_min_y + fb->height;
1124 if (top_ind_max_y > yb)
1125 top_ind_max_y = yb;
1126
1127 for (y = row->y + row->height, rn = top_ind_rn + 1;
1128 y < top_ind_max_y && rn < nrows;
1129 y += row1->height, rn++)
1130 {
1131 if (bot_ind_rn >= 0 && rn >= bot_ind_rn)
1132 break;
1133
1134 row1 = w->desired_matrix->rows + rn;
1135 if (!row1->enabled_p)
1136 row1 = w->current_matrix->rows + rn;
1137
1138 row1->indicate_bob_p = row->indicate_bob_p;
1139 row1->indicate_top_line_p = row->indicate_top_line_p;
1140 }
1141 }
1142 }
1143 }
1144 if (bot_ind_rn >= 0)
1145 {
1146 int bn = NO_FRINGE_BITMAP;
1147
1148 row = w->desired_matrix->rows + bot_ind_rn;
1149 if (!row->enabled_p)
1150 row = w->current_matrix->rows + bot_ind_rn;
1151
1152 bot_row_ends_at_zv_p = row->ends_at_zv_p;
1153 if (row->indicate_eob_p)
1154 {
1155 if (EQ (boundary_bot, Qleft))
1156 bn = LEFT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1157 else
1158 bn = RIGHT_FRINGE (3, Qbottom, row->ends_at_zv_p);
1159 }
1160 else if (row->indicate_bottom_line_p)
1161 {
1162 if (EQ (arrow_bot, Qleft))
1163 bn = LEFT_FRINGE (7, Qdown, 0);
1164 else
1165 bn = RIGHT_FRINGE (7, Qdown, 0);
1166 }
1167
1168 if (bn != NO_FRINGE_BITMAP)
1169 {
1170 struct fringe_bitmap *fb = get_fringe_bitmap_data (bn);
1171
1172 if (fb->align == ALIGN_BITMAP_BOTTOM && fb->period == 0)
1173 {
1174 struct glyph_row *row1;
1175 int bot_ind_min_y;
1176
1177 bot_ind_max_y = row->y + row->visible_height;
1178 bot_ind_min_y = bot_ind_max_y - fb->height;
1179 if (bot_ind_min_y < WINDOW_TAB_LINE_HEIGHT (w)
1180 + WINDOW_HEADER_LINE_HEIGHT (w))
1181 bot_ind_min_y = WINDOW_TAB_LINE_HEIGHT (w)
1182 + WINDOW_HEADER_LINE_HEIGHT (w);
1183
1184 for (y = row->y, rn = bot_ind_rn - 1;
1185 y >= bot_ind_min_y && rn >= 0;
1186 y -= row1->height, rn--)
1187 {
1188 if (top_ind_rn >= 0 && rn <= top_ind_rn)
1189 break;
1190
1191 row1 = w->desired_matrix->rows + rn;
1192 if (!row1->enabled_p)
1193 row1 = w->current_matrix->rows + rn;
1194
1195 row1->indicate_eob_p = row->indicate_eob_p;
1196 row1->indicate_bottom_line_p = row->indicate_bottom_line_p;
1197 }
1198 }
1199 }
1200 }
1201
1202 for (y = w->vscroll, rn = 0;
1203 y < yb && rn < nrows;
1204 y += row->height, rn++)
1205 {
1206 int left, right;
1207 unsigned left_face_id, right_face_id;
1208 int left_offset, right_offset;
1209 bool periodic_p;
1210
1211 row = w->desired_matrix->rows + rn;
1212 cur = w->current_matrix->rows + rn;
1213 if (!row->enabled_p)
1214 row = cur;
1215
1216 left_face_id = right_face_id = DEFAULT_FACE_ID;
1217 left_offset = right_offset = 0;
1218 periodic_p = 0;
1219
1220
1221 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
1222 left = NO_FRINGE_BITMAP;
1223 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP)
1224 {
1225 left = row->left_user_fringe_bitmap;
1226 left_face_id = row->left_user_fringe_face_id;
1227 }
1228 else if ((!row->reversed_p && row->truncated_on_left_p)
1229 || (row->reversed_p && row->truncated_on_right_p))
1230 left = LEFT_FRINGE (0, Qtruncation, 0);
1231 else if (row->indicate_bob_p && EQ (boundary_top, Qleft))
1232 {
1233 left = ((row->indicate_eob_p && EQ (boundary_bot, Qleft))
1234 ? LEFT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
1235 : LEFT_FRINGE (2, Qtop, 0));
1236 if (top_ind_min_y >= 0)
1237 left_offset = top_ind_min_y - row->y;
1238 }
1239 else if (row->indicate_eob_p && EQ (boundary_bot, Qleft))
1240 {
1241 left = LEFT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
1242 if (bot_ind_max_y >= 0)
1243 left_offset = bot_ind_max_y - (row->y + row->visible_height);
1244 }
1245 else if ((!row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row))
1246 || (row->reversed_p && row->continued_p))
1247 left = LEFT_FRINGE (4, Qcontinuation, 0);
1248 else if (row->indicate_empty_line_p && EQ (empty_pos, Qleft))
1249 left = LEFT_FRINGE (5, Qempty_line, 0);
1250 else if (row->indicate_top_line_p && EQ (arrow_top, Qleft))
1251 {
1252 left = LEFT_FRINGE (6, Qup, 0);
1253 if (top_ind_min_y >= 0)
1254 left_offset = top_ind_min_y - row->y;
1255 }
1256 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qleft))
1257 {
1258 left = LEFT_FRINGE (7, Qdown, 0);
1259 if (bot_ind_max_y >= 0)
1260 left_offset = bot_ind_max_y - (row->y + row->visible_height);
1261 }
1262 else
1263 left = NO_FRINGE_BITMAP;
1264
1265
1266 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0)
1267 right = NO_FRINGE_BITMAP;
1268 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP)
1269 {
1270 right = row->right_user_fringe_bitmap;
1271 right_face_id = row->right_user_fringe_face_id;
1272 }
1273 else if ((!row->reversed_p && row->truncated_on_right_p)
1274 || (row->reversed_p && row->truncated_on_left_p))
1275 right = RIGHT_FRINGE (0, Qtruncation, 0);
1276 else if (row->indicate_bob_p && EQ (boundary_top, Qright))
1277 {
1278 right = ((row->indicate_eob_p && EQ (boundary_bot, Qright))
1279 ? RIGHT_FRINGE (1, Qtop_bottom, top_row_ends_at_zv_p)
1280 : RIGHT_FRINGE (2, Qtop, 0));
1281 if (top_ind_min_y >= 0)
1282 right_offset = top_ind_min_y - row->y;
1283 }
1284 else if (row->indicate_eob_p && EQ (boundary_bot, Qright))
1285 {
1286 right = RIGHT_FRINGE (3, Qbottom, bot_row_ends_at_zv_p);
1287 if (bot_ind_max_y >= 0)
1288 right_offset = bot_ind_max_y - (row->y + row->visible_height);
1289 }
1290 else if ((!row->reversed_p && row->continued_p)
1291 || (row->reversed_p && MATRIX_ROW_CONTINUATION_LINE_P (row)))
1292 right = RIGHT_FRINGE (4, Qcontinuation, 0);
1293 else if (row->indicate_top_line_p && EQ (arrow_top, Qright))
1294 {
1295 right = RIGHT_FRINGE (6, Qup, 0);
1296 if (top_ind_min_y >= 0)
1297 right_offset = top_ind_min_y - row->y;
1298 }
1299 else if (row->indicate_bottom_line_p && EQ (arrow_bot, Qright))
1300 {
1301 right = RIGHT_FRINGE (7, Qdown, 0);
1302 if (bot_ind_max_y >= 0)
1303 right_offset = bot_ind_max_y - (row->y + row->visible_height);
1304 }
1305 else if (row->indicate_empty_line_p && EQ (empty_pos, Qright))
1306 right = RIGHT_FRINGE (5, Qempty_line, 0);
1307 else
1308 right = NO_FRINGE_BITMAP;
1309
1310 periodic_p = (get_fringe_bitmap_data (left)->period != 0
1311 || get_fringe_bitmap_data (right)->period != 0);
1312
1313 if (row->y != cur->y
1314 || row->visible_height != cur->visible_height
1315 || row->ends_at_zv_p != cur->ends_at_zv_p
1316 || left != cur->left_fringe_bitmap
1317 || right != cur->right_fringe_bitmap
1318 || left_face_id != cur->left_fringe_face_id
1319 || right_face_id != cur->right_fringe_face_id
1320 || left_offset != cur->left_fringe_offset
1321 || right_offset != cur->right_fringe_offset
1322 || periodic_p != cur->fringe_bitmap_periodic_p
1323 || cur->redraw_fringe_bitmaps_p)
1324 {
1325 redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
1326 if (!keep_current_p)
1327 {
1328 cur->redraw_fringe_bitmaps_p = 1;
1329 cur->left_fringe_bitmap = left;
1330 cur->right_fringe_bitmap = right;
1331 cur->left_fringe_face_id = left_face_id;
1332 cur->right_fringe_face_id = right_face_id;
1333 cur->left_fringe_offset = left_offset;
1334 cur->right_fringe_offset = right_offset;
1335 cur->fringe_bitmap_periodic_p = periodic_p;
1336 }
1337 }
1338
1339 if (row->overlay_arrow_bitmap < 0)
1340 row->overlay_arrow_bitmap = get_logical_fringe_bitmap (w, Qoverlay_arrow, 0, 0);
1341
1342 if (row->overlay_arrow_bitmap != cur->overlay_arrow_bitmap)
1343 {
1344 redraw_p = 1, row->redraw_fringe_bitmaps_p = 1;
1345 if (!keep_current_p)
1346 {
1347 cur->redraw_fringe_bitmaps_p = 1;
1348 cur->overlay_arrow_bitmap = row->overlay_arrow_bitmap;
1349 }
1350 }
1351
1352 row->left_fringe_bitmap = left;
1353 row->right_fringe_bitmap = right;
1354 row->left_fringe_face_id = left_face_id;
1355 row->right_fringe_face_id = right_face_id;
1356 row->left_fringe_offset = left_offset;
1357 row->right_fringe_offset = right_offset;
1358 row->fringe_bitmap_periodic_p = periodic_p;
1359 }
1360
1361 unbind_to (count, Qnil);
1362
1363 return redraw_p && !keep_current_p;
1364 }
1365
1366
1367
1368
1369
1370 static void
1371 destroy_fringe_bitmap (int n)
1372 {
1373 struct fringe_bitmap **fbp;
1374
1375 fringe_faces[n] = Qnil;
1376
1377 fbp = &fringe_bitmaps[n];
1378 if (*fbp && (*fbp)->dynamic)
1379 {
1380
1381 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1382 if (rif && rif->destroy_fringe_bitmap)
1383 rif->destroy_fringe_bitmap (n);
1384 xfree (*fbp);
1385 *fbp = NULL;
1386 }
1387
1388 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS
1389 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL)
1390 max_used_fringe_bitmap--;
1391 }
1392
1393
1394 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap,
1395 1, 1, 0,
1396 doc:
1397 )
1398 (Lisp_Object bitmap)
1399 {
1400 int n;
1401
1402 CHECK_SYMBOL (bitmap);
1403 n = lookup_fringe_bitmap (bitmap);
1404 if (!n)
1405 return Qnil;
1406
1407 destroy_fringe_bitmap (n);
1408
1409 if (n >= MAX_STANDARD_FRINGE_BITMAPS)
1410 {
1411 Vfringe_bitmaps = Fdelq (bitmap, Vfringe_bitmaps);
1412
1413 Fput (bitmap, Qfringe, Qnil);
1414 }
1415
1416 return Qnil;
1417 }
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430 #if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK)
1431 static const unsigned char swap_nibble[16] = {
1432 0x0, 0x8, 0x4, 0xc,
1433 0x2, 0xa, 0x6, 0xe,
1434 0x1, 0x9, 0x5, 0xd,
1435 0x3, 0xb, 0x7, 0xf};
1436 #endif
1437
1438 static void
1439 init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
1440 {
1441 if (once_p || fb->dynamic)
1442 {
1443 #if defined (HAVE_X_WINDOWS)
1444 unsigned short *bits = fb->bits;
1445 int j;
1446
1447 #ifdef USE_CAIRO
1448 for (j = 0; j < fb->height; j++)
1449 {
1450 unsigned short b = *bits;
1451 #ifdef WORDS_BIGENDIAN
1452 *bits++ = (b << (16 - fb->width));
1453 #else
1454 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1455 | (swap_nibble[(b>>4) & 0xf] << 8)
1456 | (swap_nibble[(b>>8) & 0xf] << 4)
1457 | (swap_nibble[(b>>12) & 0xf]));
1458 *bits++ = (b >> (16 - fb->width));
1459 #endif
1460 }
1461 #else
1462 if (fb->width <= 8)
1463 {
1464 unsigned char *cbits = (unsigned char *)fb->bits;
1465 for (j = 0; j < fb->height; j++)
1466 {
1467 unsigned short b = *bits++;
1468 unsigned char c;
1469 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1470 | (swap_nibble[(b>>4) & 0xf]));
1471 *cbits++ = (c >> (8 - fb->width));
1472 }
1473 }
1474 else
1475 {
1476 for (j = 0; j < fb->height; j++)
1477 {
1478 unsigned short b = *bits;
1479 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1480 | (swap_nibble[(b>>4) & 0xf] << 8)
1481 | (swap_nibble[(b>>8) & 0xf] << 4)
1482 | (swap_nibble[(b>>12) & 0xf]));
1483 b >>= (16 - fb->width);
1484 #ifdef WORDS_BIGENDIAN
1485 b = bswap_16 (b);
1486 #endif
1487 *bits++ = b;
1488 }
1489 }
1490 #endif
1491 #endif
1492
1493 #if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK)
1494 unsigned short *bits = fb->bits;
1495 int j;
1496
1497 for (j = 0; j < fb->height; j++)
1498 {
1499 unsigned short b = *bits;
1500 #ifdef WORDS_BIGENDIAN
1501 *bits++ = (b << (16 - fb->width));
1502 #else
1503 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1504 | (swap_nibble[(b>>4) & 0xf] << 8)
1505 | (swap_nibble[(b>>8) & 0xf] << 4)
1506 | (swap_nibble[(b>>12) & 0xf]));
1507 *bits++ = (b >> (16 - fb->width));
1508 #endif
1509 }
1510 #endif
1511
1512 #ifdef HAVE_NTGUI
1513 unsigned short *bits = fb->bits;
1514 int j;
1515 for (j = 0; j < fb->height; j++)
1516 {
1517 unsigned short b = *bits;
1518 b <<= (16 - fb->width);
1519
1520
1521 b = ((b >> 8) | (b << 8));
1522 *bits++ = b;
1523 }
1524 #endif
1525 }
1526
1527 if (!once_p)
1528 {
1529
1530 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1531
1532 destroy_fringe_bitmap (which);
1533
1534 if (rif && rif->define_fringe_bitmap)
1535 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1536
1537 fringe_bitmaps[which] = fb;
1538 if (which >= max_used_fringe_bitmap)
1539 max_used_fringe_bitmap = which + 1;
1540 }
1541 }
1542
1543
1544 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1545 2, 5, 0,
1546 doc:
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557 )
1558 (Lisp_Object bitmap, Lisp_Object bits, Lisp_Object height, Lisp_Object width, Lisp_Object align)
1559 {
1560 int n, h, i, j;
1561 unsigned short *b;
1562 struct fringe_bitmap fb, *xfb;
1563 int fill1 = 0, fill2 = 0;
1564
1565 CHECK_SYMBOL (bitmap);
1566 h = CHECK_VECTOR_OR_STRING (bits);
1567
1568 if (NILP (height))
1569 fb.height = h;
1570 else
1571 {
1572 CHECK_FIXNUM (height);
1573 fb.height = max (0, min (XFIXNUM (height), 255));
1574 if (fb.height > h)
1575 {
1576 fill1 = (fb.height - h) / 2;
1577 fill2 = fb.height - h - fill1;
1578 }
1579 }
1580
1581 if (NILP (width))
1582 fb.width = 8;
1583 else
1584 {
1585 CHECK_FIXNUM (width);
1586 fb.width = max (1, min (XFIXNUM (width), 16));
1587 if (fb.width != XFIXNUM (width))
1588 args_out_of_range (width, build_string ("Width must be from 1 to 16"));
1589 }
1590
1591 fb.period = 0;
1592 fb.align = ALIGN_BITMAP_CENTER;
1593
1594 if (CONSP (align))
1595 {
1596 Lisp_Object period = XCDR (align);
1597 if (CONSP (period))
1598 {
1599 period = XCAR (period);
1600 if (!NILP (period))
1601 {
1602 fb.period = fb.height;
1603 fb.height = 255;
1604 }
1605 }
1606 align = XCAR (align);
1607 }
1608 if (EQ (align, Qtop))
1609 fb.align = ALIGN_BITMAP_TOP;
1610 else if (EQ (align, Qbottom))
1611 fb.align = ALIGN_BITMAP_BOTTOM;
1612 else if (!NILP (align) && !EQ (align, Qcenter))
1613 error ("Bad align argument");
1614
1615 n = lookup_fringe_bitmap (bitmap);
1616 if (!n)
1617 {
1618 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1619 n = max_used_fringe_bitmap++;
1620 else
1621 {
1622 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1623 n < max_fringe_bitmaps;
1624 n++)
1625 if (fringe_bitmaps[n] == NULL)
1626 break;
1627
1628 if (n == max_fringe_bitmaps)
1629 {
1630 int bitmaps = max_fringe_bitmaps + 20;
1631 if (MAX_FRINGE_BITMAPS < bitmaps)
1632 error ("No free fringe bitmap slots");
1633
1634 i = max_fringe_bitmaps;
1635 fringe_bitmaps = xrealloc (fringe_bitmaps,
1636 bitmaps * sizeof *fringe_bitmaps);
1637 fringe_faces = xrealloc (fringe_faces,
1638 bitmaps * sizeof *fringe_faces);
1639
1640 for (i = max_fringe_bitmaps; i < bitmaps; i++)
1641 {
1642 fringe_bitmaps[i] = NULL;
1643 fringe_faces[i] = Qnil;
1644 }
1645
1646 max_fringe_bitmaps = bitmaps;
1647 }
1648 }
1649
1650 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1651 Fput (bitmap, Qfringe, make_fixnum (n));
1652 }
1653
1654 fb.dynamic = true;
1655
1656 xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW);
1657 fb.bits = b = (unsigned short *) (xfb + 1);
1658
1659 j = 0;
1660 while (j < fb.height)
1661 {
1662 for (i = 0; i < fill1 && j < fb.height; i++)
1663 b[j++] = 0;
1664 for (i = 0; i < h && j < fb.height; i++)
1665 {
1666 Lisp_Object elt = Faref (bits, make_fixnum (i));
1667 b[j++] = FIXNUMP (elt) ? XFIXNUM (elt) : 0;
1668 }
1669 for (i = 0; i < fill2 && j < fb.height; i++)
1670 b[j++] = 0;
1671 }
1672
1673 *xfb = fb;
1674
1675 init_fringe_bitmap (n, xfb, 0);
1676
1677 return bitmap;
1678 }
1679
1680 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1681 1, 2, 0,
1682 doc:
1683
1684
1685 )
1686 (Lisp_Object bitmap, Lisp_Object face)
1687 {
1688 int n;
1689
1690 CHECK_SYMBOL (bitmap);
1691 n = lookup_fringe_bitmap (bitmap);
1692 if (!n)
1693 error ("Undefined fringe bitmap");
1694
1695
1696
1697
1698
1699 fringe_faces[n] = face;
1700 return Qnil;
1701 }
1702
1703 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1704 0, 2, 0,
1705 doc:
1706
1707
1708
1709
1710
1711 )
1712 (Lisp_Object pos, Lisp_Object window)
1713 {
1714 struct window *w;
1715 struct glyph_row *row;
1716 ptrdiff_t textpos;
1717
1718 w = decode_any_window (window);
1719 XSETWINDOW (window, w);
1720
1721 if (!NILP (pos))
1722 {
1723 EMACS_INT p = fix_position (pos);
1724 if (! (BEGV <= p && p <= ZV))
1725 args_out_of_range (window, pos);
1726 textpos = p;
1727 }
1728 else if (w == XWINDOW (selected_window))
1729 textpos = PT;
1730 else
1731 textpos = marker_position (w->pointm);
1732
1733 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1734 row = row_containing_pos (w, textpos, row, NULL, 0);
1735 if (row)
1736 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1737 get_fringe_bitmap_name (row->right_fringe_bitmap),
1738 (row->overlay_arrow_bitmap == 0 ? Qnil
1739 : row->overlay_arrow_bitmap < 0 ? Qt
1740 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1741 else
1742 return Qnil;
1743 }
1744
1745
1746
1747
1748
1749
1750 void
1751 syms_of_fringe (void)
1752 {
1753 DEFSYM (Qtruncation, "truncation");
1754 DEFSYM (Qcontinuation, "continuation");
1755 DEFSYM (Qoverlay_arrow, "overlay-arrow");
1756 DEFSYM (Qempty_line, "empty-line");
1757 DEFSYM (Qtop_bottom, "top-bottom");
1758 DEFSYM (Qhollow_small, "hollow-small");
1759
1760 defsubr (&Sdestroy_fringe_bitmap);
1761 defsubr (&Sdefine_fringe_bitmap);
1762 defsubr (&Sfringe_bitmaps_at_pos);
1763 defsubr (&Sset_fringe_bitmap_face);
1764
1765 DEFVAR_LISP ("overflow-newline-into-fringe", Voverflow_newline_into_fringe,
1766 doc:
1767
1768
1769
1770
1771 );
1772 Voverflow_newline_into_fringe = Qt;
1773
1774 DEFVAR_LISP ("fringe-bitmaps", Vfringe_bitmaps,
1775 doc: );
1776 Vfringe_bitmaps = Qnil;
1777 }
1778
1779
1780
1781 void
1782 mark_fringe_data (void)
1783 {
1784 mark_objects (fringe_faces, max_fringe_bitmaps);
1785 }
1786
1787
1788
1789 static void init_fringe_once_for_pdumper (void);
1790
1791 void
1792 init_fringe_once (void)
1793 {
1794 pdumper_do_now_and_after_load (init_fringe_once_for_pdumper);
1795 }
1796
1797 static void
1798 init_fringe_once_for_pdumper (void)
1799 {
1800 for (int bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1801 init_fringe_bitmap (bt, &standard_bitmaps[bt], 1);
1802 }
1803
1804 void
1805 init_fringe (void)
1806 {
1807 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1808
1809 fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
1810
1811 verify (NIL_IS_ZERO);
1812 fringe_faces = xzalloc (max_fringe_bitmaps * sizeof *fringe_faces);
1813 }
1814
1815 void
1816 gui_init_fringe (struct redisplay_interface *rif)
1817 {
1818 int bt;
1819
1820 if (!rif || !rif->define_fringe_bitmap)
1821 return;
1822
1823
1824 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1825 {
1826 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1827 if (!fringe_bitmaps[bt])
1828 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1829 }
1830
1831
1832
1833
1834
1835 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1836 {
1837 struct fringe_bitmap *fb = fringe_bitmaps[bt];
1838 if (fb)
1839 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1840 }
1841 }
1842
1843
1844
1845
1846
1847 void
1848 gui_define_fringe_bitmap (struct frame *f, int n)
1849 {
1850 struct redisplay_interface *rif = FRAME_RIF (f);
1851
1852 if (!rif || !rif->define_fringe_bitmap || n >= max_used_fringe_bitmap)
1853 return;
1854
1855 struct fringe_bitmap *fb = fringe_bitmaps[n];
1856 if (fb)
1857 rif->define_fringe_bitmap (n, fb->bits, fb->height, fb->width);
1858 }
1859
1860 #ifdef HAVE_NTGUI
1861 void
1862 w32_reset_fringes (void)
1863 {
1864
1865 int bt;
1866 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1867
1868 if (!rif || !rif->destroy_fringe_bitmap)
1869 return;
1870
1871 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1872 rif->destroy_fringe_bitmap (bt);
1873 }
1874
1875 #endif