Fixed showing the loading progress when in-game.
[cboard.git] / src / message.c
blobabc855bc247e8ce4112325822815edbc2cc6e5d2
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2002-2011 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdarg.h>
22 #include <string.h>
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #ifdef HAVE_STDARG_H
29 #include <stdarg.h>
30 #endif
32 #ifdef HAVE_CURSES_H
33 #include <curses.h>
34 #endif
36 #ifdef HAVE_PANEL_H
37 #include <panel.h>
38 #endif
40 #ifdef HAVE_LIMITS_H
41 #include <limits.h>
42 #endif
44 #include "chess.h"
45 #include "conf.h"
46 #include "colors.h"
47 #include "misc.h"
48 #include "window.h"
49 #include "message.h"
51 #ifdef WITH_DMALLOC
52 #include <dmalloc.h>
53 #endif
55 static void build_message_lines(const char *title, const char *prompt,
56 int force_trim, const char *extra, int *h, int *w, char ***str,
57 const char *fmt, va_list ap)
59 int i, n, pos;
60 char *line, **lines = NULL;
61 int width = 0, height = 0;
62 char buf[LINE_MAX];
63 char *p;
64 int total = 0;
66 #ifdef HAVE_VASPRINTF
67 vasprintf(&line, fmt, ap);
68 #else
69 line = Malloc(LINE_MAX);
70 vsnprintf(line, LINE_MAX, fmt, ap);
71 #endif
73 /* Get the longest line to dynamically adjust the message box width. */
74 for (i = n = pos = 0; line[i]; i++, n++) {
75 if (line[i] == '\n') {
76 if (n > pos)
77 pos = n;
79 n = 0;
83 pos = (n > pos) ? n : pos;
85 if (pos) {
86 if (pos > MSG_WIDTH)
87 width = MSG_WIDTH;
88 else
89 width = pos;
92 for (i = n = pos = 0; line[i]; i++, n++, pos++) {
93 if (line[i] == '\t')
94 continue;
96 if (line[i] == '\n')
97 pos = 0;
99 if (pos > width) {
100 while (line[--i] != ' ')
101 buf[--n] = ' ';
103 buf[n++] = '\n';
104 pos = 0;
107 buf[n] = line[i];
110 free(line);
112 buf[n] = '\0';
113 p = buf;
114 lines = split_str(p, "\n", &total, &width, force_trim);
116 if (prompt && width < strlen(prompt))
117 width = strlen(prompt);
119 if (extra && width < strlen(extra))
120 width = strlen(extra);
122 if (title && width < strlen(title))
123 width = strlen(title);
125 height = total;
127 if (extra)
128 height++;
130 if (title)
131 height++;
133 height += 4; // 1 padding, 2 box, 1 prompt
134 width += 4; // 2 padding, 2 box
135 *h = height;
136 *w = width;
137 *str = lines;
140 static int display_message(WIN *win)
142 struct message_s *m = win->data;
143 int i;
144 void *p = NULL;
146 keypad(win->w, TRUE);
147 window_draw_title(win->w, win->title, m->w, CP_MESSAGE_TITLE,
148 CP_MESSAGE_BORDER);
150 for (i = 0; m->lines[i]; i++)
151 mvwprintw(win->w, (win->title) ? 2 + i: 1 + i,
152 (m->center || (!i && !m->lines[i+1])) ?
153 CENTERX(m->w, m->lines[i]) : 1, "%s", m->lines[i]);
155 if (m->extra)
156 window_draw_prompt(win->w, (m->prompt) ? m->h - 3 : m->h - 2, m->w,
157 m->extra, CP_MESSAGE_PROMPT);
159 if (m->prompt)
160 window_draw_prompt(win->w, m->h - 2, m->w, m->prompt, CP_MESSAGE_PROMPT);
162 if (m->func && win->c == m->c) {
163 (*m->func)(m->arg);
164 return 1;
167 if (win->c != 0) {
168 for (i = 0; m->lines[i]; i++)
169 free(m->lines[i]);
171 free(m->lines);
173 if (m->prompt)
174 free(m->prompt);
176 if (m->extra)
177 free(m->extra);
179 if (m->arg)
180 p = m->arg;
182 free(m);
183 win->data = p;
184 return 0;
187 return 1;
191 * The force_trim parameter will trim whitespace reguardless if there is more
192 * than one line or not (help text vs. tag viewing).
194 WIN *construct_message(const char *title, const char *prompt, int center,
195 int force_trim, const char *extra_help, message_func *func, void *arg,
196 window_exit_func *efunc, int ckey, int freedata, const char *fmt, ...)
198 char **lines = NULL;
199 va_list ap;
200 struct message_s *m = NULL;
201 WIN *win = NULL;
202 int h, w;
204 va_start(ap, fmt);
205 build_message_lines(title, prompt, force_trim, extra_help, &h, &w, &lines, fmt, ap);
206 va_end(ap);
208 m = Calloc(1, sizeof(struct message_s));
209 m->lines = lines;
210 m->w = w;
211 m->h = h;
212 m->center = center;
213 m->c = ckey;
214 m->func = func;
215 m->arg = arg;
217 if (prompt)
218 m->prompt = strdup(prompt);
220 if (extra_help)
221 m->extra = strdup(extra_help);
223 win = window_create(title, h, w, CALCPOSY(h), CALCPOSX(w), display_message, m,
224 efunc);
226 win->freedata = freedata;
227 wbkgd(win->w, CP_MESSAGE_WINDOW);
228 (*win->func)(win);
229 return win;