Mercurial > emacs
comparison src/fringe.c @ 53879:e3771c262410
New file. Move original fringe related declarations
and code from dispextern.h and xdisp.c here.
Rework code to support user defined fringe bitmaps, redefining
standard bitmaps, ability to overlay user defined bitmap with
overlay arrow bitmap, and add faces to bitmaps.
(Voverflow_newline_into_fringe): Declare here.
(enum fringe_bitmap_align): New enum.
(..._bits): All bitmaps are now defined without bitswapping; that
is now done in init_fringe_once (if necessary).
(standard_bitmaps): New array with specifications for the
standard fringe bitmaps.
(fringe_faces): New array.
(valid_fringe_bitmap_id_p): New function.
(draw_fringe_bitmap_1): Rename from draw_fringe_bitmap.
(draw_fringe_bitmap): New function which draws fringe bitmap,
possibly overlaying bitmap with cursor in right fringe or the
overlay arrow in the left fringe.
(update_window_fringes): Do not handle overlay arrow here.
Compare and copy fringe bitmap faces.
(init_fringe_bitmap): New function.
(Fdefine_fringe_bitmap, Fdestroy_fringe_bitmap): New DEFUNs to
define and destroy user defined fringe bitmaps.
(Fset_fringe_bitmap_face): New DEFUN to set face for a fringe bitmap.
(Ffringe_bitmaps_at_pos): New DEFUN to read current fringe bitmaps.
(syms_of_fringe): New function. Defsubr new DEFUNs.
DEFVAR_LISP Voverflow_newline_into_fringe.
(init_fringe_once, init_fringe): New functions.
(w32_init_fringe, w32_reset_fringes) [WINDOWS_NT]: New functions.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 08 Feb 2004 23:18:16 +0000 |
parents | |
children | 5d607f751ba3 |
comparison
equal
deleted
inserted
replaced
53878:edab26b4150c | 53879:e3771c262410 |
---|---|
1 /* Fringe handling (split from xdisp.c). | |
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04 | |
3 Free Software Foundation, Inc. | |
4 | |
5 This file is part of GNU Emacs. | |
6 | |
7 GNU Emacs is free software; you can redistribute it and/or modify | |
8 it under the terms of the GNU General Public License as published by | |
9 the Free Software Foundation; either version 2, or (at your option) | |
10 any later version. | |
11 | |
12 GNU Emacs is distributed in the hope that it will be useful, | |
13 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 GNU General Public License for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with GNU Emacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 #include <config.h> | |
23 #include <stdio.h> | |
24 | |
25 #include "lisp.h" | |
26 #include "frame.h" | |
27 #include "window.h" | |
28 #include "dispextern.h" | |
29 #include "buffer.h" | |
30 #include "blockinput.h" | |
31 | |
32 #ifdef HAVE_WINDOW_SYSTEM | |
33 | |
34 extern Lisp_Object Qtop, Qbottom, Qcenter; | |
35 | |
36 /* Non-nil means that newline may flow into the right fringe. */ | |
37 | |
38 Lisp_Object Voverflow_newline_into_fringe; | |
39 | |
40 | |
41 enum fringe_bitmap_type | |
42 { | |
43 NO_FRINGE_BITMAP = 0, | |
44 UNDEF_FRINGE_BITMAP, | |
45 LEFT_TRUNCATION_BITMAP, | |
46 RIGHT_TRUNCATION_BITMAP, | |
47 UP_ARROW_BITMAP, | |
48 DOWN_ARROW_BITMAP, | |
49 CONTINUED_LINE_BITMAP, | |
50 CONTINUATION_LINE_BITMAP, | |
51 OVERLAY_ARROW_BITMAP, | |
52 TOP_LEFT_ANGLE_BITMAP, | |
53 TOP_RIGHT_ANGLE_BITMAP, | |
54 BOTTOM_LEFT_ANGLE_BITMAP, | |
55 BOTTOM_RIGHT_ANGLE_BITMAP, | |
56 LEFT_BRACKET_BITMAP, | |
57 RIGHT_BRACKET_BITMAP, | |
58 FILLED_BOX_CURSOR_BITMAP, | |
59 HOLLOW_BOX_CURSOR_BITMAP, | |
60 HOLLOW_SQUARE_BITMAP, | |
61 BAR_CURSOR_BITMAP, | |
62 HBAR_CURSOR_BITMAP, | |
63 ZV_LINE_BITMAP, | |
64 MAX_STANDARD_FRINGE_BITMAPS | |
65 }; | |
66 | |
67 enum fringe_bitmap_align | |
68 { | |
69 ALIGN_BITMAP_CENTER = 0, | |
70 ALIGN_BITMAP_TOP, | |
71 ALIGN_BITMAP_BOTTOM | |
72 }; | |
73 | |
74 struct fringe_bitmap | |
75 { | |
76 unsigned char *bits; | |
77 unsigned height : 8; | |
78 unsigned width : 8; | |
79 unsigned period : 8; | |
80 unsigned align : 2; | |
81 unsigned dynamic : 1; | |
82 }; | |
83 | |
84 | |
85 /*********************************************************************** | |
86 Fringe bitmaps | |
87 ***********************************************************************/ | |
88 | |
89 /* Undefined bitmap. A question mark. */ | |
90 /* | |
91 ..xxxx.. | |
92 .xxxxxx. | |
93 xx....xx | |
94 xx....xx | |
95 ....xx.. | |
96 ...xx... | |
97 ...xx... | |
98 ........ | |
99 ...xx... | |
100 ...xx... | |
101 */ | |
102 static unsigned char unknown_bits[] = { | |
103 0x3c, 0x7e, 0x7e, 0x0c, 0x18, 0x18, 0x00, 0x18, 0x18}; | |
104 | |
105 /* An arrow like this: `<-'. */ | |
106 /* | |
107 ...xx... | |
108 ..xx.... | |
109 .xx..... | |
110 xxxxxx.. | |
111 xxxxxx.. | |
112 .xx..... | |
113 ..xx.... | |
114 ...xx... | |
115 */ | |
116 static unsigned char left_arrow_bits[] = { | |
117 0x18, 0x30, 0x60, 0xfc, 0xfc, 0x60, 0x30, 0x18}; | |
118 | |
119 | |
120 /* Right truncation arrow bitmap `->'. */ | |
121 /* | |
122 ...xx... | |
123 ....xx.. | |
124 .....xx. | |
125 ..xxxxxx | |
126 ..xxxxxx | |
127 .....xx. | |
128 ....xx.. | |
129 ...xx... | |
130 */ | |
131 static unsigned char right_arrow_bits[] = { | |
132 0x18, 0x0c, 0x06, 0x3f, 0x3f, 0x06, 0x0c, 0x18}; | |
133 | |
134 | |
135 /* Up arrow bitmap. */ | |
136 /* | |
137 ...xx... | |
138 ..xxxx.. | |
139 .xxxxxx. | |
140 xxxxxxxx | |
141 ...xx... | |
142 ...xx... | |
143 ...xx... | |
144 ...xx... | |
145 */ | |
146 static unsigned char up_arrow_bits[] = { | |
147 0x18, 0x3c, 0x7e, 0xff, 0x18, 0x18, 0x18, 0x18}; | |
148 | |
149 | |
150 /* Down arrow bitmap. */ | |
151 /* | |
152 ...xx... | |
153 ...xx... | |
154 ...xx... | |
155 ...xx... | |
156 xxxxxxxx | |
157 .xxxxxx. | |
158 ..xxxx.. | |
159 ...xx... | |
160 */ | |
161 static unsigned char down_arrow_bits[] = { | |
162 0x18, 0x18, 0x18, 0x18, 0xff, 0x7e, 0x3c, 0x18}; | |
163 | |
164 /* Marker for continued lines. */ | |
165 /* | |
166 ..xxxx.. | |
167 ..xxxxx. | |
168 ......xx | |
169 ..x..xxx | |
170 ..xxxxxx | |
171 ..xxxxx. | |
172 ..xxxx.. | |
173 ..xxxxx. | |
174 */ | |
175 static unsigned char continued_bits[] = { | |
176 0x3c, 0x3e, 0x03, 0x27, 0x3f, 0x3e, 0x3c, 0x3e}; | |
177 | |
178 /* Marker for continuation lines. */ | |
179 /* | |
180 ..xxxx.. | |
181 .xxxxx.. | |
182 xx...... | |
183 xxx..x.. | |
184 xxxxxx.. | |
185 .xxxxx.. | |
186 ..xxxx.. | |
187 .xxxxx.. | |
188 */ | |
189 static unsigned char continuation_bits[] = { | |
190 0x3c, 0x7c, 0xc0, 0xe4, 0xfc, 0x7c, 0x3c, 0x7c}; | |
191 | |
192 /* Overlay arrow bitmap. A triangular arrow. */ | |
193 /* | |
194 xx...... | |
195 xxxx.... | |
196 xxxxx... | |
197 xxxxxx.. | |
198 xxxxxx.. | |
199 xxxxx... | |
200 xxxx.... | |
201 xx...... | |
202 */ | |
203 static unsigned char ov_bits[] = { | |
204 0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0}; | |
205 | |
206 #if 0 | |
207 /* Reverse Overlay arrow bitmap. A triangular arrow. */ | |
208 /* | |
209 ......xx | |
210 ....xxxx | |
211 ...xxxxx | |
212 ..xxxxxx | |
213 ..xxxxxx | |
214 ...xxxxx | |
215 ....xxxx | |
216 ......xx | |
217 */ | |
218 static unsigned char rev_ov_bits[] = { | |
219 0x03, 0x0f, 0x1f, 0x3f, 0x3f, 0x1f, 0x0f, 0x03}; | |
220 #endif | |
221 | |
222 /* First line bitmap. An top-left angle. */ | |
223 /* | |
224 xxxxxx.. | |
225 xxxxxx.. | |
226 xx...... | |
227 xx...... | |
228 xx...... | |
229 xx...... | |
230 xx...... | |
231 ........ | |
232 */ | |
233 static unsigned char top_left_angle_bits[] = { | |
234 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00}; | |
235 | |
236 /* First line bitmap. An right-up angle. */ | |
237 /* | |
238 ..xxxxxx | |
239 ..xxxxxx | |
240 ......xx | |
241 ......xx | |
242 ......xx | |
243 ......xx | |
244 ......xx | |
245 ........ | |
246 */ | |
247 static unsigned char top_right_angle_bits[] = { | |
248 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00}; | |
249 | |
250 /* Last line bitmap. An left-down angle. */ | |
251 /* | |
252 ........ | |
253 xx...... | |
254 xx...... | |
255 xx...... | |
256 xx...... | |
257 xx...... | |
258 xxxxxx.. | |
259 xxxxxx.. | |
260 */ | |
261 static unsigned char bottom_left_angle_bits[] = { | |
262 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc}; | |
263 | |
264 /* Last line bitmap. An right-down angle. */ | |
265 /* | |
266 ........ | |
267 ......xx | |
268 ......xx | |
269 ......xx | |
270 ......xx | |
271 ......xx | |
272 ..xxxxxx | |
273 ..xxxxxx | |
274 */ | |
275 static unsigned char bottom_right_angle_bits[] = { | |
276 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f}; | |
277 | |
278 /* First/last line bitmap. An left bracket. */ | |
279 /* | |
280 xxxxxx.. | |
281 xxxxxx.. | |
282 xx...... | |
283 xx...... | |
284 xx...... | |
285 xx...... | |
286 xx...... | |
287 xx...... | |
288 xxxxxx.. | |
289 xxxxxx.. | |
290 */ | |
291 static unsigned char left_bracket_bits[] = { | |
292 0xfc, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xfc}; | |
293 | |
294 /* First/last line bitmap. An right bracket. */ | |
295 /* | |
296 ..xxxxxx | |
297 ..xxxxxx | |
298 ......xx | |
299 ......xx | |
300 ......xx | |
301 ......xx | |
302 ......xx | |
303 ......xx | |
304 ..xxxxxx | |
305 ..xxxxxx | |
306 */ | |
307 static unsigned char right_bracket_bits[] = { | |
308 0x3f, 0x3f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3f, 0x3f}; | |
309 | |
310 /* Filled box cursor bitmap. A filled box; max 13 pixels high. */ | |
311 /* | |
312 xxxxxxx. | |
313 xxxxxxx. | |
314 xxxxxxx. | |
315 xxxxxxx. | |
316 xxxxxxx. | |
317 xxxxxxx. | |
318 xxxxxxx. | |
319 xxxxxxx. | |
320 xxxxxxx. | |
321 xxxxxxx. | |
322 xxxxxxx. | |
323 xxxxxxx. | |
324 xxxxxxx. | |
325 */ | |
326 static unsigned char filled_box_cursor_bits[] = { | |
327 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe}; | |
328 | |
329 /* Hollow box cursor bitmap. A hollow box; max 13 pixels high. */ | |
330 /* | |
331 xxxxxxx. | |
332 x.....x. | |
333 x.....x. | |
334 x.....x. | |
335 x.....x. | |
336 x.....x. | |
337 x.....x. | |
338 x.....x. | |
339 x.....x. | |
340 x.....x. | |
341 x.....x. | |
342 x.....x. | |
343 xxxxxxx. | |
344 */ | |
345 static unsigned char hollow_box_cursor_bits[] = { | |
346 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe}; | |
347 | |
348 /* Bar cursor bitmap. A vertical bar; max 13 pixels high. */ | |
349 /* | |
350 xx...... | |
351 xx...... | |
352 xx...... | |
353 xx...... | |
354 xx...... | |
355 xx...... | |
356 xx...... | |
357 xx...... | |
358 xx...... | |
359 xx...... | |
360 xx...... | |
361 xx...... | |
362 xx...... | |
363 */ | |
364 static unsigned char bar_cursor_bits[] = { | |
365 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}; | |
366 | |
367 /* HBar cursor bitmap. A horisontal bar; 2 pixels high. */ | |
368 /* | |
369 xxxxxxx. | |
370 xxxxxxx. | |
371 */ | |
372 static unsigned char hbar_cursor_bits[] = { | |
373 0xfe, 0xfe}; | |
374 | |
375 | |
376 /* Bitmap drawn to indicate lines not displaying text if | |
377 `indicate-empty-lines' is non-nil. */ | |
378 /* | |
379 ........ | |
380 ..xxxx.. | |
381 ........ | |
382 ........ | |
383 ..xxxx.. | |
384 ........ | |
385 */ | |
386 static unsigned char zv_bits[] = { | |
387 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
388 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
389 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
390 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
391 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
392 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
393 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, | |
394 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3c, 0x00}; | |
395 | |
396 /* Hollow square bitmap. */ | |
397 /* | |
398 .xxxxxx. | |
399 .x....x. | |
400 .x....x. | |
401 .x....x. | |
402 .x....x. | |
403 .xxxxxx. | |
404 */ | |
405 static unsigned char hollow_square_bits[] = { | |
406 0x7e, 0x42, 0x42, 0x42, 0x42, 0x7e}; | |
407 | |
408 | |
409 | |
410 #define FRBITS(bits) bits, sizeof bits | |
411 struct fringe_bitmap standard_bitmaps[MAX_STANDARD_FRINGE_BITMAPS] = | |
412 { | |
413 { NULL, 0, 0, 0, 0, 0 }, /* NO_FRINGE_BITMAP */ | |
414 { FRBITS (unknown_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
415 { FRBITS (left_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
416 { FRBITS (right_arrow_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
417 { FRBITS (up_arrow_bits), 8, 0, ALIGN_BITMAP_TOP, 0 }, | |
418 { FRBITS (down_arrow_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 }, | |
419 { FRBITS (continued_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
420 { FRBITS (continuation_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
421 { FRBITS (ov_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
422 { FRBITS (top_left_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 }, | |
423 { FRBITS (top_right_angle_bits), 8, 0, ALIGN_BITMAP_TOP, 0 }, | |
424 { FRBITS (bottom_left_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 }, | |
425 { FRBITS (bottom_right_angle_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 }, | |
426 { FRBITS (left_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
427 { FRBITS (right_bracket_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
428 { FRBITS (filled_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
429 { FRBITS (hollow_box_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
430 { FRBITS (hollow_square_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
431 { FRBITS (bar_cursor_bits), 8, 0, ALIGN_BITMAP_CENTER, 0 }, | |
432 { FRBITS (hbar_cursor_bits), 8, 0, ALIGN_BITMAP_BOTTOM, 0 }, | |
433 { FRBITS (zv_bits), 8, 3, ALIGN_BITMAP_TOP, 0 }, | |
434 }; | |
435 | |
436 static struct fringe_bitmap *fringe_bitmaps[MAX_FRINGE_BITMAPS]; | |
437 static unsigned fringe_faces[MAX_FRINGE_BITMAPS]; | |
438 | |
439 static int max_used_fringe_bitmap = MAX_STANDARD_FRINGE_BITMAPS; | |
440 | |
441 /* Return 1 if FRINGE_ID is a valid fringe bitmap id. */ | |
442 | |
443 int | |
444 valid_fringe_bitmap_id_p (fringe_id) | |
445 int fringe_id; | |
446 { | |
447 return (fringe_id >= NO_FRINGE_BITMAP | |
448 && fringe_id < max_used_fringe_bitmap | |
449 && (fringe_id < MAX_STANDARD_FRINGE_BITMAPS | |
450 || fringe_bitmaps[fringe_id] != NULL)); | |
451 } | |
452 | |
453 /* Draw the bitmap WHICH in one of the left or right fringes of | |
454 window W. ROW is the glyph row for which to display the bitmap; it | |
455 determines the vertical position at which the bitmap has to be | |
456 drawn. | |
457 LEFT_P is 1 for left fringe, 0 for right fringe. | |
458 */ | |
459 | |
460 void | |
461 draw_fringe_bitmap_1 (w, row, left_p, overlay, which) | |
462 struct window *w; | |
463 struct glyph_row *row; | |
464 int left_p, overlay; | |
465 enum fringe_bitmap_type which; | |
466 { | |
467 struct frame *f = XFRAME (WINDOW_FRAME (w)); | |
468 struct draw_fringe_bitmap_params p; | |
469 struct fringe_bitmap *fb; | |
470 int period; | |
471 int face_id = DEFAULT_FACE_ID; | |
472 | |
473 p.cursor_p = 0; | |
474 p.overlay_p = (overlay & 1) == 1; | |
475 p.cursor_p = (overlay & 2) == 2; | |
476 | |
477 if (which != NO_FRINGE_BITMAP) | |
478 { | |
479 } | |
480 else if (left_p) | |
481 { | |
482 which = row->left_fringe_bitmap; | |
483 face_id = row->left_fringe_face_id; | |
484 } | |
485 else | |
486 { | |
487 which = row->right_fringe_bitmap; | |
488 face_id = row->right_fringe_face_id; | |
489 } | |
490 | |
491 if (face_id == DEFAULT_FACE_ID) | |
492 face_id = fringe_faces[which]; | |
493 | |
494 fb = fringe_bitmaps[which]; | |
495 if (fb == NULL) | |
496 fb = &standard_bitmaps[which < MAX_STANDARD_FRINGE_BITMAPS | |
497 ? which : UNDEF_FRINGE_BITMAP]; | |
498 | |
499 period = fb->period; | |
500 | |
501 /* Convert row to frame coordinates. */ | |
502 p.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | |
503 | |
504 p.which = which; | |
505 p.bits = fb->bits; | |
506 p.wd = fb->width; | |
507 | |
508 p.h = fb->height; | |
509 p.dh = (period > 0 ? (p.y % period) : 0); | |
510 p.h -= p.dh; | |
511 /* Clip bitmap if too high. */ | |
512 if (p.h > row->height) | |
513 p.h = row->height; | |
514 | |
515 p.face = FACE_FROM_ID (f, face_id); | |
516 | |
517 if (p.face == NULL) | |
518 { | |
519 /* Why does this happen? ++kfs */ | |
520 return; | |
521 } | |
522 | |
523 PREPARE_FACE_FOR_DISPLAY (f, p.face); | |
524 | |
525 /* Clear left fringe if no bitmap to draw or if bitmap doesn't fill | |
526 the fringe. */ | |
527 p.bx = -1; | |
528 if (left_p) | |
529 { | |
530 int wd = WINDOW_LEFT_FRINGE_WIDTH (w); | |
531 int x = window_box_left (w, (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | |
532 ? LEFT_MARGIN_AREA | |
533 : TEXT_AREA)); | |
534 if (p.wd > wd) | |
535 p.wd = wd; | |
536 p.x = x - p.wd - (wd - p.wd) / 2; | |
537 | |
538 if (p.wd < wd || row->height > p.h) | |
539 { | |
540 /* If W has a vertical border to its left, don't draw over it. */ | |
541 wd -= ((!WINDOW_LEFTMOST_P (w) | |
542 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)) | |
543 ? 1 : 0); | |
544 p.bx = x - wd; | |
545 p.nx = wd; | |
546 } | |
547 } | |
548 else | |
549 { | |
550 int x = window_box_right (w, | |
551 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) | |
552 ? RIGHT_MARGIN_AREA | |
553 : TEXT_AREA)); | |
554 int wd = WINDOW_RIGHT_FRINGE_WIDTH (w); | |
555 if (p.wd > wd) | |
556 p.wd = wd; | |
557 p.x = x + (wd - p.wd) / 2; | |
558 /* Clear right fringe if no bitmap to draw of if bitmap doesn't fill | |
559 the fringe. */ | |
560 if (p.wd < wd || row->height > p.h) | |
561 { | |
562 p.bx = x; | |
563 p.nx = wd; | |
564 } | |
565 } | |
566 | |
567 if (p.bx >= 0) | |
568 { | |
569 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w); | |
570 | |
571 p.by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, row->y)); | |
572 p.ny = row->visible_height; | |
573 } | |
574 | |
575 /* Adjust y to the offset in the row to start drawing the bitmap. */ | |
576 switch (fb->align) | |
577 { | |
578 case ALIGN_BITMAP_CENTER: | |
579 p.y += (row->height - p.h) / 2; | |
580 break; | |
581 case ALIGN_BITMAP_BOTTOM: | |
582 p.h = fb->height; | |
583 p.y += (row->visible_height - p.h); | |
584 break; | |
585 case ALIGN_BITMAP_TOP: | |
586 break; | |
587 } | |
588 | |
589 rif->draw_fringe_bitmap (w, row, &p); | |
590 } | |
591 | |
592 void | |
593 draw_fringe_bitmap (w, row, left_p) | |
594 struct window *w; | |
595 struct glyph_row *row; | |
596 int left_p; | |
597 { | |
598 int overlay = 0; | |
599 | |
600 if (!left_p && row->cursor_in_fringe_p) | |
601 { | |
602 int cursor = NO_FRINGE_BITMAP; | |
603 | |
604 switch (w->phys_cursor_type) | |
605 { | |
606 case HOLLOW_BOX_CURSOR: | |
607 if (row->visible_height >= sizeof(hollow_box_cursor_bits)) | |
608 cursor = HOLLOW_BOX_CURSOR_BITMAP; | |
609 else | |
610 cursor = HOLLOW_SQUARE_BITMAP; | |
611 break; | |
612 case FILLED_BOX_CURSOR: | |
613 cursor = FILLED_BOX_CURSOR_BITMAP; | |
614 break; | |
615 case BAR_CURSOR: | |
616 cursor = BAR_CURSOR_BITMAP; | |
617 break; | |
618 case HBAR_CURSOR: | |
619 cursor = HBAR_CURSOR_BITMAP; | |
620 break; | |
621 case NO_CURSOR: | |
622 default: | |
623 w->phys_cursor_on_p = 0; | |
624 row->cursor_in_fringe_p = 0; | |
625 break; | |
626 } | |
627 if (cursor != NO_FRINGE_BITMAP) | |
628 { | |
629 draw_fringe_bitmap_1 (w, row, 0, 2, cursor); | |
630 overlay = cursor == FILLED_BOX_CURSOR_BITMAP ? 3 : 1; | |
631 } | |
632 } | |
633 | |
634 draw_fringe_bitmap_1 (w, row, left_p, overlay, NO_FRINGE_BITMAP); | |
635 | |
636 if (left_p && row->overlay_arrow_p) | |
637 draw_fringe_bitmap_1 (w, row, 1, 1, OVERLAY_ARROW_BITMAP); | |
638 } | |
639 | |
640 | |
641 /* Draw fringe bitmaps for glyph row ROW on window W. Call this | |
642 function with input blocked. */ | |
643 | |
644 void | |
645 draw_row_fringe_bitmaps (w, row) | |
646 struct window *w; | |
647 struct glyph_row *row; | |
648 { | |
649 xassert (interrupt_input_blocked); | |
650 | |
651 /* If row is completely invisible, because of vscrolling, we | |
652 don't have to draw anything. */ | |
653 if (row->visible_height <= 0) | |
654 return; | |
655 | |
656 if (WINDOW_LEFT_FRINGE_WIDTH (w) != 0) | |
657 draw_fringe_bitmap (w, row, 1); | |
658 | |
659 if (WINDOW_RIGHT_FRINGE_WIDTH (w) != 0) | |
660 draw_fringe_bitmap (w, row, 0); | |
661 } | |
662 | |
663 /* Draw the fringes of window W. Only fringes for rows marked for | |
664 update in redraw_fringe_bitmaps_p are drawn. */ | |
665 | |
666 void | |
667 draw_window_fringes (w) | |
668 struct window *w; | |
669 { | |
670 struct glyph_row *row; | |
671 int yb = window_text_bottom_y (w); | |
672 int nrows = w->current_matrix->nrows; | |
673 int y = 0, rn; | |
674 | |
675 if (w->pseudo_window_p) | |
676 return; | |
677 | |
678 for (y = 0, rn = 0, row = w->current_matrix->rows; | |
679 y < yb && rn < nrows; | |
680 y += row->height, ++row, ++rn) | |
681 { | |
682 if (!row->redraw_fringe_bitmaps_p) | |
683 continue; | |
684 draw_row_fringe_bitmaps (w, row); | |
685 row->redraw_fringe_bitmaps_p = 0; | |
686 } | |
687 } | |
688 | |
689 | |
690 /* Recalculate the bitmaps to show in the fringes of window W. | |
691 If FORCE_P is 0, only mark rows with modified bitmaps for update in | |
692 redraw_fringe_bitmaps_p; else mark all rows for update. */ | |
693 | |
694 int | |
695 update_window_fringes (w, force_p) | |
696 struct window *w; | |
697 int force_p; | |
698 { | |
699 struct glyph_row *row, *cur = 0; | |
700 int yb = window_text_bottom_y (w); | |
701 int rn, nrows = w->current_matrix->nrows; | |
702 int y; | |
703 int redraw_p = 0; | |
704 Lisp_Object ind; | |
705 int boundary_pos = 0, arrow_pos = 0; | |
706 int empty_pos = 0; | |
707 | |
708 if (w->pseudo_window_p) | |
709 return 0; | |
710 | |
711 if (!MINI_WINDOW_P (w) | |
712 && (ind = XBUFFER (w->buffer)->indicate_buffer_boundaries, !NILP (ind))) | |
713 { | |
714 int do_eob = 1, do_bob = 1; | |
715 Lisp_Object arrows; | |
716 | |
717 if (CONSP (ind)) | |
718 arrows = XCDR (ind), ind = XCAR (ind); | |
719 else | |
720 arrows = ind; | |
721 | |
722 if (EQ (ind, Qleft)) | |
723 boundary_pos = -1; | |
724 else if (EQ (ind, Qright)) | |
725 boundary_pos = 1; | |
726 | |
727 if (EQ (arrows, Qleft)) | |
728 arrow_pos = -1; | |
729 else if (EQ (arrows, Qright)) | |
730 arrow_pos = 1; | |
731 | |
732 for (y = 0, rn = 0; | |
733 y < yb && rn < nrows; | |
734 y += row->height, ++rn) | |
735 { | |
736 unsigned indicate_bob_p, indicate_top_line_p; | |
737 unsigned indicate_eob_p, indicate_bottom_line_p; | |
738 | |
739 row = w->desired_matrix->rows + rn; | |
740 if (!row->enabled_p) | |
741 row = w->current_matrix->rows + rn; | |
742 | |
743 indicate_bob_p = row->indicate_bob_p; | |
744 indicate_top_line_p = row->indicate_top_line_p; | |
745 indicate_eob_p = row->indicate_eob_p; | |
746 indicate_bottom_line_p = row->indicate_bottom_line_p; | |
747 | |
748 row->indicate_bob_p = row->indicate_top_line_p = 0; | |
749 row->indicate_eob_p = row->indicate_bottom_line_p = 0; | |
750 | |
751 if (!NILP (ind) | |
752 && MATRIX_ROW_START_CHARPOS (row) <= BUF_BEGV (XBUFFER (w->buffer))) | |
753 row->indicate_bob_p = do_bob, do_bob = 0; | |
754 else if (!NILP (arrows) | |
755 && (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0) == rn) | |
756 row->indicate_top_line_p = 1; | |
757 | |
758 if (!NILP (ind) | |
759 && MATRIX_ROW_END_CHARPOS (row) >= BUF_ZV (XBUFFER (w->buffer))) | |
760 row->indicate_eob_p = do_eob, do_eob = 0; | |
761 else if (!NILP (arrows) | |
762 && y + row->height >= yb) | |
763 row->indicate_bottom_line_p = 1; | |
764 | |
765 if (indicate_bob_p != row->indicate_bob_p | |
766 || indicate_top_line_p != row->indicate_top_line_p | |
767 || indicate_eob_p != row->indicate_eob_p | |
768 || indicate_bottom_line_p != row->indicate_bottom_line_p) | |
769 row->redraw_fringe_bitmaps_p = 1; | |
770 } | |
771 } | |
772 | |
773 if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qright)) | |
774 empty_pos = 1; | |
775 else if (EQ (XBUFFER (w->buffer)->indicate_empty_lines, Qleft)) | |
776 empty_pos = -1; | |
777 | |
778 for (y = 0, rn = 0; | |
779 y < yb && rn < nrows; | |
780 y += row->height, rn++) | |
781 { | |
782 enum fringe_bitmap_type left, right; | |
783 unsigned left_face_id, right_face_id; | |
784 | |
785 row = w->desired_matrix->rows + rn; | |
786 cur = w->current_matrix->rows + rn; | |
787 if (!row->enabled_p) | |
788 row = cur; | |
789 | |
790 left_face_id = right_face_id = DEFAULT_FACE_ID; | |
791 | |
792 /* Decide which bitmap to draw in the left fringe. */ | |
793 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0) | |
794 left = NO_FRINGE_BITMAP; | |
795 else if (row->left_user_fringe_bitmap != NO_FRINGE_BITMAP) | |
796 { | |
797 left = row->left_user_fringe_bitmap; | |
798 left_face_id = row->left_user_fringe_face_id; | |
799 } | |
800 #if 0 /* this is now done via an overlay */ | |
801 else if (row->overlay_arrow_p) | |
802 left = OVERLAY_ARROW_BITMAP; | |
803 #endif | |
804 else if (row->indicate_bob_p && boundary_pos <= 0) | |
805 left = ((row->indicate_eob_p && boundary_pos < 0) | |
806 ? LEFT_BRACKET_BITMAP : TOP_LEFT_ANGLE_BITMAP); | |
807 else if (row->indicate_eob_p && boundary_pos < 0) | |
808 left = BOTTOM_LEFT_ANGLE_BITMAP; | |
809 else if (row->truncated_on_left_p) | |
810 left = LEFT_TRUNCATION_BITMAP; | |
811 else if (MATRIX_ROW_CONTINUATION_LINE_P (row)) | |
812 left = CONTINUATION_LINE_BITMAP; | |
813 else if (row->indicate_empty_line_p && empty_pos <= 0) | |
814 left = ZV_LINE_BITMAP; | |
815 else if (row->indicate_top_line_p && arrow_pos <= 0) | |
816 left = UP_ARROW_BITMAP; | |
817 else if (row->indicate_bottom_line_p && arrow_pos < 0) | |
818 left = DOWN_ARROW_BITMAP; | |
819 else | |
820 left = NO_FRINGE_BITMAP; | |
821 | |
822 /* Decide which bitmap to draw in the right fringe. */ | |
823 if (WINDOW_RIGHT_FRINGE_WIDTH (w) == 0) | |
824 right = NO_FRINGE_BITMAP; | |
825 else if (row->right_user_fringe_bitmap != NO_FRINGE_BITMAP) | |
826 { | |
827 right = row->right_user_fringe_bitmap; | |
828 right_face_id = row->right_user_fringe_face_id; | |
829 } | |
830 else if (row->indicate_bob_p && boundary_pos > 0) | |
831 right = ((row->indicate_eob_p && boundary_pos >= 0) | |
832 ? RIGHT_BRACKET_BITMAP : TOP_RIGHT_ANGLE_BITMAP); | |
833 else if (row->indicate_eob_p && boundary_pos >= 0) | |
834 right = BOTTOM_RIGHT_ANGLE_BITMAP; | |
835 else if (row->truncated_on_right_p) | |
836 right = RIGHT_TRUNCATION_BITMAP; | |
837 else if (row->continued_p) | |
838 right = CONTINUED_LINE_BITMAP; | |
839 else if (row->indicate_top_line_p && arrow_pos > 0) | |
840 right = UP_ARROW_BITMAP; | |
841 else if (row->indicate_bottom_line_p && arrow_pos >= 0) | |
842 right = DOWN_ARROW_BITMAP; | |
843 else if (row->indicate_empty_line_p | |
844 && (empty_pos > 0 | |
845 || (WINDOW_LEFT_FRINGE_WIDTH (w) == 0 && empty_pos == 0))) | |
846 right = ZV_LINE_BITMAP; | |
847 else | |
848 right = NO_FRINGE_BITMAP; | |
849 | |
850 if (force_p | |
851 || row->y != cur->y | |
852 || row->visible_height != cur->visible_height | |
853 || left != cur->left_fringe_bitmap | |
854 || right != cur->right_fringe_bitmap | |
855 || left_face_id != cur->left_fringe_face_id | |
856 || right_face_id != cur->right_fringe_face_id | |
857 || cur->redraw_fringe_bitmaps_p) | |
858 { | |
859 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1; | |
860 cur->left_fringe_bitmap = left; | |
861 cur->right_fringe_bitmap = right; | |
862 cur->left_fringe_face_id = left_face_id; | |
863 cur->right_fringe_face_id = right_face_id; | |
864 } | |
865 | |
866 if (row->overlay_arrow_p != cur->overlay_arrow_p) | |
867 { | |
868 redraw_p = row->redraw_fringe_bitmaps_p = cur->redraw_fringe_bitmaps_p = 1; | |
869 cur->overlay_arrow_p = row->overlay_arrow_p; | |
870 } | |
871 | |
872 row->left_fringe_bitmap = left; | |
873 row->right_fringe_bitmap = right; | |
874 row->left_fringe_face_id = left_face_id; | |
875 row->right_fringe_face_id = right_face_id; | |
876 } | |
877 | |
878 return redraw_p; | |
879 } | |
880 | |
881 | |
882 /* Compute actual fringe widths for frame F. | |
883 | |
884 If REDRAW is 1, redraw F if the fringe settings was actually | |
885 modified and F is visible. | |
886 | |
887 Since the combined left and right fringe must occupy an integral | |
888 number of columns, we may need to add some pixels to each fringe. | |
889 Typically, we add an equal amount (+/- 1 pixel) to each fringe, | |
890 but a negative width value is taken literally (after negating it). | |
891 | |
892 We never make the fringes narrower than specified. It is planned | |
893 to make fringe bitmaps customizable and expandable, and at that | |
894 time, the user will typically specify the minimum number of pixels | |
895 needed for his bitmaps, so we shouldn't select anything less than | |
896 what is specified. | |
897 */ | |
898 | |
899 void | |
900 compute_fringe_widths (f, redraw) | |
901 struct frame *f; | |
902 int redraw; | |
903 { | |
904 int o_left = FRAME_LEFT_FRINGE_WIDTH (f); | |
905 int o_right = FRAME_RIGHT_FRINGE_WIDTH (f); | |
906 int o_cols = FRAME_FRINGE_COLS (f); | |
907 | |
908 Lisp_Object left_fringe = Fassq (Qleft_fringe, f->param_alist); | |
909 Lisp_Object right_fringe = Fassq (Qright_fringe, f->param_alist); | |
910 int left_fringe_width, right_fringe_width; | |
911 | |
912 if (!NILP (left_fringe)) | |
913 left_fringe = Fcdr (left_fringe); | |
914 if (!NILP (right_fringe)) | |
915 right_fringe = Fcdr (right_fringe); | |
916 | |
917 left_fringe_width = ((NILP (left_fringe) || !INTEGERP (left_fringe)) ? 8 : | |
918 XINT (left_fringe)); | |
919 right_fringe_width = ((NILP (right_fringe) || !INTEGERP (right_fringe)) ? 8 : | |
920 XINT (right_fringe)); | |
921 | |
922 if (left_fringe_width || right_fringe_width) | |
923 { | |
924 int left_wid = left_fringe_width >= 0 ? left_fringe_width : -left_fringe_width; | |
925 int right_wid = right_fringe_width >= 0 ? right_fringe_width : -right_fringe_width; | |
926 int conf_wid = left_wid + right_wid; | |
927 int font_wid = FRAME_COLUMN_WIDTH (f); | |
928 int cols = (left_wid + right_wid + font_wid-1) / font_wid; | |
929 int real_wid = cols * font_wid; | |
930 if (left_wid && right_wid) | |
931 { | |
932 if (left_fringe_width < 0) | |
933 { | |
934 /* Left fringe width is fixed, adjust right fringe if necessary */ | |
935 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid; | |
936 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid - left_wid; | |
937 } | |
938 else if (right_fringe_width < 0) | |
939 { | |
940 /* Right fringe width is fixed, adjust left fringe if necessary */ | |
941 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid - right_wid; | |
942 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid; | |
943 } | |
944 else | |
945 { | |
946 /* Adjust both fringes with an equal amount. | |
947 Note that we are doing integer arithmetic here, so don't | |
948 lose a pixel if the total width is an odd number. */ | |
949 int fill = real_wid - conf_wid; | |
950 FRAME_LEFT_FRINGE_WIDTH (f) = left_wid + fill/2; | |
951 FRAME_RIGHT_FRINGE_WIDTH (f) = right_wid + fill - fill/2; | |
952 } | |
953 } | |
954 else if (left_fringe_width) | |
955 { | |
956 FRAME_LEFT_FRINGE_WIDTH (f) = real_wid; | |
957 FRAME_RIGHT_FRINGE_WIDTH (f) = 0; | |
958 } | |
959 else | |
960 { | |
961 FRAME_LEFT_FRINGE_WIDTH (f) = 0; | |
962 FRAME_RIGHT_FRINGE_WIDTH (f) = real_wid; | |
963 } | |
964 FRAME_FRINGE_COLS (f) = cols; | |
965 } | |
966 else | |
967 { | |
968 FRAME_LEFT_FRINGE_WIDTH (f) = 0; | |
969 FRAME_RIGHT_FRINGE_WIDTH (f) = 0; | |
970 FRAME_FRINGE_COLS (f) = 0; | |
971 } | |
972 | |
973 if (redraw && FRAME_VISIBLE_P (f)) | |
974 if (o_left != FRAME_LEFT_FRINGE_WIDTH (f) || | |
975 o_right != FRAME_RIGHT_FRINGE_WIDTH (f) || | |
976 o_cols != FRAME_FRINGE_COLS (f)) | |
977 redraw_frame (f); | |
978 } | |
979 | |
980 DEFUN ("destroy-fringe-bitmap", Fdestroy_fringe_bitmap, Sdestroy_fringe_bitmap, | |
981 1, 1, 0, | |
982 doc: /* Destroy fringe bitmap WHICH. | |
983 If WHICH overrides a standard fringe bitmap, the original bitmap is restored. */) | |
984 (which) | |
985 Lisp_Object which; | |
986 { | |
987 int n; | |
988 struct fringe_bitmap **fbp; | |
989 | |
990 CHECK_NUMBER (which); | |
991 if (n = XINT (which), n >= max_used_fringe_bitmap) | |
992 return Qnil; | |
993 | |
994 fringe_faces[n] = FRINGE_FACE_ID; | |
995 | |
996 fbp = &fringe_bitmaps[n]; | |
997 if (*fbp && (*fbp)->dynamic) | |
998 { | |
999 if (rif->destroy_fringe_bitmap) | |
1000 rif->destroy_fringe_bitmap (n); | |
1001 xfree (*fbp); | |
1002 *fbp = NULL; | |
1003 } | |
1004 | |
1005 while (max_used_fringe_bitmap > MAX_STANDARD_FRINGE_BITMAPS | |
1006 && fringe_bitmaps[max_used_fringe_bitmap - 1] == NULL) | |
1007 max_used_fringe_bitmap--; | |
1008 | |
1009 return Qnil; | |
1010 } | |
1011 | |
1012 | |
1013 /* Initialize bitmap bit. | |
1014 On X and MAC, we bit-swap the built-in bitmaps. | |
1015 On W32, there's no need to do this. | |
1016 */ | |
1017 | |
1018 void | |
1019 init_fringe_bitmap (which, fb, once_p) | |
1020 enum fringe_bitmap_type which; | |
1021 struct fringe_bitmap *fb; | |
1022 int once_p; | |
1023 { | |
1024 if (once_p || fb->dynamic) | |
1025 { | |
1026 #if defined (HAVE_X_WINDOWS) || defined (MAC_OS) | |
1027 unsigned char *bits = fb->bits; | |
1028 int j; | |
1029 for (j = 0; j < fb->height; j++) | |
1030 { | |
1031 static unsigned char swap_nibble[16] | |
1032 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */ | |
1033 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */ | |
1034 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */ | |
1035 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */ | |
1036 | |
1037 unsigned char b = *bits; | |
1038 *bits++ = (unsigned short)((swap_nibble[b & 0xf]<<4) | |
1039 | (swap_nibble[(b>>4) & 0xf])); | |
1040 } | |
1041 #endif | |
1042 } | |
1043 | |
1044 if (!once_p) | |
1045 { | |
1046 Fdestroy_fringe_bitmap (make_number (which)); | |
1047 | |
1048 if (rif->define_fringe_bitmap) | |
1049 rif->define_fringe_bitmap (which, fb->bits, fb->height, fb->width); | |
1050 | |
1051 fringe_bitmaps[which] = fb; | |
1052 if (which >= max_used_fringe_bitmap) | |
1053 max_used_fringe_bitmap = which + 1; | |
1054 } | |
1055 } | |
1056 | |
1057 | |
1058 DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap, | |
1059 1, 5, 0, | |
1060 doc: /* Define a fringe bitmap from BITS of height HEIGHT and width WIDTH. | |
1061 BITS is either a string or a vector. If HEIGHT is nil, use number of bytes | |
1062 in BITS. If WIDTH is zero, default to 8. Optional forth arg ALIGN may be | |
1063 one of `top', `center', or `bottom', indicating the positioning of the | |
1064 bitmap relative to the rows where it is used; the default is to center the | |
1065 bitmap. Fourth arg may also be a list (ALIGN PERIODIC) where | |
1066 PERIODIC non-nil specifies that the bitmap should be repeated. | |
1067 Optional fifth argument WHICH is bitmap number to redefine. | |
1068 Return new bitmap number, or nil of no more free bitmap slots. */) | |
1069 (bits, height, width, align, which) | |
1070 Lisp_Object bits, height, width, align, which; | |
1071 { | |
1072 Lisp_Object len; | |
1073 int n, h, i, j; | |
1074 unsigned char *b; | |
1075 struct fringe_bitmap fb, *xfb; | |
1076 int fill1 = 0, fill2 = 0; | |
1077 | |
1078 if (!STRINGP (bits) && !VECTORP (bits)) | |
1079 bits = wrong_type_argument (Qstringp, bits); | |
1080 | |
1081 len = Flength (bits); | |
1082 | |
1083 if (NILP (height)) | |
1084 h = fb.height = XINT (len); | |
1085 else | |
1086 { | |
1087 CHECK_NUMBER (height); | |
1088 fb.height = min (XINT (height), 255); | |
1089 if (fb.height > XINT (len)) | |
1090 { | |
1091 h = XINT (len); | |
1092 fill1 = (fb.height - h) / 2; | |
1093 fill2 = fb.height - h - fill1; | |
1094 } | |
1095 } | |
1096 | |
1097 if (NILP (width)) | |
1098 fb.width = 8; | |
1099 else | |
1100 { | |
1101 CHECK_NUMBER (width); | |
1102 fb.width = min (XINT (width), 255); | |
1103 } | |
1104 | |
1105 fb.period = 0; | |
1106 fb.align = ALIGN_BITMAP_CENTER; | |
1107 | |
1108 if (CONSP (align)) | |
1109 { | |
1110 Lisp_Object period = XCDR (align); | |
1111 if (CONSP (period)) | |
1112 { | |
1113 period = XCAR (period); | |
1114 if (!NILP (period)) | |
1115 { | |
1116 fb.period = fb.height; | |
1117 fb.height = 255; | |
1118 } | |
1119 } | |
1120 align = XCAR (align); | |
1121 } | |
1122 if (EQ (align, Qtop)) | |
1123 fb.align = ALIGN_BITMAP_TOP; | |
1124 else if (EQ (align, Qbottom)) | |
1125 fb.align = ALIGN_BITMAP_BOTTOM; | |
1126 else if (!NILP (align) && !EQ (align, Qcenter)) | |
1127 error ("Bad align argument"); | |
1128 | |
1129 if (NILP (which)) | |
1130 { | |
1131 if (max_used_fringe_bitmap < MAX_FRINGE_BITMAPS) | |
1132 n = make_number (max_used_fringe_bitmap++); | |
1133 else | |
1134 { | |
1135 for (n = MAX_STANDARD_FRINGE_BITMAPS; | |
1136 n < MAX_FRINGE_BITMAPS; | |
1137 n++) | |
1138 if (fringe_bitmaps[n] == NULL) | |
1139 break; | |
1140 if (n == MAX_FRINGE_BITMAPS) | |
1141 return Qnil; | |
1142 } | |
1143 which = make_number (n); | |
1144 } | |
1145 else | |
1146 { | |
1147 CHECK_NUMBER (which); | |
1148 n = XINT (which); | |
1149 if (n <= NO_FRINGE_BITMAP || n >= MAX_FRINGE_BITMAPS) | |
1150 error ("Invalid fringe bitmap number"); | |
1151 } | |
1152 | |
1153 fb.dynamic = 1; | |
1154 | |
1155 xfb = (struct fringe_bitmap *)xmalloc (sizeof fb + fb.height); | |
1156 fb.bits = b = (unsigned char *)(xfb+1); | |
1157 bzero (b, fb.height); | |
1158 | |
1159 j = 0; | |
1160 while (j < fb.height) | |
1161 { | |
1162 for (i = 0; i < fill1 && j < fb.height; i++) | |
1163 b[j++] = 0; | |
1164 for (i = 0; i < h & j < fb.height; i++) | |
1165 { | |
1166 Lisp_Object elt = Faref (bits, make_number (i)); | |
1167 b[j++] = NUMBERP (elt) ? XINT (elt) : 0; | |
1168 } | |
1169 for (i = 0; i < fill2 && j < fb.height; i++) | |
1170 b[j++] = 0; | |
1171 } | |
1172 | |
1173 *xfb = fb; | |
1174 | |
1175 init_fringe_bitmap (n, xfb, 0); | |
1176 | |
1177 return which; | |
1178 } | |
1179 | |
1180 DEFUN ("set-fringe-bitmap-face", Fset_fringe_bitmap_face, Sset_fringe_bitmap_face, | |
1181 1, 2, 0, | |
1182 doc: /* Set face for fringe bitmap FRINGE-ID to FACE. | |
1183 If FACE is nil, reset face to default fringe face. */) | |
1184 (fringe_id, face) | |
1185 Lisp_Object fringe_id, face; | |
1186 { | |
1187 int face_id; | |
1188 | |
1189 CHECK_NUMBER (fringe_id); | |
1190 if (!valid_fringe_bitmap_id_p (XINT (fringe_id))) | |
1191 error ("Invalid fringe id"); | |
1192 | |
1193 if (!NILP (face)) | |
1194 { | |
1195 face_id = lookup_named_face (SELECTED_FRAME (), face, 'A'); | |
1196 if (face_id < 0) | |
1197 error ("No such face"); | |
1198 } | |
1199 else | |
1200 face_id = FRINGE_FACE_ID; | |
1201 | |
1202 fringe_faces [XINT (fringe_id)] = face_id; | |
1203 | |
1204 return Qnil; | |
1205 } | |
1206 | |
1207 DEFUN ("fringe-bitmaps-at-pos", Ffringe_bitmaps_at_pos, Sfringe_bitmaps_at_pos, | |
1208 0, 2, 0, | |
1209 doc: /* Return fringe bitmaps of row containing position POS in window WINDOW. | |
1210 If WINDOW is nil, use selected window. If POS is nil, use value of point | |
1211 in that window. Return value is a cons (LEFT . RIGHT) where LEFT and RIGHT | |
1212 are the fringe bitmap numbers for the bitmaps in the left and right fringe, | |
1213 resp. Return nil if POS is not visible in WINDOW. */) | |
1214 (pos, window) | |
1215 { | |
1216 struct window *w; | |
1217 struct buffer *old_buffer = NULL; | |
1218 struct glyph_row *row; | |
1219 int textpos; | |
1220 | |
1221 if (NILP (window)) | |
1222 window = selected_window; | |
1223 CHECK_WINDOW (window); | |
1224 w = XWINDOW (window); | |
1225 | |
1226 if (!NILP (pos)) | |
1227 { | |
1228 CHECK_NUMBER_COERCE_MARKER (pos); | |
1229 textpos = XINT (pos); | |
1230 } | |
1231 else if (w == XWINDOW (selected_window)) | |
1232 textpos = PT; | |
1233 else | |
1234 textpos = XMARKER (w->pointm)->charpos; | |
1235 | |
1236 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix); | |
1237 row = row_containing_pos (w, textpos, row, NULL, 0); | |
1238 if (row) | |
1239 return Fcons (make_number (row->left_fringe_bitmap), | |
1240 make_number (row->right_fringe_bitmap)); | |
1241 else | |
1242 return Qnil; | |
1243 } | |
1244 | |
1245 | |
1246 /*********************************************************************** | |
1247 Initialization | |
1248 ***********************************************************************/ | |
1249 | |
1250 void | |
1251 syms_of_fringe () | |
1252 { | |
1253 | |
1254 defsubr (&Sdestroy_fringe_bitmap); | |
1255 defsubr (&Sdefine_fringe_bitmap); | |
1256 defsubr (&Sfringe_bitmaps_at_pos); | |
1257 defsubr (&Sset_fringe_bitmap_face); | |
1258 | |
1259 DEFVAR_LISP ("overflow-newline-into-fringe", &Voverflow_newline_into_fringe, | |
1260 doc: /* *Non-nil means that newline may flow into the right fringe. | |
1261 This means that display lines which are exactly as wide as the window | |
1262 (not counting the final newline) will only occupy one screen line, by | |
1263 showing (or hiding) the final newline in the right fringe; when point | |
1264 is at the final newline, the cursor is shown in the right fringe. | |
1265 If nil, also continue lines which are exactly as wide as the window. */); | |
1266 Voverflow_newline_into_fringe = Qt; | |
1267 | |
1268 } | |
1269 | |
1270 /* Initialize this module when Emacs starts. */ | |
1271 | |
1272 void | |
1273 init_fringe_once () | |
1274 { | |
1275 enum fringe_bitmap_type bt; | |
1276 | |
1277 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++) | |
1278 init_fringe_bitmap(bt, &standard_bitmaps[bt], 1); | |
1279 } | |
1280 | |
1281 void | |
1282 init_fringe () | |
1283 { | |
1284 int i; | |
1285 | |
1286 bzero (fringe_bitmaps, sizeof fringe_bitmaps); | |
1287 for (i = 0; i < MAX_FRINGE_BITMAPS; i++) | |
1288 fringe_faces[i] = FRINGE_FACE_ID; | |
1289 } | |
1290 | |
1291 #ifdef HAVE_NTGUI | |
1292 | |
1293 void | |
1294 w32_init_fringe () | |
1295 { | |
1296 enum fringe_bitmap_type bt; | |
1297 | |
1298 for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++) | |
1299 { | |
1300 struct fringe_bitmap *fb = &standard_bitmaps[bt]; | |
1301 rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width); | |
1302 } | |
1303 } | |
1304 | |
1305 void | |
1306 w32_reset_fringes () | |
1307 { | |
1308 /* Destroy row bitmaps. */ | |
1309 int bt; | |
1310 | |
1311 for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++) | |
1312 rif->destroy_fringe_bitmap (bt); | |
1313 } | |
1314 | |
1315 #endif | |
1316 | |
1317 #endif /* HAVE_WINDOW_SYSTEM */ | |
1318 |