1 /*
2 * msgs.c
3 *
4 * Support functions for "popup-msgs" mode.
5 * Written by T.E.Dickey for vile (august 1994).
6 *
7 * $Id: msgs.c,v 1.31 2010/09/08 21:11:30 tom Exp $
8 */
9 #include "estruct.h"
10
11 #if OPT_POPUP_MSGS
12
13 #include "edef.h"
14
15 /*
16 * Create the message-buffer if it doesn't already exist
17 */
18 static BUFFER *
create_msgs(void)19 create_msgs(void)
20 {
21 BUFFER *bp = 0;
22
23 if (wheadp != 0) { /* we need windows before creating buffers */
24 bp = bfind(MESSAGES_BufName, BFINVS);
25
26 if (valid_buffer(bp)) {
27 b_set_invisible(bp);
28 bp->b_active = TRUE;
29 }
30 }
31 return bp;
32 }
33
34 /*
35 * This is invoked as a wrapper for 'kbd_putc()'. It writes to the Messages
36 * scratch buffer, and also to the message line. If the Messages buffer isn't
37 * visible, it is automatically popped up when a new message line is begun.
38 * Since it's a scratch buffer, popping it down destroys it.
39 */
40 int
msg_putc(int c)41 msg_putc(int c)
42 {
43 BUFFER *savebp = curbp;
44 WINDOW *savewp = curwp;
45 MARK savemk;
46 int saverow = ttrow;
47 int savecol = ttcol;
48 register BUFFER *bp;
49 register WINDOW *wp;
50
51 if ((bp = create_msgs()) == 0)
52 return TRUE;
53
54 savemk = DOT;
55 beginDisplay();
56 /*
57 * Modify the current-buffer state as unobtrusively as possible (i.e.,
58 * don't modify the buffer order, and don't make the buffer visible if
59 * it isn't already!). To use the 'bputc()' logic, though, we've got
60 * to have a window, even if it's not real.
61 */
62 curbp = bp;
63 if ((wp = bp2any_wp(bp)) == NULL) {
64 static WINDOW dummy;
65 wp = &dummy;
66 wp->w_bufp = bp;
67 }
68 curwp = wp;
69 DOT.l = lback(buf_head(bp));
70 DOT.o = llength(DOT.l);
71
72 /*
73 * Write into the [Messages]-buffer
74 */
75 #if OPT_TRACE
76 if (c == '\n') {
77 static TBUFF *ss;
78 int len = (DOT.o > 0) ? DOT.o : 1;
79 if (tb_init(&ss, EOS) != 0
80 && tb_bappend(&ss,
81 (DOT.o > 0) ? lvalue(DOT.l) : "?",
82 (size_t) len) != 0
83 && tb_append(&ss, EOS) != 0) {
84 TRACE(("msg:%s\n",
85 visible_buff(tb_values(ss),
86 (int) tb_length(ss) - 1, TRUE)));
87 }
88 }
89 #endif
90 if ((c != '\n') || (DOT.o > 0)) {
91 bputc(c);
92 b_clr_changed(bp);
93 }
94
95 /* Finally, restore the original current-buffer and write the character
96 * to the message line.
97 */
98 curbp = savebp;
99 curwp = savewp;
100 if (savewp)
101 DOT = savemk;
102 movecursor(saverow, savecol);
103 if (c != '\n') {
104 if (sgarbf) {
105 mlsavec(c);
106 } else {
107 kbd_putc(c);
108 }
109 }
110 endofDisplay();
111
112 return TRUE;
113 }
114
115 void
popup_msgs(void)116 popup_msgs(void)
117 {
118 BUFFER *savebp = curbp;
119 WINDOW *savewp = curwp;
120 MARK savemk;
121 register BUFFER *bp;
122 WINDOW *wp;
123
124 if ((bp = create_msgs()) == 0)
125 return;
126
127 savemk = DOT;
128 if (!is_empty_buf(bp)) {
129 if ((curwp == 0) || sgarbf || global_g_val(GMDPOPUP_MSGS) == -TRUE) {
130 return; /* CAN'T popup yet */
131 }
132 if (popupbuff(bp) == FALSE) {
133 (void) zotbuf(bp);
134 return;
135 }
136
137 if ((wp = bp2any_wp(bp)) != NULL) {
138 make_local_w_val(wp, WMDNUMBER);
139 set_w_val(wp, WMDNUMBER, FALSE);
140 }
141 set_rdonly(bp, non_filename(), MDVIEW);
142 curbp = savebp;
143 curwp = savewp;
144 if (savewp)
145 DOT = savemk;
146 }
147 }
148
149 /*
150 * If no warning messages were encountered during startup, and the popup-msgs
151 * mode wasn't enabled, discard the informational messages that are there
152 * already.
153 */
154 void
purge_msgs(void)155 purge_msgs(void)
156 {
157 TRACE(("purge_msgs mode:%d, warnings:%d\n",
158 global_g_val(GMDPOPUP_MSGS), warnings));
159
160 if ((global_g_val(GMDPOPUP_MSGS) == -TRUE)
161 && (warnings == 0)) {
162 BUFFER *bp = find_b_name(MESSAGES_BufName);
163 if (valid_buffer(bp)
164 && bp->b_nwnd == 0) {
165 (void) zotbuf(bp);
166 }
167 set_global_g_val(GMDPOPUP_MSGS, FALSE);
168 }
169 }
170 #endif
171