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