comparison mcabber/src/screen.c @ 74:b392112ab995

[/trunk] Changeset 88 by mikael * Switch to using hbuf, the new history buffer implementation. * I've had to rewrite some parts of the interface, and I have removed the frames for the roster and the chat window. * The wrapping is not perfect, as the prefix is not yet treated separately... * Seems to be a display problem when receiving UTF-8, too. :-(
author mikael
date Sat, 16 Apr 2005 16:37:31 +0000
parents a8689087db5c
children ff119bb11563
comparison
equal deleted inserted replaced
73:1fc66b6c08ef 74:b392112ab995
13 #include "buddies.h" 13 #include "buddies.h"
14 #include "parsecfg.h" 14 #include "parsecfg.h"
15 #include "lang.h" 15 #include "lang.h"
16 #include "list.h" 16 #include "list.h"
17 #include "utf8.h" 17 #include "utf8.h"
18 #include "hbuf.h"
18 19
19 #define window_entry(n) list_entry(n, window_entry_t, list) 20 #define window_entry(n) list_entry(n, window_entry_t, list)
20 21
21 LIST_HEAD(window_list); 22 LIST_HEAD(window_list);
22 23
23 typedef struct _window_entry_t { 24 typedef struct _window_entry_t {
24 WINDOW *win; 25 WINDOW *win;
25 PANEL *panel; 26 PANEL *panel;
26 char *name; 27 char *name;
27 int nlines; 28 GList *hbuf;
28 char **texto;
29 int hidden_msg; 29 int hidden_msg;
30 struct list_head list; 30 struct list_head list;
31 } window_entry_t; 31 } window_entry_t;
32 32
33 33
47 static short int inputline_offset; 47 static short int inputline_offset;
48 48
49 49
50 /* Funciones */ 50 /* Funciones */
51 51
52 int scr_WindowHeight(WINDOW * win) 52 int scr_WindowWidth(WINDOW * win)
53 { 53 {
54 int x, y; 54 int x, y;
55 getmaxyx(win, y, x); 55 getmaxyx(win, y, x);
56 return x; 56 return x;
57 }
58
59 void scr_clear_box(WINDOW *win, int y, int x, int height, int width, int Color)
60 {
61 int i, j;
62
63 wattrset(win, COLOR_PAIR(Color));
64 for (i = 0; i < height; i++) {
65 wmove(win, y + i, x);
66 for (j = 0; j < width; j++)
67 wprintw(win, " ");
68 }
57 } 69 }
58 70
59 void scr_draw_box(WINDOW * win, int y, int x, int height, int width, 71 void scr_draw_box(WINDOW * win, int y, int x, int height, int width,
60 int Color, chtype box, chtype border) 72 int Color, chtype box, chtype border)
61 { 73 {
172 tmp->win = newwin(lines, cols, y, x); 184 tmp->win = newwin(lines, cols, y, x);
173 tmp->panel = new_panel(tmp->win); 185 tmp->panel = new_panel(tmp->win);
174 tmp->name = (char *) calloc(1, 1024); 186 tmp->name = (char *) calloc(1, 1024);
175 strncpy(tmp->name, title, 1024); 187 strncpy(tmp->name, title, 1024);
176 188
177 scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0); 189 //scr_draw_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL, 0, 0);
190 scr_clear_box(tmp->win, 0, 0, lines, cols, COLOR_GENERAL);
178 //mvwprintw(tmp->win, 0, (cols - (2 + strlen(title))) / 2, " %s ", title); 191 //mvwprintw(tmp->win, 0, (cols - (2 + strlen(title))) / 2, " %s ", title);
179 if ((!dont_show)) { 192 if ((!dont_show)) {
180 currentWindow = tmp; 193 currentWindow = tmp;
181 } else { 194 } else {
182 if (currentWindow) 195 if (currentWindow)
209 } 222 }
210 } 223 }
211 return NULL; 224 return NULL;
212 } 225 }
213 226
227 void scr_UpdateWindow(window_entry_t *win_entry)
228 {
229 int n;
230 int width;
231 char **lines;
232 GList *hbuf_head;
233
234 // We will show the last CHAT_WIN_HEIGHT lines.
235 // Let's find out where it begins.
236 win_entry->hbuf = g_list_last(win_entry->hbuf);
237 hbuf_head = win_entry->hbuf;
238 for (n=0; hbuf_head && n<(CHAT_WIN_HEIGHT-1) && g_list_previous(hbuf_head); n++)
239 hbuf_head = g_list_previous(hbuf_head);
240
241 // Get the last CHAT_WIN_HEIGHT lines.
242 lines = hbuf_get_lines(hbuf_head, CHAT_WIN_HEIGHT);
243
244 // Display these lines
245 width = scr_WindowWidth(win_entry->win);
246 wmove(win_entry->win, 0, 0);
247 for (n = 0; n < CHAT_WIN_HEIGHT; n++) {
248 int r = width;
249 if (*(lines+n)) {
250 wprintw(win_entry->win, "%s", *(lines+n));
251 r -= strlen(*(lines+n));
252 }// else
253 // wmove(win_entry->win, n, 0);
254 for ( ; r>0 ; r--) {
255 wprintw(win_entry->win, " ");
256 }
257 //// wclrtoeol(win_entry->win); does not work :(
258 }
259 g_free(lines);
260 }
261
214 void scr_ShowWindow(const char *winId) 262 void scr_ShowWindow(const char *winId)
215 { 263 {
216 int n, width, i; 264 window_entry_t *win_entry = scr_SearchWindow(winId);
217 window_entry_t *tmp = scr_SearchWindow(winId); 265
218 if (tmp != NULL) { 266 if (win_entry != NULL) {
219 top_panel(tmp->panel); 267 top_panel(win_entry->panel);
220 currentWindow = tmp; 268 currentWindow = win_entry;
221 chatmode = TRUE; 269 chatmode = TRUE;
222 tmp->hidden_msg = FALSE; 270 win_entry->hidden_msg = FALSE;
223 update_roster = TRUE; 271 update_roster = TRUE;
224 width = scr_WindowHeight(tmp->win); 272
225 for (n = 0; n < tmp->nlines; n++) { 273 // Refresh the window entry
226 mvwprintw(tmp->win, n + 1, 1, ""); 274 scr_UpdateWindow(win_entry);
227 for (i = 0; i < width - 2; i++) 275
228 waddch(tmp->win, ' '); 276 // Finished :)
229 mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]);
230 }
231 //move(CHAT_WIN_HEIGHT - 1, maxX - 1);
232 update_panels(); 277 update_panels();
233 doupdate(); 278 doupdate();
234 } else { 279 } else {
235 top_panel(chatPanel); 280 top_panel(chatPanel);
236 currentWindow = tmp; 281 currentWindow = win_entry; // == NULL (current window empty)
237 } 282 }
238 } 283 }
239 284
240 void scr_ShowBuddyWindow(void) 285 void scr_ShowBuddyWindow(void)
241 { 286 {
244 scr_ShowWindow(tmp->jid); 289 scr_ShowWindow(tmp->jid);
245 top_panel(inputPanel); 290 top_panel(inputPanel);
246 } 291 }
247 292
248 293
249 void scr_WriteInWindow(const char *winId, char *texto, int TimeStamp, int force_show) 294 void scr_WriteInWindow(const char *winId, char *text, int TimeStamp,
250 { 295 int force_show)
251 time_t ahora; 296 {
252 int n; 297 char *line;
253 int i; 298 window_entry_t *win_entry;
254 int width;
255 window_entry_t *tmp;
256 int dont_show = FALSE; 299 int dont_show = FALSE;
257 300
258 tmp = scr_SearchWindow(winId); 301 line = calloc(1, strlen(text)+16);
259 302
303 // Prepare line (timestamp + text)
304 // FIXME: actually timestamp and text should not be merged, there is a prefix
305 // field in the hbuf_block structure just for that.
306 if (TimeStamp) {
307 time_t now = time(NULL);
308 strftime(line, 12, "[%H:%M] ", localtime(&now));
309 } else {
310 strcpy(line, " ");
311 }
312 strcat(line, text);
313
314 // Look for the window entry.
315 win_entry = scr_SearchWindow(winId);
316
317 // Do we have to really show the window?
260 if (!chatmode) 318 if (!chatmode)
261 dont_show = TRUE; 319 dont_show = TRUE;
262 else if ((!force_show) && ((!currentWindow || (currentWindow != tmp)))) 320 else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry))))
263 dont_show = TRUE; 321 dont_show = TRUE;
264 322
265 if (tmp == NULL) { 323 // If the window entry doesn't exist yet, let's create it.
266 tmp = scr_CreatePanel(winId, ROSTER_WEIGHT, 0, CHAT_WIN_HEIGHT, 324 if (win_entry == NULL) {
267 maxX - ROSTER_WEIGHT, dont_show); 325 win_entry = scr_CreatePanel(winId, ROSTER_WIDTH, 0, CHAT_WIN_HEIGHT,
268 tmp->texto = (char **) calloc((CHAT_WIN_HEIGHT+1) * 3, sizeof(char *)); 326 maxX - ROSTER_WIDTH, dont_show);
269 for (n = 0; n < CHAT_WIN_HEIGHT * 3; n++) 327 }
270 tmp->texto[n] = (char *) calloc(1, 1024); 328
271 329 hbuf_add_line(&win_entry->hbuf, line,
272 if (TimeStamp) { 330 maxX - scr_WindowWidth(rosterWnd) - 14);
273 ahora = time(NULL); 331 free(line);
274 strftime(tmp->texto[tmp->nlines], 1024, "[%H:%M] ",
275 localtime(&ahora));
276 strcat(tmp->texto[tmp->nlines], texto);
277 } else {
278 sprintf(tmp->texto[tmp->nlines], " %s", texto);
279 }
280 tmp->nlines++;
281 } else {
282 if (tmp->nlines < CHAT_WIN_HEIGHT - 2) {
283 if (TimeStamp) {
284 ahora = time(NULL);
285 strftime(tmp->texto[tmp->nlines], 1024,
286 "[%H:%M] ", localtime(&ahora));
287 strcat(tmp->texto[tmp->nlines], texto);
288 } else {
289 sprintf(tmp->texto[tmp->nlines], " %s", texto);
290 }
291 tmp->nlines++;
292 } else {
293 for (n = 0; n < tmp->nlines; n++) {
294 memset(tmp->texto[n], 0, 1024);
295 strncpy(tmp->texto[n], tmp->texto[n + 1], 1024);
296 }
297 if (TimeStamp) {
298 ahora = time(NULL);
299 strftime(tmp->texto[tmp->nlines - 1], 1024,
300 "[%H:%M] ", localtime(&ahora));
301 strcat(tmp->texto[tmp->nlines - 1], texto);
302 } else {
303 sprintf(tmp->texto[tmp->nlines - 1], " %s", texto);
304 }
305 }
306 }
307 332
308 if (!dont_show) { 333 if (!dont_show) {
309 top_panel(tmp->panel); 334 // Show and refresh the window
310 width = scr_WindowHeight(tmp->win); 335 top_panel(win_entry->panel);
311 for (n = 0; n < tmp->nlines; n++) { 336 scr_UpdateWindow(win_entry);
312 mvwprintw(tmp->win, n + 1, 1, "");
313 for (i = 0; i < width - 2; i++)
314 waddch(tmp->win, ' ');
315 mvwprintw(tmp->win, n + 1, 1, "%s", tmp->texto[n]);
316 }
317
318 update_panels(); 337 update_panels();
319 doupdate(); 338 doupdate();
320 } else { 339 } else {
321 tmp->hidden_msg = TRUE; 340 win_entry->hidden_msg = TRUE;
322 update_roster = TRUE; 341 update_roster = TRUE;
323 } 342 }
324 } 343 }
325 344
326 void scr_InitCurses(void) 345 void scr_InitCurses(void)
343 return; 362 return;
344 } 363 }
345 364
346 void scr_DrawMainWindow(void) 365 void scr_DrawMainWindow(void)
347 { 366 {
367 int l;
368
348 /* Draw main panels */ 369 /* Draw main panels */
349 rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WEIGHT, 0, 0); 370 rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WIDTH, 0, 0);
350 rosterPanel = new_panel(rosterWnd); 371 rosterPanel = new_panel(rosterWnd);
351 scr_draw_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WEIGHT, 372 scr_clear_box(rosterWnd, 0, 0, CHAT_WIN_HEIGHT, ROSTER_WIDTH,
352 COLOR_GENERAL, 0, 0); 373 COLOR_GENERAL);
353 mvwprintw(rosterWnd, 0, (ROSTER_WEIGHT - strlen(i18n("Roster"))) / 2, 374 for (l=0 ; l < CHAT_WIN_HEIGHT ; l++)
354 i18n("Roster")); 375 mvwaddch(rosterWnd, l, ROSTER_WIDTH-1, ACS_VLINE);
355 376
356 chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT, 0, ROSTER_WEIGHT); 377 chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH, 0, ROSTER_WIDTH);
357 chatPanel = new_panel(chatWnd); 378 chatPanel = new_panel(chatWnd);
358 scr_draw_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WEIGHT, 379 scr_clear_box(chatWnd, 0, 0, CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH,
359 COLOR_GENERAL, 0, 0); 380 COLOR_GENERAL);
360 mvwprintw(chatWnd, 1, 1, "This is the status window"); 381 scrollok(chatWnd, TRUE);
382 mvwprintw(chatWnd, 0, 0, "This is the status window");
361 383
362 logWnd_border = newwin(LOG_WIN_HEIGHT, maxX, CHAT_WIN_HEIGHT, 0); 384 logWnd_border = newwin(LOG_WIN_HEIGHT, maxX, CHAT_WIN_HEIGHT, 0);
363 logPanel_border = new_panel(logWnd_border); 385 logPanel_border = new_panel(logWnd_border);
364 scr_draw_box(logWnd_border, 0, 0, LOG_WIN_HEIGHT, maxX, COLOR_GENERAL, 0, 0); 386 scr_draw_box(logWnd_border, 0, 0, LOG_WIN_HEIGHT, maxX, COLOR_GENERAL, 0, 0);
365 logWnd = derwin(logWnd_border, LOG_WIN_HEIGHT-2, maxX-2, 1, 1); 387 logWnd = derwin(logWnd_border, LOG_WIN_HEIGHT-2, maxX-2, 1, 1);
366 logPanel = new_panel(logWnd); 388 logPanel = new_panel(logWnd);
367 wbkgd(logWnd, COLOR_PAIR(COLOR_GENERAL)); 389 wbkgd(logWnd, COLOR_PAIR(COLOR_GENERAL));
368 390
369 scrollok(logWnd,TRUE); 391 scrollok(logWnd, TRUE);
370 392
371 inputWnd = newwin(1, maxX, maxY-1, 0); 393 inputWnd = newwin(1, maxX, maxY-1, 0);
372 inputPanel = new_panel(inputWnd); 394 inputPanel = new_panel(inputWnd);
373 395
374 bud_DrawRoster(rosterWnd); 396 bud_DrawRoster(rosterWnd);
383 refresh(); 405 refresh();
384 endwin(); 406 endwin();
385 return; 407 return;
386 } 408 }
387 409
410 // XXX This function is almost useless now. Once we handle properly
411 // the prefix in scr_WriteInWindow(), we can remove it...
388 void scr_WriteMessage(const char *jid, const char *text, char *prefix) 412 void scr_WriteMessage(const char *jid, const char *text, char *prefix)
389 { 413 {
390 char **submsgs; 414 char *buffer = (char *) malloc(strlen(prefix) + strlen(text) + 1);
391 int n, i;
392 char *buffer = (char *) malloc(strlen(text) + strlen(text));
393 415
394 if (prefix) 416 if (prefix)
395 strcpy(buffer, prefix); 417 strcpy(buffer, prefix);
396 else 418 else
397 *buffer = 0; 419 *buffer = 0;
398 420
399 strcat(buffer, text); 421 strcat(buffer, text);
400 422
401 submsgs = 423 scr_WriteInWindow(jid, buffer, TRUE, FALSE);
402 ut_SplitMessage(buffer, &n, maxX - scr_WindowHeight(rosterWnd) - 14); 424
403
404 for (i = 0; i < n; i++) {
405 if (i == 0)
406 scr_WriteInWindow(jid, submsgs[i], TRUE, FALSE);
407 else
408 scr_WriteInWindow(jid, submsgs[i], FALSE, FALSE);
409 }
410
411 for (i = 0; i < n; i++)
412 free(submsgs[i]);
413 free(submsgs);
414 free(buffer); 425 free(buffer);
415 } 426 }
416 427
417 void scr_WriteIncomingMessage(const char *jidfrom, const char *text) 428 void scr_WriteIncomingMessage(const char *jidfrom, const char *text)
418 { 429 {
419 char *buffer = utf8_decode(text); 430 char *buffer = utf8_decode(text);
431 // FIXME expand tabs...
420 scr_WriteMessage(jidfrom, buffer, "<== "); 432 scr_WriteMessage(jidfrom, buffer, "<== ");
421 free(buffer); 433 free(buffer);
422 top_panel(inputPanel); 434 top_panel(inputPanel);
423 update_panels(); 435 update_panels();
424 doupdate(); 436 doupdate();