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
1431
1432
1433 #if defined (HAVE_X_WINDOWS) || defined (HAVE_PGTK) || defined (HAVE_ANDROID)
1434 static const unsigned char swap_nibble[16] =
1435 {
1436 0x0, 0x8, 0x4, 0xc,
1437 0x2, 0xa, 0x6, 0xe,
1438 0x1, 0x9, 0x5, 0xd,
1439 0x3, 0xb, 0x7, 0xf,
1440 };
1441 #endif
1442
1443 static void
1444 init_fringe_bitmap (int which, struct fringe_bitmap *fb, int once_p)
1445 {
1446 if (once_p || fb->dynamic)
1447 {
1448 #if defined (HAVE_X_WINDOWS) || defined (HAVE_ANDROID)
1449 unsigned short *bits = fb->bits;
1450 int j;
1451
1452 #ifdef USE_CAIRO
1453 for (j = 0; j < fb->height; j++)
1454 {
1455 unsigned short b = *bits;
1456 #ifdef WORDS_BIGENDIAN
1457 *bits++ = (b << (16 - fb->width));
1458 #else
1459 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1460 | (swap_nibble[(b>>4) & 0xf] << 8)
1461 | (swap_nibble[(b>>8) & 0xf] << 4)
1462 | (swap_nibble[(b>>12) & 0xf]));
1463 *bits++ = (b >> (16 - fb->width));
1464 #endif
1465 }
1466 #else
1467 if (fb->width <= 8)
1468 {
1469 unsigned char *cbits = (unsigned char *)fb->bits;
1470 for (j = 0; j < fb->height; j++)
1471 {
1472 unsigned short b = *bits++;
1473 unsigned char c;
1474 c = (unsigned char)((swap_nibble[b & 0xf] << 4)
1475 | (swap_nibble[(b>>4) & 0xf]));
1476 *cbits++ = (c >> (8 - fb->width));
1477 }
1478 }
1479 else
1480 {
1481 for (j = 0; j < fb->height; j++)
1482 {
1483 unsigned short b = *bits;
1484 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1485 | (swap_nibble[(b>>4) & 0xf] << 8)
1486 | (swap_nibble[(b>>8) & 0xf] << 4)
1487 | (swap_nibble[(b>>12) & 0xf]));
1488 b >>= (16 - fb->width);
1489 #ifdef WORDS_BIGENDIAN
1490 b = bswap_16 (b);
1491 #endif
1492 *bits++ = b;
1493 }
1494 }
1495 #endif
1496 #endif
1497
1498 #if !defined(HAVE_X_WINDOWS) && defined (HAVE_PGTK)
1499 unsigned short *bits = fb->bits;
1500 int j;
1501
1502 for (j = 0; j < fb->height; j++)
1503 {
1504 unsigned short b = *bits;
1505 #ifdef WORDS_BIGENDIAN
1506 *bits++ = (b << (16 - fb->width));
1507 #else
1508 b = (unsigned short)((swap_nibble[b & 0xf] << 12)
1509 | (swap_nibble[(b>>4) & 0xf] << 8)
1510 | (swap_nibble[(b>>8) & 0xf] << 4)
1511 | (swap_nibble[(b>>12) & 0xf]));
1512 *bits++ = (b >> (16 - fb->width));
1513 #endif
1514 }
1515 #endif
1516
1517 #ifdef HAVE_NTGUI
1518 unsigned short *bits = fb->bits;
1519 int j;
1520 for (j = 0; j < fb->height; j++)
1521 {
1522 unsigned short b = *bits;
1523 b <<= (16 - fb->width);
1524
1525
1526 b = ((b >> 8) | (b << 8));
1527 *bits++ = b;
1528 }
1529 #endif
1530 }
1531
1532 if (!once_p)
1533 {
1534
1535 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1536
1537 destroy_fringe_bitmap (which);
1538
1539 if (rif && rif->define_fringe_bitmap)
1540 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width);
1541
1542 fringe_bitmaps[which] = fb;
1543 if (which >= max_used_fringe_bitmap)
1544 max_used_fringe_bitmap = which + 1;
1545 }
1546 }
1547
1548
1549 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
1550 2, 5, 0,
1551 doc:
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562 )
1563 (Lisp_Object bitmap, Lisp_Object bits, Lisp_Object height, Lisp_Object width, Lisp_Object align)
1564 {
1565 int n, h, i, j;
1566 unsigned short *b;
1567 struct fringe_bitmap fb, *xfb;
1568 int fill1 = 0, fill2 = 0;
1569
1570 CHECK_SYMBOL (bitmap);
1571 h = CHECK_VECTOR_OR_STRING (bits);
1572
1573 if (NILP (height))
1574 fb.height = h;
1575 else
1576 {
1577 CHECK_FIXNUM (height);
1578 fb.height = max (0, min (XFIXNUM (height), 255));
1579 if (fb.height > h)
1580 {
1581 fill1 = (fb.height - h) / 2;
1582 fill2 = fb.height - h - fill1;
1583 }
1584 }
1585
1586 if (NILP (width))
1587 fb.width = 8;
1588 else
1589 {
1590 CHECK_FIXNUM (width);
1591 fb.width = max (1, min (XFIXNUM (width), 16));
1592 if (fb.width != XFIXNUM (width))
1593 args_out_of_range (width, build_string ("Width must be from 1 to 16"));
1594 }
1595
1596 fb.period = 0;
1597 fb.align = ALIGN_BITMAP_CENTER;
1598
1599 if (CONSP (align))
1600 {
1601 Lisp_Object period = XCDR (align);
1602 if (CONSP (period))
1603 {
1604 period = XCAR (period);
1605 if (!NILP (period))
1606 {
1607 fb.period = fb.height;
1608 fb.height = 255;
1609 }
1610 }
1611 align = XCAR (align);
1612 }
1613 if (EQ (align, Qtop))
1614 fb.align = ALIGN_BITMAP_TOP;
1615 else if (EQ (align, Qbottom))
1616 fb.align = ALIGN_BITMAP_BOTTOM;
1617 else if (!NILP (align) && !EQ (align, Qcenter))
1618 error ("Bad align argument");
1619
1620 n = lookup_fringe_bitmap (bitmap);
1621 if (!n)
1622 {
1623 if (max_used_fringe_bitmap < max_fringe_bitmaps)
1624 n = max_used_fringe_bitmap++;
1625 else
1626 {
1627 for (n = MAX_STANDARD_FRINGE_BITMAPS;
1628 n < max_fringe_bitmaps;
1629 n++)
1630 if (fringe_bitmaps[n] == NULL)
1631 break;
1632
1633 if (n == max_fringe_bitmaps)
1634 {
1635 int bitmaps = max_fringe_bitmaps + 20;
1636 if (MAX_FRINGE_BITMAPS < bitmaps)
1637 error ("No free fringe bitmap slots");
1638
1639 i = max_fringe_bitmaps;
1640 fringe_bitmaps = xrealloc (fringe_bitmaps,
1641 bitmaps * sizeof *fringe_bitmaps);
1642 fringe_faces = xrealloc (fringe_faces,
1643 bitmaps * sizeof *fringe_faces);
1644
1645 for (i = max_fringe_bitmaps; i < bitmaps; i++)
1646 {
1647 fringe_bitmaps[i] = NULL;
1648 fringe_faces[i] = Qnil;
1649 }
1650
1651 max_fringe_bitmaps = bitmaps;
1652 }
1653 }
1654
1655 Vfringe_bitmaps = Fcons (bitmap, Vfringe_bitmaps);
1656 Fput (bitmap, Qfringe, make_fixnum (n));
1657 }
1658
1659 fb.dynamic = true;
1660
1661 xfb = xmalloc (sizeof fb + fb.height * BYTES_PER_BITMAP_ROW);
1662 fb.bits = b = (unsigned short *) (xfb + 1);
1663
1664 j = 0;
1665 while (j < fb.height)
1666 {
1667 for (i = 0; i < fill1 && j < fb.height; i++)
1668 b[j++] = 0;
1669 for (i = 0; i < h && j < fb.height; i++)
1670 {
1671 Lisp_Object elt = Faref (bits, make_fixnum (i));
1672 b[j++] = FIXNUMP (elt) ? XFIXNUM (elt) : 0;
1673 }
1674 for (i = 0; i < fill2 && j < fb.height; i++)
1675 b[j++] = 0;
1676 }
1677
1678 *xfb = fb;
1679
1680 init_fringe_bitmap (n, xfb, 0);
1681
1682 return bitmap;
1683 }
1684
1685 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face,
1686 1, 2, 0,
1687 doc:
1688
1689
1690 )
1691 (Lisp_Object bitmap, Lisp_Object face)
1692 {
1693 int n;
1694
1695 CHECK_SYMBOL (bitmap);
1696 n = lookup_fringe_bitmap (bitmap);
1697 if (!n)
1698 error ("Undefined fringe bitmap");
1699
1700
1701
1702
1703
1704 fringe_faces[n] = face;
1705 return Qnil;
1706 }
1707
1708 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos,
1709 0, 2, 0,
1710 doc:
1711
1712
1713
1714
1715
1716 )
1717 (Lisp_Object pos, Lisp_Object window)
1718 {
1719 struct window *w;
1720 struct glyph_row *row;
1721 ptrdiff_t textpos;
1722
1723 w = decode_any_window (window);
1724 XSETWINDOW (window, w);
1725
1726 if (!NILP (pos))
1727 {
1728 EMACS_INT p = fix_position (pos);
1729 if (! (BEGV <= p && p <= ZV))
1730 args_out_of_range (window, pos);
1731 textpos = p;
1732 }
1733 else if (w == XWINDOW (selected_window))
1734 textpos = PT;
1735 else
1736 textpos = marker_position (w->pointm);
1737
1738 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
1739 row = row_containing_pos (w, textpos, row, NULL, 0);
1740 if (row)
1741 return list3 (get_fringe_bitmap_name (row->left_fringe_bitmap),
1742 get_fringe_bitmap_name (row->right_fringe_bitmap),
1743 (row->overlay_arrow_bitmap == 0 ? Qnil
1744 : row->overlay_arrow_bitmap < 0 ? Qt
1745 : get_fringe_bitmap_name (row->overlay_arrow_bitmap)));
1746 else
1747 return Qnil;
1748 }
1749
1750
1751
1752
1753
1754
1755 void
1756 syms_of_fringe (void)
1757 {
1758 DEFSYM (Qtruncation, "truncation");
1759 DEFSYM (Qcontinuation, "continuation");
1760 DEFSYM (Qoverlay_arrow, "overlay-arrow");
1761 DEFSYM (Qempty_line, "empty-line");
1762 DEFSYM (Qtop_bottom, "top-bottom");
1763 DEFSYM (Qhollow_small, "hollow-small");
1764
1765 defsubr (&Sdestroy_fringe_bitmap);
1766 defsubr (&Sdefine_fringe_bitmap);
1767 defsubr (&Sfringe_bitmaps_at_pos);
1768 defsubr (&Sset_fringe_bitmap_face);
1769
1770 DEFVAR_LISP ("overflow-newline-into-fringe", Voverflow_newline_into_fringe,
1771 doc:
1772
1773
1774
1775
1776 );
1777 Voverflow_newline_into_fringe = Qt;
1778
1779 DEFVAR_LISP ("fringe-bitmaps", Vfringe_bitmaps,
1780 doc: );
1781 Vfringe_bitmaps = Qnil;
1782 }
1783
1784
1785
1786 void
1787 mark_fringe_data (void)
1788 {
1789 mark_objects (fringe_faces, max_fringe_bitmaps);
1790 }
1791
1792
1793
1794 static void init_fringe_once_for_pdumper (void);
1795
1796 void
1797 init_fringe_once (void)
1798 {
1799 pdumper_do_now_and_after_load (init_fringe_once_for_pdumper);
1800 }
1801
1802 static void
1803 init_fringe_once_for_pdumper (void)
1804 {
1805 for (int bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1806 init_fringe_bitmap (bt, &standard_bitmaps[bt], 1);
1807 }
1808
1809 void
1810 init_fringe (void)
1811 {
1812 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1813
1814 fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
1815
1816 verify (NIL_IS_ZERO);
1817 fringe_faces = xzalloc (max_fringe_bitmaps * sizeof *fringe_faces);
1818 }
1819
1820 void
1821 gui_init_fringe (struct redisplay_interface *rif)
1822 {
1823 int bt;
1824
1825 if (!rif || !rif->define_fringe_bitmap)
1826 return;
1827
1828
1829 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
1830 {
1831 struct fringe_bitmap *fb = &standard_bitmaps[bt];
1832 if (!fringe_bitmaps[bt])
1833 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1834 }
1835
1836
1837
1838
1839
1840 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1841 {
1842 struct fringe_bitmap *fb = fringe_bitmaps[bt];
1843 if (fb)
1844 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
1845 }
1846 }
1847
1848
1849
1850
1851
1852 void
1853 gui_define_fringe_bitmap (struct frame *f, int n)
1854 {
1855 struct redisplay_interface *rif = FRAME_RIF (f);
1856
1857 if (!rif || !rif->define_fringe_bitmap || n >= max_used_fringe_bitmap)
1858 return;
1859
1860 struct fringe_bitmap *fb = fringe_bitmaps[n];
1861 if (fb)
1862 rif->define_fringe_bitmap (n, fb->bits, fb->height, fb->width);
1863 }
1864
1865 #ifdef HAVE_NTGUI
1866 void
1867 w32_reset_fringes (void)
1868 {
1869
1870 int bt;
1871 struct redisplay_interface *rif = FRAME_RIF (SELECTED_FRAME ());
1872
1873 if (!rif || !rif->destroy_fringe_bitmap)
1874 return;
1875
1876 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
1877 rif->destroy_fringe_bitmap (bt);
1878 }
1879
1880 #endif