summaryrefslogtreecommitdiff
path: root/vchat-ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'vchat-ui.c')
-rw-r--r--[-rwxr-xr-x]vchat-ui.c1984
1 files changed, 1060 insertions, 924 deletions
diff --git a/vchat-ui.c b/vchat-ui.c
index 82a6840..185cad0 100755..100644
--- a/vchat-ui.c
+++ b/vchat-ui.c
@@ -10,116 +10,124 @@
10 * without even the implied warranty of merchantability or fitness for a 10 * without even the implied warranty of merchantability or fitness for a
11 * particular purpose. In no event shall the copyright holder be liable for 11 * particular purpose. In no event shall the copyright holder be liable for
12 * any direct, indirect, incidental or special damages arising in any way out 12 * any direct, indirect, incidental or special damages arising in any way out
13 * of the use of this software. 13 * of the use of this software.
14 * 14 *
15 */ 15 */
16 16
17/* general includes */ 17/* general includes */
18#include <unistd.h> 18#include <errno.h>
19#include <stdint.h>
20#include <ncurses.h> 19#include <ncurses.h>
20#include <readline/history.h>
21#include <readline/readline.h>
22#include <regex.h>
21#include <signal.h> 23#include <signal.h>
24#include <stdint.h>
22#include <stdlib.h> 25#include <stdlib.h>
26#include <string.h>
23#include <strings.h> 27#include <strings.h>
24#include <errno.h>
25#include <termios.h>
26#include <sys/ioctl.h> 28#include <sys/ioctl.h>
29#include <termios.h>
27#include <time.h> 30#include <time.h>
28#include <string.h> 31#include <unistd.h>
29#include <readline/readline.h>
30#include <readline/history.h>
31#include <regex.h>
32#include <wchar.h> 32#include <wchar.h>
33 33
34#include "vchat.h"
35#include "vchat-user.h" 34#include "vchat-user.h"
35#include "vchat.h"
36 36
37/* version of this module */ 37/* version of this module */
38const char *vchat_ui_version = "vchat-ui.c $Id$"; 38const char *vchat_ui_version =
39 "vchat-ui.c $Id$";
39 40
40/* externally used variables */ 41/* externally used variables */
41/* current string in topic window */ 42/* current string in topic window */
42char topicstr[TOPICSTRSIZE] = "[] VChat 0.19"; 43char topicstr[TOPICSTRSIZE] = "[] VChat 0.20";
43/* current string in console window */ 44/* current string in console window */
44char consolestr[CONSOLESTRSIZE] = "[ Get help: .h for server /h for client commands"; 45char consolestr[CONSOLESTRSIZE] =
46 "[ Get help: .h for server /h for client commands";
45 47
46static unsigned int ui_init = 0; 48static unsigned int ui_init = 0;
47 49
48/* our windows */ 50/* our windows */
49static WINDOW *console = NULL; 51static WINDOW *console = NULL;
50static WINDOW *input = NULL; 52static WINDOW *input = NULL;
51static WINDOW *topic = NULL; 53static WINDOW *topic = NULL;
52static WINDOW *channel = NULL; 54static WINDOW *channel = NULL;
53static WINDOW *private = NULL; 55static WINDOW *private = NULL;
54static WINDOW *output = NULL; 56static WINDOW *output = NULL;
55 57
56/* our screen dimensions */ 58/* our screen dimensions */
57static int screensx = 0; 59static int screensx = 0;
58static int screensy = 0; 60static int screensy = 0;
59/* current horizontal scrolling offset for input line */ 61/* current horizontal scrolling offset for input line */
60static int scroff = 0; 62static int scroff = 0;
61/* cache for stepping value of horizontal scrolling */ 63/* cache for stepping value of horizontal scrolling */
62unsigned int hscroll = 0; 64unsigned int hscroll = 0;
63 65
64static int outputshown = 0; 66static int outputshown = 0;
65static int outputwidth_desired = 0; 67static int outputwidth_desired = 0;
66 68
67static int privheight = 0; 69static int privheight = 0;
68static int privheight_desired = 0; 70static int privheight_desired = 0;
69static int privwinhidden = 0; 71static int privwinhidden = 0;
70int usetime = 1; 72int usetime = 1;
71int outputcountdown = 0; 73int outputcountdown = 0;
72char *querypartner = NULL; 74char *querypartner = NULL;
73 75
74struct sb_entry { 76struct sb_entry {
75 int id; 77 int id;
76 time_t when; 78 time_t when;
77 int stamp; 79 int stamp;
78 char *what; 80 char *what;
79 struct sb_entry *link; 81 struct sb_entry *link;
80}; 82};
81 83
82struct sb_data { 84struct sb_data {
83 struct sb_entry *entries; 85 struct sb_entry *entries;
84 struct sb_entry *last; 86 struct sb_entry *last;
85 int count; 87 int count;
86 int scroll; 88 int scroll;
87}; 89};
88 90
89static struct sb_data *sb_pub = NULL; 91static struct sb_data *sb_pub = NULL;
90static struct sb_data *sb_priv = NULL; 92static struct sb_data *sb_priv = NULL;
91static struct sb_data *sb_out = NULL; 93static struct sb_data *sb_out = NULL;
94static struct sb_data *sb_connect = NULL;
92 95
93/* Tells, which window is active */ 96/* Tells, which window is active */
94static int sb_win = 0; /* 0 for pub, 1 for priv */ 97static int sb_win = 0; /* 0 for pub, 1 for priv */
95 98
96/* struct to keep filter list */ 99/* struct to keep filter list */
97struct filt { 100struct filt {
98 char colour; 101 char colour;
99 unsigned int id; 102 unsigned int id;
100 char *text; 103 char *text;
101 regex_t regex; 104 regex_t regex;
102 struct filt *next; 105 struct filt *next;
103}; 106};
104 107
105typedef struct filt filt; 108typedef struct filt filt;
106 109
107static filt *filterlist = NULL; 110static filt *filterlist = NULL;
108static int filtertype = 0; 111static int filtertype = 0;
109static int currentstamp = 0; 112static int currentstamp = 0;
110 113
111/* Prototype declarations */ 114/* Prototype declarations */
112 115
113static void resize (int); 116static void resize(int);
114static void forceredraw (void); 117static void forceredraw(void);
115static void forceredraw_wrapper (int a) {forceredraw();} 118static void forceredraw_wrapper(int a) {
116static void drawwin (WINDOW *win, struct sb_data *sb); 119 (void)a;
117static int writescr (WINDOW *win, struct sb_entry *entry); 120 forceredraw();
118static int testfilter ( struct sb_entry *entry); 121}
119static int gettextwidth (const char *textbuffer); 122static void drawwin(WINDOW *win, struct sb_data *sb);
120static void resize_output (void); 123static int writescr(WINDOW *win, struct sb_entry *entry);
121static int getsbeheight (struct sb_entry *entry, const int xwidth, int needstime ); 124static int testfilter(struct sb_entry *entry);
122static int getsbdataheight (struct sb_data *data, const int xwidth, int needstime ); 125static int gettextwidth(const char *textbuffer);
126static void resize_output(void);
127static int getsbeheight(struct sb_entry *entry, const int xwidth,
128 int needstime);
129static int getsbdataheight(struct sb_data *data, const int xwidth,
130 int needstime);
123/* CURRENTLY UNUSED 131/* CURRENTLY UNUSED
124static void writecolorized (WINDOW *win, char *string); 132static void writecolorized (WINDOW *win, char *string);
125*/ 133*/
@@ -132,22 +140,29 @@ enum {
132}; 140};
133 141
134/* */ 142/* */
135static void 143static void togglequery() {
136togglequery() { 144 if (querypartner && private) {
137 if( querypartner && private ) { 145 {
138 { struct sb_data *tmp = sb_pub; sb_pub = sb_priv; sb_priv = tmp; } 146 struct sb_data *tmp = sb_pub;
139 { WINDOW *tmp= private; private = channel; channel = tmp; } 147 sb_pub = sb_priv;
148 sb_priv = tmp;
149 }
150 {
151 WINDOW *tmp = private;
152 private
153 = channel;
154 channel = tmp;
155 }
140 } 156 }
141} 157}
142 158
143const char * skip_to_character( const char * string, size_t offset ) { 159const char *skip_to_character(const char *string, size_t offset) {
144 size_t ch_size; 160 size_t ch_size;
145 mbstate_t mbs; 161 mbstate_t mbs;
146 memset(&mbs, 0, sizeof(mbs)); 162 memset(&mbs, 0, sizeof(mbs));
147 163
148 while( offset-- > 0 ) { 164 while (offset-- > 0) {
149 switch( ch_size = mbrlen( string, MB_CUR_MAX, &mbs ) ) 165 switch (ch_size = mbrlen(string, MB_CUR_MAX, &mbs)) {
150 {
151 case (size_t)-1: 166 case (size_t)-1:
152 case (size_t)-2: 167 case (size_t)-2:
153 return NULL; 168 return NULL;
@@ -161,15 +176,14 @@ const char * skip_to_character( const char * string, size_t offset ) {
161 return string; 176 return string;
162} 177}
163 178
164size_t offset_to_character( const char * string, size_t offset ) { 179size_t offset_to_character(const char *string, size_t offset) {
165 mbstate_t mbs; 180 mbstate_t mbs;
166 memset(&mbs, 0, sizeof(mbs)); 181 memset(&mbs, 0, sizeof(mbs));
167 const char * string_offset = string + offset; 182 const char *string_offset = string + offset;
168 size_t ch_size, nchars = 0; 183 size_t ch_size, nchars = 0;
169 184
170 while( string < string_offset ) { 185 while (string < string_offset) {
171 switch( ch_size = mbrlen( string, MB_CUR_MAX, &mbs ) ) 186 switch (ch_size = mbrlen(string, MB_CUR_MAX, &mbs)) {
172 {
173 case (size_t)-1: 187 case (size_t)-1:
174 case (size_t)-2: 188 case (size_t)-2:
175 return -1; 189 return -1;
@@ -184,191 +198,195 @@ size_t offset_to_character( const char * string, size_t offset ) {
184} 198}
185 199
186/* readlines callback when a line is completed */ 200/* readlines callback when a line is completed */
187static void 201static void linecomplete(char *line) {
188linecomplete (char *line)
189{
190 char *c; 202 char *c;
191 int i; 203 int i;
192 204
193 /* send linefeed, return pointer, reset cursors */ 205 /* send linefeed, return pointer, reset cursors */
194 waddch (input, '\n'); 206 waddch(input, '\n');
195 wmove (input, 0, 0); 207 wmove(input, 0, 0);
196 scroff = 0; 208 scroff = 0;
197 209
198 if (line) { 210 if (line) {
199 i = strlen(line) - 1; 211 i = strlen(line) - 1;
200 while (line[i] == ' ') line[i--]='\0'; 212 while (line[i] == ' ')
213 line[i--] = '\0';
201 214
202 if (line[0] && strchr(line,' ') == NULL && line[i] == ':') 215 if (line[0] && strchr(line, ' ') == NULL && line[i] == ':')
203 line[i--] = '\0'; 216 line[i--] = '\0';
204 217
205 /* empty line? nada. */ 218 /* empty line? nada. */
206 if (line[0]) { 219 if (line[0]) {
207 /* add line to history and have it handled in vchat-protocol.c */ 220 /* add line to history and have it handled in vchat-protocol.c */
208 add_history (line); 221 add_history(line);
209 handleline (line); 222 handleline(line);
210 } 223 }
211 free (line); 224 free(line);
212 rl_reset_line_state(); 225 rl_reset_line_state();
213 rl_point = rl_end = rl_done = 0; 226 rl_point = rl_end = rl_done = 0;
214 227
215 /* If in query mode, feed query prefix */ 228 /* If in query mode, feed query prefix */
216 if (( c = querypartner )) 229 if ((c = querypartner))
217 while( *c ) rl_stuff_char( *c++ ); 230 while (*c)
231 rl_stuff_char(*c++);
218 232
219 /* wipe input line and reset cursor */ 233 /* wipe input line and reset cursor */
220 wrefresh (input); 234 wrefresh(input);
221 } 235 }
222} 236}
223 237
224/* redraw-callback for readline */ 238/* redraw-callback for readline */
225static void 239static void vciredraw(void) {
226vciredraw (void)
227{
228 int i; 240 int i;
229 size_t readline_point; 241 size_t readline_point;
230 242
231 /* readline offers us information we don't need 243 /* readline offers us information we don't need
232 so ignore outabound cursor positions */ 244 so ignore outabound cursor positions */
233 if( rl_point < 0 ) rl_point = 0; 245 if (rl_point < 0)
234 //if( rl_point > rl_end ) rl_point = rl_end; 246 rl_point = 0;
247 // if( rl_point > rl_end ) rl_point = rl_end;
235 248
236 readline_point = offset_to_character( rl_line_buffer, rl_point ); 249 readline_point = offset_to_character(rl_line_buffer, rl_point);
237 250
238 /* hscroll value cache set up? */ 251 /* hscroll value cache set up? */
239 if (!hscroll) { 252 if (!hscroll) {
240 /* check config-option or set hardcoded default */ 253 /* check config-option or set hardcoded default */
241 hscroll = getintoption (CF_HSCROLL); 254 hscroll = getintoption(CF_HSCROLL);
242 if (!hscroll) 255 if (!hscroll)
243 hscroll = 15; 256 hscroll = 15;
244 } 257 }
245 258
246 /* calculate horizontal scrolling offset */ 259 /* calculate horizontal scrolling offset */
247 260
248 /* Case 1: readline is left of current scroll offset: Adjust to left to reveal more text */ 261 /* Case 1: readline is left of current scroll offset: Adjust to left to reveal
249 if( readline_point < scroff ) 262 * more text */
263 if (readline_point < scroff)
250 scroff = readline_point - hscroll; 264 scroff = readline_point - hscroll;
251 if( scroff < 1 ) 265 if (scroff < 1)
252 scroff = 0; 266 scroff = 0;
253 267
254 /* Case 2: readline just hit the last char on the line: Adjust to right to leave more space on screen */ 268 /* Case 2: readline just hit the last char on the line: Adjust to right to
255 if( readline_point >= scroff + getmaxx(input) - 1 ) 269 * leave more space on screen */
270 if (readline_point >= scroff + getmaxx(input) - 1)
256 scroff = readline_point - getmaxx(input) + hscroll; 271 scroff = readline_point - getmaxx(input) + hscroll;
257 272
258 /* wipe input line */ 273 /* wipe input line */
259 wmove (input, 0, 0); 274 wmove(input, 0, 0);
260 for (i = 0; i < getmaxx(input) - 1; i++) 275 for (i = 0; i < getmaxx(input) - 1; i++)
261 waddch (input, ' '); 276 waddch(input, ' ');
262 277
263 /* show current line, move cursor, redraw! */ 278 /* show current line, move cursor, redraw! */
264 const char *start_line = skip_to_character( rl_line_buffer, scroff ); 279 const char *start_line = skip_to_character(rl_line_buffer, scroff);
265 const char *end_line = skip_to_character( start_line, getmaxx(input) - 1 ); 280 const char *end_line = skip_to_character(start_line, getmaxx(input) - 1);
266
267 mvwaddnstr (input, 0, 0, start_line, end_line - start_line );
268 wmove (input, 0, readline_point - scroff );
269 wrefresh (input);
270 281
282 mvwaddnstr(input, 0, 0, start_line, end_line - start_line);
283 wmove(input, 0, readline_point - scroff);
284 wrefresh(input);
271} 285}
272 286
273/* called by the eventloop in vchat-client.c */ 287/* called by the eventloop in vchat-client.c */
274void 288void userinput(void) {
275userinput (void)
276{
277 /* let readline handle what the user typed .. */ 289 /* let readline handle what the user typed .. */
278 rl_callback_read_char (); 290 rl_callback_read_char();
279} 291}
280 292
281static int 293static int calcdrawcus(char *const str) {
282calcdrawcus (char * const str) {
283 char *tmp = str; 294 char *tmp = str;
284 int zero = 0; 295 int zero = 0;
285 while( *tmp && (*tmp!=' ') && (*tmp!='\n')) { if(*tmp==1) zero+=2; tmp++; } 296 while (*tmp && (*tmp != ' ') && (*tmp != '\n')) {
297 if (*tmp == 1)
298 zero += 2;
299 tmp++;
300 }
286 return (tmp - str) - zero; 301 return (tmp - str) - zero;
287} 302}
288 303
289static void 304static void sb_flush(struct sb_data *sb) {
290sb_flush ( struct sb_data *sb ) {
291 struct sb_entry *now = sb->entries, *prev = NULL, *tmp; 305 struct sb_entry *now = sb->entries, *prev = NULL, *tmp;
292 while( now ) { 306 while (now) {
293 tmp = (struct sb_entry*)((unsigned long)prev ^ (unsigned long)now->link); 307 tmp = (struct sb_entry *)((unsigned long)prev ^ (unsigned long)now->link);
294 free(now->what ); 308 free(now->what);
295 free(now); 309 free(now);
296 prev = now; 310 prev = now;
297 now = tmp; 311 now = tmp;
298 } 312 }
299 sb->entries = NULL; 313 sb->entries = NULL;
314 sb->last = NULL;
315 sb->count = 0;
316 sb->scroll = 0;
300} 317}
301 318
302/*static void 319/*
303sb_clear ( struct sb_data **sb ) { 320static void sb_clear ( struct sb_data **sb ) {
304 sb_flush(*sb); 321 sb_flush(*sb);
305 free( *sb ); 322 free( *sb );
306 *sb = NULL; 323 *sb = NULL;
307}*/ 324}
308 325*/
309static struct sb_entry* 326
310sb_add (struct sb_data *sb, const char *line, time_t when) { 327static struct sb_entry *sb_add(struct sb_data *sb, const char *line,
311 struct sb_entry *newone = malloc (sizeof(struct sb_entry)); 328 time_t when) {
312 if( newone ) { 329 struct sb_entry *newone = malloc(sizeof(struct sb_entry));
313 if( sb->count == sb->scroll ) sb->scroll++; 330 if (newone) {
314 newone->id = sb->count++; 331 if (sb->count == sb->scroll)
315 newone->when = when; 332 sb->scroll++;
316 newone->what = strdup(line); 333 newone->id = sb->count++;
317 newone->link = sb->entries; 334 newone->when = when;
318 newone->stamp= 0xffff; 335 newone->what = strdup(line);
319 if( sb->entries ) 336 newone->link = sb->entries;
320 sb->entries->link = (struct sb_entry*)((unsigned long)sb->entries->link ^ (unsigned long)newone); 337 newone->stamp = 0xffff;
321 else 338 if (sb->entries)
322 sb->last = newone; 339 sb->entries->link = (struct sb_entry *)((unsigned long)sb->entries->link ^
323 sb->entries = newone; 340 (unsigned long)newone);
341 else
342 sb->last = newone;
343 sb->entries = newone;
324 } 344 }
325 return newone; 345 return newone;
326} 346}
327 347
328void flushout ( ) 348void flushout() {
329{
330 sb_flush(sb_out); 349 sb_flush(sb_out);
331 writeout(" "); 350 writeout(" ");
332 outputwidth_desired = 0; 351 outputwidth_desired = 0;
333 outputshown = 0; 352 outputshown = 0;
334} 353}
335 354
336void hideout( ) 355void hideout() {
337{ 356 if (outputshown) {
338 if( outputshown ) { 357 outputshown = 0;
339 outputshown = 0; 358 resize(0);
340 resize(0);
341 } 359 }
342} 360}
343 361
344void showout (void) 362void showout(void) {
345{
346 writeout(" "); 363 writeout(" ");
347 outputcountdown = 6; 364 outputcountdown = 6;
348 outputshown = 1; 365 outputshown = 1;
349 resize(0); 366 resize(0);
350} 367}
351 368
352void writeout (const char *str) 369void writeout(const char *str) {
353{
354 int i; 370 int i;
355 sb_add(sb_out,str,time(NULL)); 371 sb_add(sb_out, str, time(NULL));
356 i = 1 + gettextwidth( str ); 372 i = 1 + gettextwidth(str);
357 if( i > outputwidth_desired ) outputwidth_desired = i; 373 if (i > outputwidth_desired)
374 outputwidth_desired = i;
358} 375}
359 376
360int writechan (char *str) { 377int writechan(char *str) {
361 struct sb_entry *tmp; 378 struct sb_entry *tmp;
362 int i = 0; 379 int i = 0;
363 time_t now = time(NULL); 380 time_t now = time(NULL);
364 tmp = sb_add(sb_pub,str,now); 381 tmp = sb_add(sb_pub, str, now);
365 382
366 if ( (sb_pub->scroll == sb_pub->count) && ((filtertype == 0) || ( testfilter(tmp)))) { 383 if ((sb_pub->scroll == sb_pub->count) &&
367 i = writescr(channel, tmp); 384 ((filtertype == 0) || (testfilter(tmp)))) {
368 wnoutrefresh(channel); 385 i = writescr(channel, tmp);
386 wnoutrefresh(channel);
369 } 387 }
370 388
371 if( querypartner && private ) 389 if (querypartner && private)
372 topicline(NULL); 390 topicline(NULL);
373 else 391 else
374 consoleline(NULL); 392 consoleline(NULL);
@@ -376,55 +394,73 @@ int writechan (char *str) {
376 return i; 394 return i;
377} 395}
378 396
379int writecf (formtstr id, char *str) { 397int writecf(formtstr id, char *str) {
380 struct sb_entry *tmp; 398 struct sb_entry *tmp;
381 int i = 0; 399 int i = 0;
382 time_t now = time(NULL); 400 time_t now = time(NULL);
383 snprintf(tmpstr,TMPSTRSIZE,getformatstr(id),str); 401 snprintf(tmpstr, TMPSTRSIZE, getformatstr(id), str);
384 tmp = sb_add(sb_pub,tmpstr,now); 402 tmp = sb_add(sb_pub, tmpstr, now);
385 403
386 if ( (sb_pub->scroll == sb_pub->count) && 404 if ((sb_pub->scroll == sb_pub->count) &&
387 ((filtertype == 0) || ( testfilter(tmp)))) { 405 ((filtertype == 0) || (testfilter(tmp)))) {
388 i = writescr(channel, tmp); 406 i = writescr(channel, tmp);
389 wnoutrefresh(channel); 407 wnoutrefresh(channel);
390 } 408 }
391 409
392 if( querypartner && private ) 410 if (querypartner && private)
393 topicline(NULL); 411 topicline(NULL);
394 else 412 else
395 consoleline(NULL); 413 consoleline(NULL);
396 414
415 if (!loggedin)
416 sb_add(sb_connect, str, now);
417
397 return i; 418 return i;
398} 419}
399 420
400int writepriv (char *str, int maybeep) { 421void dumpconnect() {
422 struct sb_entry *now = sb_connect->entries, *prev = NULL, *tmp;
423 while (now) {
424 tmp = (struct sb_entry *)((unsigned long)prev ^ (unsigned long)now->link);
425 fputs(now->what, stderr);
426 fputc(10, stderr);
427 prev = now;
428 now = tmp;
429 }
430}
431
432void flushconnect() {
433 sb_flush(sb_connect);
434}
435
436int writepriv(char *str, int maybeep) {
401 int i = 0; 437 int i = 0;
402 if (private) { 438 if (private) {
403 439
404 time_t now = time (NULL); 440 time_t now = time(NULL);
405 struct sb_entry *tmp; 441 struct sb_entry *tmp;
406 tmp = sb_add(sb_priv,str,now); 442 tmp = sb_add(sb_priv, str, now);
407 443
408 if ( !privwinhidden && (sb_priv->scroll == sb_priv->count) && 444 if (!privwinhidden && (sb_priv->scroll == sb_priv->count) &&
409 ((filtertype == 0) || ( testfilter(tmp)))) { 445 ((filtertype == 0) || (testfilter(tmp)))) {
410 i = writescr(private, tmp); 446 i = writescr(private, tmp);
411 } 447 }
412 if( privwinhidden && !querypartner ) { 448 if (privwinhidden && !querypartner) {
413 if( (maybeep != 0) && (getintoption( CF_BELLPRIV ) != 0 )) 449 if ((maybeep != 0) && (getintoption(CF_BELLPRIV) != 0))
414 putchar( 7 ); 450 putchar(7);
415 privheight_desired = privwinhidden; 451 privheight_desired = privwinhidden;
416 privwinhidden = 0; 452 privwinhidden = 0;
417 resize(0); 453 resize(0);
418 } 454 }
419 wnoutrefresh(private); 455 wnoutrefresh(private);
420 456
421 if( querypartner && private ) 457 if (querypartner && private)
422 consoleline(NULL); 458 consoleline(NULL);
423 else 459 else
424 topicline(NULL); 460 topicline(NULL);
425 461
426 } else 462 } else
427 i = writechan( str ); 463 i = writechan(str);
428 464
429 return i; 465 return i;
430} 466}
@@ -434,338 +470,364 @@ int writepriv (char *str, int maybeep) {
434#if NCURSES_VERSION_MAJOR >= 5 470#if NCURSES_VERSION_MAJOR >= 5
435 471
436typedef struct { 472typedef struct {
437 attr_t attr; 473 attr_t attr;
438 short pair; 474 short pair;
439} ncurs_attr; 475} ncurs_attr;
440 476
441#define WATTR_GET( win, orgattr ) wattr_get( win, &orgattr.attr, &orgattr.pair, NULL) 477#define WATTR_GET(win, orgattr) \
442#define WATTR_SET( win, orgattr ) wattr_set( win, orgattr.attr, orgattr.pair, NULL) 478 wattr_get(win, &orgattr.attr, &orgattr.pair, NULL)
443#define BCOLR_SET( attr, colour ) attr->pair = colour; 479#define WATTR_SET(win, orgattr) wattr_set(win, orgattr.attr, orgattr.pair, NULL)
480#define BCOLR_SET(attr, colour) attr->pair = colour;
444 481
445#else 482#else
446 483
447typedef struct { 484typedef struct {
448 attr_t attr; 485 attr_t attr;
449} ncurs_attr; 486} ncurs_attr;
450 487
451#define WATTR_GET( win, orgattr ) orgattr.attr = wattr_get(win); 488#define WATTR_GET(win, orgattr) orgattr.attr = wattr_get(win);
452#define WATTR_SET( win, orgattr ) wattr_set( win, orgattr.attr); 489#define WATTR_SET(win, orgattr) wattr_set(win, orgattr.attr);
453#define BCOLR_SET( attr, colour ) attr->attr = ((attr->attr) & ~A_COLOR) | COLOR_PAIR((colour)); 490#define BCOLR_SET(attr, colour) \
491 attr->attr = ((attr->attr) & ~A_COLOR) | COLOR_PAIR((colour));
454 492
455#endif 493#endif
456 494
457/* 'A' - 'Z' attriute type */ 495/* 'A' - 'Z' attriute type */
458static int attributes[] = { A_ALTCHARSET, A_BOLD, 0, A_DIM, 0, 0, 0, 0, A_INVIS, 0, 0, A_BLINK, 496static int attributes[] = {A_ALTCHARSET,
459 0, A_NORMAL, 0, A_PROTECT, 0, A_REVERSE, A_STANDOUT, 0, A_UNDERLINE, 497 A_BOLD,
460 0, 0, 1, 0, 0 }; 498 0,
461 499 A_DIM,
462static void 500 0,
463docolorize (char colour, ncurs_attr *attr, ncurs_attr orgattr) { 501 0,
464 if( colour== '0') { 502 0,
465 *attr = orgattr; 503 0,
466 } else if( ( colour > '0') && ( colour <= '9')) { 504 A_INVIS,
467 BCOLR_SET( attr, colour - '0' ); 505 0,
506 0,
507 A_BLINK,
508 0,
509 A_NORMAL,
510 0,
511 A_PROTECT,
512 0,
513 A_REVERSE,
514 A_STANDOUT,
515 0,
516 A_UNDERLINE,
517 0,
518 0,
519 1,
520 0,
521 0};
522
523static void docolorize(char colour, ncurs_attr *attr, ncurs_attr orgattr) {
524 if (colour == '0') {
525 *attr = orgattr;
526 } else if ((colour > '0') && (colour <= '9')) {
527 BCOLR_SET(attr, colour - '0');
468 } else { 528 } else {
469 char upc = colour & ( 0x20 ^ 0xff ); /* colour AND NOT 0x20 */ 529 char upc = colour & (0x20 ^ 0xff); /* colour AND NOT 0x20 */
470 attr_t newattr; 530 attr_t newattr;
471 if( ( upc >= 'A') && ( upc<='Z' ) && ( newattr = attributes[upc - 'A']) ) 531 if ((upc >= 'A') && (upc <= 'Z') && (newattr = attributes[upc - 'A']))
472 attr->attr = ( colour & 0x20 ) ? attr->attr | newattr : attr->attr & ~newattr; 532 attr->attr =
533 (colour & 0x20) ? attr->attr | newattr : attr->attr & ~newattr;
473 } 534 }
474} 535}
475 536
476/* draw arbitrary strings */ 537/* draw arbitrary strings */
477static int 538static int writescr(WINDOW *win, struct sb_entry *entry) {
478writescr ( WINDOW *win, struct sb_entry *entry ) { 539 char tmp[64];
479 char tmp [64];
480 int charcount = 0; 540 int charcount = 0;
481 int i; 541 int i;
482 int textlen = strlen( entry->what ); 542 int textlen = strlen(entry->what);
483 int timelen = ((win == channel)||(win == private)) && usetime ? 543 int timelen = ((win == channel) || (win == private)) && usetime
484 (int)strftime(tmp,64,getformatstr(FS_TIME),localtime(&entry->when)) : 0; 544 ? (int)strftime(tmp, 64, getformatstr(FS_TIME),
485 char textbuffer[ textlen+timelen+1 ]; 545 localtime(&entry->when))
486 ncurs_attr attrbuffer[ textlen+timelen+1 ]; 546 : 0;
487 ncurs_attr orgattr; 547 char textbuffer[textlen + timelen + 1];
548 ncurs_attr attrbuffer[textlen + timelen + 1];
549 ncurs_attr orgattr;
488 550
489 /* illegal window? return */ 551 /* illegal window? return */
490 if( !win || !(textlen+timelen)) return 0; 552 if (!win || !(textlen + timelen))
553 return 0;
491 554
492 /* store original attributes */ 555 /* store original attributes */
493 WATTR_GET( win, orgattr); 556 WATTR_GET(win, orgattr);
494 attrbuffer[ 0 ] = orgattr; 557 attrbuffer[0] = orgattr;
495 558
496 /* copy time string */ 559 /* copy time string */
497 for( i = 0; i < timelen; i++ ) 560 for (i = 0; i < timelen; i++)
498 if( tmp[ i ] == 1 ) { 561 if (tmp[i] == 1) {
499 docolorize( tmp[++i], attrbuffer+charcount, orgattr); 562 docolorize(tmp[++i], attrbuffer + charcount, orgattr);
500 } else { 563 } else {
501 attrbuffer[ charcount+1 ] = attrbuffer[ charcount ]; 564 attrbuffer[charcount + 1] = attrbuffer[charcount];
502 textbuffer[ charcount++ ] = tmp[ i ]; 565 textbuffer[charcount++] = tmp[i];
503 } 566 }
504 567
505 timelen = charcount; 568 timelen = charcount;
506 569
507 /* copy text */ 570 /* copy text */
508 for( i = 0; i< textlen; i++ ) 571 for (i = 0; i < textlen; i++)
509 if( entry->what[ i ] == 1 ) { 572 if (entry->what[i] == 1) {
510 docolorize( entry->what[++i], attrbuffer+charcount, orgattr); 573 docolorize(entry->what[++i], attrbuffer + charcount, orgattr);
511 } else { 574 } else {
512 attrbuffer[ charcount+1 ] = attrbuffer[ charcount ]; 575 attrbuffer[charcount + 1] = attrbuffer[charcount];
513 textbuffer[ charcount++ ] = entry->what[ i ]; 576 textbuffer[charcount++] = entry->what[i];
514 } 577 }
515 578
516 /* zero terminate text --- very important :) */ 579 /* zero terminate text --- very important :) */
517 textbuffer[ charcount ] = 0; 580 textbuffer[charcount] = 0;
518 581
519 /* hilite */ 582 /* hilite */
520 if((win == channel)||(win == private)) { /* do not higlight bars */ 583 if ((win == channel) || (win == private)) { /* do not higlight bars */
521 filt *flt = filterlist; 584 filt *flt = filterlist;
522 char *instr = textbuffer; 585 char *instr = textbuffer;
523 regmatch_t match; 586 regmatch_t match;
524 int j; 587 int j;
525 588
526 while( flt ) { 589 while (flt) {
527 if ( (flt->colour != '-') && (flt->colour != '+')) { 590 if ((flt->colour != '-') && (flt->colour != '+')) {
528 i = timelen; 591 i = timelen;
529 while( i < charcount ) { 592 while (i < charcount) {
530 if( regexec( &flt->regex, instr+i, 1, &match, 0 )) { 593 if (regexec(&flt->regex, instr + i, 1, &match, 0)) {
531 i = charcount; 594 i = charcount;
532 } else { 595 } else {
533 for( j = i + match.rm_so; j < i + match.rm_eo; j++) 596 for (j = i + match.rm_so; j < i + match.rm_eo; j++)
534 docolorize( flt->colour, attrbuffer+j, orgattr ); 597 docolorize(flt->colour, attrbuffer + j, orgattr);
535 i += 1 + match.rm_so; 598 i += 1 + match.rm_so;
536 }
537 }
538 } 599 }
539 flt = flt->next; 600 }
540 } 601 }
602 flt = flt->next;
603 }
541 } 604 }
542 605
543 if (getcurx(win)) waddch(win,'\n'); 606 if (getcurx(win))
544 607 waddch(win, '\n');
545 for( i = 0; i < charcount; i++ ) { 608
546 /* on start of line or attribute changes set new attribute */ 609 for (i = 0; i < charcount; i++) {
547 if( !i || memcmp( attrbuffer+i, attrbuffer+i-1, sizeof(ncurs_attr))) 610 /* on start of line or attribute changes set new attribute */
548 WATTR_SET( win, attrbuffer[i]); 611 if (!i || memcmp(attrbuffer + i, attrbuffer + i - 1, sizeof(ncurs_attr)))
549 if( textbuffer[ i ] == ' ') { 612 WATTR_SET(win, attrbuffer[i]);
550 if ((calcdrawcus(textbuffer+i+1) + getcurx(win) > getmaxx(win) - 1 - 1)&& 613 if (textbuffer[i] == ' ') {
551 (calcdrawcus(textbuffer+i+1) < getmaxx(win) - 1 )) { 614 if ((calcdrawcus(textbuffer + i + 1) + getcurx(win) >
552 /* line wrap found */ 615 getmaxx(win) - 1 - 1) &&
553 WATTR_SET( win, orgattr); 616 (calcdrawcus(textbuffer + i + 1) < getmaxx(win) - 1)) {
554 waddstr( win, "\n "); 617 /* line wrap found */
555 WATTR_SET( win, attrbuffer[ i ]); 618 WATTR_SET(win, orgattr);
556 } 619 waddstr(win, "\n ");
620 WATTR_SET(win, attrbuffer[i]);
557 } 621 }
558 /* plot character */ 622 }
559 waddch( win, (unsigned char)textbuffer[ i ]); 623 /* plot character */
624 waddch(win, (unsigned char)textbuffer[i]);
560 } 625 }
561 626
562 /* restore old attributes */ 627 /* restore old attributes */
563 WATTR_SET (win, orgattr); 628 WATTR_SET(win, orgattr);
564 629
565 return charcount; 630 return charcount;
566} 631}
567 632
568static void 633static void resize_output() {
569resize_output ( ) 634 int outputwidth =
570{ 635 (outputwidth_desired + 7 > screensx) ? screensx - 7 : outputwidth_desired;
571 int outputwidth = (outputwidth_desired + 7 > screensx) ? screensx - 7 : outputwidth_desired; 636 int outputheight = getsbdataheight(sb_out, outputwidth - 1, 0);
572 int outputheight = getsbdataheight(sb_out, outputwidth-1, 0);
573 637
574 if (outputheight + 5 > screensy ) outputheight = screensy - 5; 638 if (outputheight + 5 > screensy)
575 wresize(output,outputheight,outputwidth); 639 outputheight = screensy - 5;
576 mvwin(output,(screensy-outputheight)>>1,(screensx-outputwidth)>>1); 640 wresize(output, outputheight, outputwidth);
641 mvwin(output, (screensy - outputheight) >> 1, (screensx - outputwidth) >> 1);
577 drawwin(output, sb_out); 642 drawwin(output, sb_out);
578} 643}
579 644
580static void 645static void doscroll(int up) {
581doscroll ( int up ) {
582 togglequery(); 646 togglequery();
583 { 647 {
584 WINDOW *destwin = (sb_win && private) ? private : channel; 648 WINDOW *destwin = (sb_win && private) ? private : channel;
585 struct sb_data *sb = (sb_win && private) ? sb_priv : sb_pub; 649 struct sb_data *sb = (sb_win && private) ? sb_priv : sb_pub;
586 struct sb_entry *now = sb->entries, *prev = NULL, *tmp; 650 struct sb_entry *now = sb->entries, *prev = NULL, *tmp;
587 int lines = (getmaxy(destwin) - 1 ) >>1; 651 int lines = (getmaxy(destwin) - 1) >> 1;
588 652
589 if( sb->scroll != sb->count ) 653 if (sb->scroll != sb->count)
590 while( now && (now->id != sb->scroll) ) { 654 while (now && (now->id != sb->scroll)) {
591 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 655 tmp = now;
656 now =
657 (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
658 prev = tmp;
592 } 659 }
593 660
594 if( !up ) { 661 if (!up) {
595 prev = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); 662 prev =
596 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 663 (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
597 } 664 tmp = now;
665 now = (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
666 prev = tmp;
667 }
598 668
599 while( now && (lines > 0)) { 669 while (now && (lines > 0)) {
600 if ( (!filtertype) || ( (now->stamp != currentstamp) && ( (now->stamp == (currentstamp | (1<<15))) || testfilter( now ) ) ) ) 670 if ((!filtertype) ||
601 { 671 ((now->stamp != currentstamp) &&
602 lines -= getsbeheight( now, getmaxx(destwin) - 1, usetime ); 672 ((now->stamp == (currentstamp | (1 << 15))) || testfilter(now)))) {
673 lines -= getsbeheight(now, getmaxx(destwin) - 1, usetime);
603 } 674 }
604 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 675 tmp = now;
605 } 676 now = (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
606 if( now ) 677 prev = tmp;
678 }
679 if (now)
607 sb->scroll = now->id; 680 sb->scroll = now->id;
608 else 681 else if (!up)
609 if( !up ) sb->scroll = sb->count; 682 sb->scroll = sb->count;
610 683
611 drawwin(destwin, sb); 684 drawwin(destwin, sb);
612 wnoutrefresh(destwin); 685 wnoutrefresh(destwin);
613 686
614 togglequery(); 687 togglequery();
615 688
616 if( private && (destwin == channel) ) 689 if (private && (destwin == channel))
617 consoleline( NULL); 690 consoleline(NULL);
618 else 691 else
619 topicline( NULL); 692 topicline(NULL);
620 } 693 }
621} 694}
622 695
696void scrollup(void) { doscroll(1); }
623 697
624void 698void scrolldown(void) { doscroll(0); }
625scrollup (void)
626{
627 doscroll( 1 );
628}
629
630void
631scrolldown (void)
632{
633 doscroll( 0 );
634}
635 699
636void 700void scrollwin(void) {
637scrollwin (void) 701 if (!sb_win && private && !privwinhidden)
638{ 702 sb_win = 1;
639 if (!sb_win && private && !privwinhidden) sb_win = 1; 703 else
640 else sb_win = 0; 704 sb_win = 0;
641 topicline(NULL); 705 topicline(NULL);
642 consoleline(NULL); 706 consoleline(NULL);
643} 707}
644 708
645void 709void growprivwin(void) {
646growprivwin (void) { 710 if (private) {
647 if( private ) { 711 if (privwinhidden)
648 if( privwinhidden) 712 privwinhidden = 0;
649 privwinhidden = 0; 713 if (++privheight_desired > screensy - 5)
650 if( ++privheight_desired > screensy - 5) 714 privheight_desired = screensy - 5;
651 privheight_desired = screensy - 5; 715 resize(0);
652 resize(0); 716 }
653 }
654} 717}
655 718
656void toggleprivwin (void) { 719void toggleprivwin(void) {
657 if( outputshown ) { 720 if (outputshown) {
658 outputshown = 0; 721 outputshown = 0;
659 resize(0); 722 resize(0);
660 } else { 723 } else {
661 if( private ) { 724 if (private) {
662 if( privwinhidden ) { 725 if (privwinhidden) {
663 privheight_desired = privwinhidden; 726 privheight_desired = privwinhidden;
664 privwinhidden = 0; 727 privwinhidden = 0;
665 } else { 728 } else {
666 privwinhidden = privheight_desired; 729 privwinhidden = privheight_desired;
667 privheight_desired = 1; 730 privheight_desired = 1;
668 sb_win = 0; 731 sb_win = 0;
669 sb_priv->scroll = sb_priv->count; 732 sb_priv->scroll = sb_priv->count;
670 } 733 }
671 resize(0); 734 resize(0);
672 } 735 }
673 } 736 }
674} 737}
675 738
676void 739void shrinkprivwin(void) {
677shrinkprivwin (void) { 740 if (private && !privwinhidden) {
678 if( private && !privwinhidden ) { 741 if (--privheight_desired < 1)
679 if( --privheight_desired < 1) privheight_desired = 1; 742 privheight_desired = 1;
680 if( privheight_desired > screensy - 5) privheight_desired = screensy - 5; 743 if (privheight_desired > screensy - 5)
744 privheight_desired = screensy - 5;
681 resize(0); 745 resize(0);
682 } 746 }
683} 747}
684 748
685/* clear message window */ 749/* clear message window */
686void 750void clearpriv() {
687clearpriv ()
688{
689 WINDOW *dest = NULL; 751 WINDOW *dest = NULL;
690 /* do we have a private window? */ 752 /* do we have a private window? */
691 if (private && !privwinhidden ) 753 if (private && !privwinhidden)
692 dest = private; 754 dest = private;
693 else 755 else
694 dest = channel; 756 dest = channel;
695 757
696 /* clear window, move cursor to bottom, redraw */ 758 /* clear window, move cursor to bottom, redraw */
697 wclear (dest); 759 wclear(dest);
698 wmove (dest, getmaxy(dest) - 1, getmaxx(dest) - 1); 760 wmove(dest, getmaxy(dest) - 1, getmaxx(dest) - 1);
699 wrefresh (dest); 761 wrefresh(dest);
700
701} 762}
702 763
703/* clear channel window */ 764/* clear channel window */
704void 765void clearchan() {
705clearchan ()
706{
707 /* clear window, move cursor to bottom, redraw */ 766 /* clear window, move cursor to bottom, redraw */
708 wclear (channel); 767 wclear(channel);
709 wmove (channel, getmaxy(channel) - 1, getmaxx(channel) - 1); 768 wmove(channel, getmaxy(channel) - 1, getmaxx(channel) - 1);
710 wrefresh (channel); 769 wrefresh(channel);
711} 770}
712 771
713/* Get window size */ 772/* Get window size */
714 773
715void ttgtsz(int *x,int *y) { 774void ttgtsz(int *x, int *y) {
716#ifdef TIOCGSIZE 775#ifdef TIOCGSIZE
717 struct ttysize getit; 776 struct ttysize getit;
718#else 777#else
719#ifdef TIOCGWINSZ 778#ifdef TIOCGWINSZ
720 struct winsize getit; 779 struct winsize getit;
721#endif 780#endif
722#endif 781#endif
723 782
724 *x=0; *y=0; 783 *x = 0;
784 *y = 0;
725#ifdef TIOCGSIZE 785#ifdef TIOCGSIZE
726 if(ioctl(1,TIOCGSIZE,&getit)!= -1) { 786 if (ioctl(1, TIOCGSIZE, &getit) != -1) {
727 *x=getit.ts_cols; 787 *x = getit.ts_cols;
728 *y=getit.ts_lines; 788 *y = getit.ts_lines;
729 } 789 }
730#else 790#else
731#ifdef TIOCGWINSZ 791#ifdef TIOCGWINSZ
732 if(ioctl(1,TIOCGWINSZ,&getit)!= -1) { 792 if (ioctl(1, TIOCGWINSZ, &getit) != -1) {
733 *x=getit.ws_col; 793 *x = getit.ws_col;
734 *y=getit.ws_row; 794 *y = getit.ws_row;
735 } 795 }
736#endif 796#endif
737#endif 797#endif
738 } 798}
739 799
740static void 800static void forceredraw(void) {
741forceredraw (void)
742{
743 sb_pub->scroll = sb_pub->count; 801 sb_pub->scroll = sb_pub->count;
744 sb_priv->scroll = sb_priv->count; 802 sb_priv->scroll = sb_priv->count;
745 803
746 resize(0); 804 resize(0);
747 if(console) wclear(console); 805 if (console)
748 if(topic) wclear(topic); 806 wclear(console);
749 if(private) wclear(private); 807 if (topic)
750 if(channel) wclear(channel ); 808 wclear(topic);
751 if(output) wclear(output); 809 if (private)
752 if(input) wclear(input); 810 wclear(private);
811 if (channel)
812 wclear(channel);
813 if (output)
814 wclear(output);
815 if (input)
816 wclear(input);
753 resize(0); 817 resize(0);
754
755} 818}
756 819
757/* resize display on SIGWINCH 820/* resize display on SIGWINCH
758 Nowadays used as our main redraw trigger engine */ 821 Nowadays used as our main redraw trigger engine */
759void 822void resize(int signal) {
760resize (int signal) 823 int xsize, ysize, topicheight = topic ? 1 : 0;
761{ 824 (void)signal;
762 int xsize,ysize,topicheight=topic?1:0;
763 825
764 ttgtsz(&xsize,&ysize); 826 ttgtsz(&xsize, &ysize);
765 resizeterm(ysize,xsize); 827 resizeterm(ysize, xsize);
766 828
767 /* store screen-dimensions to local functions */ 829 /* store screen-dimensions to local functions */
768 getmaxyx (stdscr, screensy, screensx); 830 getmaxyx(stdscr, screensy, screensx);
769 831
770 /* desired height of PM window is user controllable, 832 /* desired height of PM window is user controllable,
771 actual size depends on space available on screen */ 833 actual size depends on space available on screen */
@@ -774,24 +836,34 @@ resize (int signal)
774 836
775 /* Leave at least 5 lines for input, console and 837 /* Leave at least 5 lines for input, console and
776 pubchannel */ 838 pubchannel */
777 if ( privheight_desired > screensy - 5) 839 if (privheight_desired > screensy - 5)
778 privheight = screensy - 5; 840 privheight = screensy - 5;
779 else 841 else
780 privheight = privheight_desired; 842 privheight = privheight_desired;
781 843
782 /* check dimensions or bump user */ 844 /* check dimensions or bump user */
783 if (screensy - privheight < 4) 845 if (screensy - privheight < 4) {
784 { 846 fprintf(stderr,
785 fprintf (stderr, "vchat-client: screen to short (only %d rows, at least %d expected), bailing out.\n", screensy, privheight + 6); 847 "vchat-client: screen to short (only %d rows, at least %d "
786 snprintf (errstr, ERRSTRSIZE, "vchat-client: screen to short (only %d rows, at least %d expected), bailing out.\n", screensy, privheight + 6); 848 "expected), bailing out.\n",
787 cleanup (0); 849 screensy, privheight + 6);
788 } 850 snprintf(errstr, ERRSTRSIZE,
789 if (screensx < 14) 851 "vchat-client: screen to short (only %d rows, at least %d "
790 { 852 "expected), bailing out.\n",
791 fprintf (stderr, "vchat-client: screen to thin (only %d cols, at least %d expected), bailing out.\n", screensx, 14); 853 screensy, privheight + 6);
792 snprintf (errstr, ERRSTRSIZE, "vchat-client: screen to thin (only %d cols, at least %d expected), bailing out.\n", screensx, 14); 854 cleanup(0);
793 cleanup (0); 855 }
794 } 856 if (screensx < 14) {
857 fprintf(stderr,
858 "vchat-client: screen to thin (only %d cols, at least %d "
859 "expected), bailing out.\n",
860 screensx, 14);
861 snprintf(errstr, ERRSTRSIZE,
862 "vchat-client: screen to thin (only %d cols, at least %d "
863 "expected), bailing out.\n",
864 screensx, 14);
865 cleanup(0);
866 }
795 867
796 /***** 868 /*****
797 * Arrange windows on screen 869 * Arrange windows on screen
@@ -800,38 +872,44 @@ resize (int signal)
800 togglequery(); 872 togglequery();
801 873
802 /* console and input are always there and always 1 line tall */ 874 /* console and input are always there and always 1 line tall */
803 wresize(console,1,screensx); 875 wresize(console, 1, screensx);
804 wresize(input,1,screensx); 876 wresize(input, 1, screensx);
805 877
806 /* If we got a private window and it is not hidden, set its size */ 878 /* If we got a private window and it is not hidden, set its size */
807 if (private && !privwinhidden) 879 if (private && !privwinhidden)
808 wresize(private,privheight,screensx); 880 wresize(private, privheight, screensx);
809 881
810 /* If oldschool vchat is not enabled, we have a topic line */ 882 /* If oldschool vchat is not enabled, we have a topic line */
811 if( topic ) 883 if (topic)
812 wresize(topic,1,screensx); 884 wresize(topic, 1, screensx);
813 885
814 /* public channel is always there and its height depends on: 886 /* public channel is always there and its height depends on:
815 * existence and visibility of priv window 887 * existence and visibility of priv window
816 * existence of a topic line (oldschool vchat style) 888 * existence of a topic line (oldschool vchat style)
817 */ 889 */
818 wresize(channel, ( !private || privwinhidden ) ? screensy - ( topicheight + 2 ) : screensy - (privheight + ( topicheight + 2 )), screensx); 890 wresize(channel,
891 (!private || privwinhidden)
892 ? screensy - (topicheight + 2)
893 : screensy - (privheight + (topicheight + 2)),
894 screensx);
819 895
820 /* Console and input alway take bottommost lines */ 896 /* Console and input alway take bottommost lines */
821 mvwin(console,screensy-2,0); 897 mvwin(console, screensy - 2, 0);
822 mvwin(input,screensy-1,0); 898 mvwin(input, screensy - 1, 0);
823 899
824 /* Private window always is top left */ 900 /* Private window always is top left */
825 if(private && !privwinhidden) 901 if (private && !privwinhidden)
826 mvwin(private,0,0); 902 mvwin(private, 0, 0);
827 903
828 /* Topic window may not exist without priv window, so it is 904 /* Topic window may not exist without priv window, so it is
829 safe to assume sane values for privwinhidden and privheight */ 905 safe to assume sane values for privwinhidden and privheight */
830 if( topic ) 906 if (topic)
831 mvwin(topic,privwinhidden ? 0 : privheight, 0); 907 mvwin(topic, privwinhidden ? 0 : privheight, 0);
832 908
833 /* chan window starts below private window and topic line */ 909 /* chan window starts below private window and topic line */
834 mvwin(channel, ( !private || privwinhidden ) ? topicheight : privheight + topicheight, 0); 910 mvwin(channel,
911 (!private || privwinhidden) ? topicheight : privheight + topicheight,
912 0);
835 913
836 /******* 914 /*******
837 * Now actual redraw starts, note, that we only fill 915 * Now actual redraw starts, note, that we only fill
@@ -844,96 +922,106 @@ resize (int signal)
844 ******/ 922 ******/
845 923
846 /* pub channel is always there, paint scrollback buffers */ 924 /* pub channel is always there, paint scrollback buffers */
847 drawwin(channel, sb_pub); 925 drawwin(channel, sb_pub);
848 /* if priv exists and is visible, paint scrollback buffers */ 926 /* if priv exists and is visible, paint scrollback buffers */
849 if(private && !privwinhidden ) 927 if (private && !privwinhidden)
850 drawwin(private, sb_priv); 928 drawwin(private, sb_priv);
851 /* Send window's contents to curses virtual buffers */ 929 /* Send window's contents to curses virtual buffers */
852 wnoutrefresh(channel); 930 wnoutrefresh(channel);
853 if(private && !privwinhidden ) 931 if (private && !privwinhidden)
854 wnoutrefresh(private); 932 wnoutrefresh(private);
855 933
856 togglequery(); 934 togglequery();
857 935
858 /* Resize and draw our message window, render topic and 936 /* Resize and draw our message window, render topic and
859 console line */ 937 console line */
860 if(outputshown) resize_output(); 938 if (outputshown)
861 if(topic) topicline(NULL); 939 resize_output();
862 consoleline(NULL); 940 if (topic)
863 if(loggedin) vciredraw(); 941 topicline(NULL);
942 consoleline(NULL);
943 if (loggedin)
944 vciredraw();
864} 945}
865 946
866static int 947static int gettextwidth(const char *textbuffer) {
867gettextwidth (const char *textbuffer) 948 int width = 0;
868{
869 int width = 0;
870 949
871 do switch( *(textbuffer++) ) { 950 do
872 case 1: 951 switch (*(textbuffer++)) {
873 if (!*(textbuffer++)) return width; 952 case 1:
874 break; 953 if (!*(textbuffer++))
875 case 0: 954 return width;
955 break;
956 case 0:
876 return width; 957 return width;
877 break; 958 break;
878 default: 959 default:
879 width++; 960 width++;
880 break; 961 break;
881 } while( 1 ); 962 }
963 while (1);
882} 964}
883 965
884static int 966static int getsbdataheight(struct sb_data *data, const int xwidth,
885getsbdataheight (struct sb_data *data, const int xwidth, int needstime ) 967 int needstime) {
886{
887 struct sb_entry *now = data->entries, *prev = NULL, *tmp; 968 struct sb_entry *now = data->entries, *prev = NULL, *tmp;
888 int height = 0; 969 int height = 0;
889 while( now ) { 970 while (now) {
890 height += getsbeheight( now, xwidth, needstime); 971 height += getsbeheight(now, xwidth, needstime);
891 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 972 tmp = now;
973 now = (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
974 prev = tmp;
892 } 975 }
893 return height; 976 return height;
894} 977}
895 978
896static int 979static int getsbeheight(struct sb_entry *entry, const int xwidth,
897getsbeheight (struct sb_entry *entry, const int xwidth, int needstime ) 980 int needstime) {
898{
899 int curx = 0, lines = 1; 981 int curx = 0, lines = 1;
900 char tmp[ 64 ], *textbuffer; 982 char tmp[64], *textbuffer;
901 983
902 if( needstime ) { 984 if (needstime) {
903 int timelen = (int)strftime(tmp,64,getformatstr(FS_TIME),localtime(&entry->when)); 985 int timelen =
904 tmp[ timelen ] = 2; 986 (int)strftime(tmp, 64, getformatstr(FS_TIME), localtime(&entry->when));
905 textbuffer=tmp; 987 tmp[timelen] = 2;
988 textbuffer = tmp;
906 } else { 989 } else {
907 textbuffer = entry->what; 990 textbuffer = entry->what;
908 } 991 }
909 992
910 do switch( *textbuffer++ ) { 993 do
911 case ' ': 994 switch (*textbuffer++) {
995 case ' ':
912 if ((calcdrawcus(textbuffer) + curx > xwidth - 1) && 996 if ((calcdrawcus(textbuffer) + curx > xwidth - 1) &&
913 (calcdrawcus(textbuffer) < xwidth)) { 997 (calcdrawcus(textbuffer) < xwidth)) {
914 lines++; curx = 4; 998 lines++;
915 } else { 999 curx = 4;
916 if( curx++ == xwidth ) { 1000 } else {
917 curx = 0; lines++; 1001 if (curx++ == xwidth) {
918 } 1002 curx = 0;
919 } 1003 lines++;
1004 }
1005 }
920 break; 1006 break;
921 case 1: 1007 case 1:
922 if (!*textbuffer++) return lines; 1008 if (!*textbuffer++)
923 break; 1009 return lines;
924 case 0: 1010 break;
1011 case 0:
925 return lines; 1012 return lines;
926 break; 1013 break;
927 case 2: 1014 case 2:
928 textbuffer=entry->what; 1015 textbuffer = entry->what;
929 break; 1016 break;
930 default: 1017 default:
931 if( curx++ == xwidth ) { 1018 if (curx++ == xwidth) {
932 curx = 0; lines++; 1019 curx = 0;
1020 lines++;
933 } 1021 }
934 break; 1022 break;
935 } while( 1 ); 1023 }
936 1024 while (1);
937} 1025}
938 1026
939/* Check, which kind of filter we have to apply: 1027/* Check, which kind of filter we have to apply:
@@ -943,8 +1031,7 @@ getsbeheight (struct sb_entry *entry, const int xwidth, int needstime )
943 If no, or only colouring rules have been found, 1031 If no, or only colouring rules have been found,
944 no line filtering applies. 1032 no line filtering applies.
945*/ 1033*/
946static int 1034static int analyzefilters(void) {
947analyzefilters( void ) {
948 filt *filters = filterlist; 1035 filt *filters = filterlist;
949 int type = 0; 1036 int type = 0;
950 1037
@@ -961,96 +1048,106 @@ analyzefilters( void ) {
961 tested the line against. This Stamp 1048 tested the line against. This Stamp
962 is updated for each change to the 1049 is updated for each change to the
963 filter list */ 1050 filter list */
964 if( ++currentstamp == 0x3fff ) currentstamp = 1; 1051 if (++currentstamp == 0x3fff)
965 1052 currentstamp = 1;
966 while( (type!=1) && filters ) { 1053
967 if( filters->colour == '-' ) type = 2; 1054 while ((type != 1) && filters) {
968 if( filters->colour == '+' ) type = 1; 1055 if (filters->colour == '-')
969 filters=filters->next; 1056 type = 2;
1057 if (filters->colour == '+')
1058 type = 1;
1059 filters = filters->next;
970 } 1060 }
971 return type; 1061 return type;
972} 1062}
973 1063
974static int 1064static int testfilter(struct sb_entry *entry) {
975testfilter ( struct sb_entry* entry ) { 1065 int match = 0;
976 int match = 0; 1066 filt *filters = filterlist;
977 filt *filters = filterlist; 1067 char filtercolour = filtertype == 2 ? '-' : '+';
978 char filtercolour = filtertype == 2 ? '-' : '+';
979 1068
980 while( !match && filters ) { 1069 while (!match && filters) {
981 if( filters->colour == filtercolour ) 1070 if (filters->colour == filtercolour)
982 match = regexec( &filters->regex, entry->what, 0, NULL, 0 ) ? 0 : 1; 1071 match = regexec(&filters->regex, entry->what, 0, NULL, 0) ? 0 : 1;
983 filters=filters->next; 1072 filters = filters->next;
984 } 1073 }
985 match = ( filtertype == 2 ) ? ( 1 - match ) : match; 1074 match = (filtertype == 2) ? (1 - match) : match;
986 entry->stamp = (match << 15) | currentstamp; 1075 entry->stamp = (match << 15) | currentstamp;
987 1076
988 return match; 1077 return match;
989} 1078}
990 1079
991static void 1080static void drawwin(WINDOW *win, struct sb_data *sb) {
992drawwin (WINDOW *win, struct sb_data *sb )
993{
994 if (win) { 1081 if (win) {
995 struct sb_entry *now = sb->entries, *prev = NULL, *tmp; 1082 struct sb_entry *now = sb->entries, *prev = NULL, *tmp;
996 struct sb_entry *vis[getmaxy(win)]; 1083 struct sb_entry *vis[getmaxy(win)];
997 int sumlines = 0, sumbuffers = 0; 1084 int sumlines = 0, sumbuffers = 0;
998 1085
999 /* public scrollback */ 1086 /* public scrollback */
1000 if( sb->scroll != sb->count ) 1087 if (sb->scroll != sb->count)
1001 while( now && (now->id != sb->scroll) ) { 1088 while (now && (now->id != sb->scroll)) {
1002 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 1089 tmp = now;
1003 } 1090 now =
1091 (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
1092 prev = tmp;
1093 }
1004 1094
1005 if( (win == output) || (filtertype == 0)) { 1095 if ((win == output) || (filtertype == 0)) {
1006 while( now && (sumlines <= getmaxy(win) - 1 )) { 1096 while (now && (sumlines <= getmaxy(win) - 1)) {
1007 sumlines += getsbeheight( now, getmaxx(win) - 1, ((win == channel)||(win == private)) && usetime ); 1097 sumlines +=
1008 vis[ sumbuffers++ ] = now; 1098 getsbeheight(now, getmaxx(win) - 1,
1009 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 1099 ((win == channel) || (win == private)) && usetime);
1010 } 1100 vis[sumbuffers++] = now;
1011 } else { 1101 tmp = now;
1012 while( now && (sumlines <= getmaxy(win) - 1 )) { 1102 now =
1013 1103 (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
1014 /* If stamp matches exactly, line has been filtered out, since top 1104 prev = tmp;
1015 bit off means hidden */ 1105 }
1016 if( now->stamp != currentstamp) { 1106 } else {
1017 1107 while (now && (sumlines <= getmaxy(win) - 1)) {
1018 /* If stamp matches and has top bit set, it has been identified 1108
1019 positively. Else stamp does not match and line has to be 1109 /* If stamp matches exactly, line has been filtered out, since top
1020 tested against filters, which updates stamp. */ 1110 bit off means hidden */
1021 if( (now->stamp == (currentstamp | 0x8000) ) || testfilter( now )) 1111 if (now->stamp != currentstamp) {
1022 { 1112
1023 sumlines += getsbeheight( now, getmaxx(win) - 1, ((win == channel)||(win == private)) && usetime ); 1113 /* If stamp matches and has top bit set, it has been identified
1024 vis[ sumbuffers++ ] = now; 1114 positively. Else stamp does not match and line has to be
1025 } 1115 tested against filters, which updates stamp. */
1026 1116 if ((now->stamp == (currentstamp | 0x8000)) || testfilter(now)) {
1027 } 1117 sumlines +=
1028 tmp = now; now = (struct sb_entry*)((unsigned long)now->link ^ (unsigned long)prev); prev = tmp; 1118 getsbeheight(now, getmaxx(win) - 1,
1119 ((win == channel) || (win == private)) && usetime);
1120 vis[sumbuffers++] = now;
1029 } 1121 }
1122 }
1123 tmp = now;
1124 now =
1125 (struct sb_entry *)((unsigned long)now->link ^ (unsigned long)prev);
1126 prev = tmp;
1030 } 1127 }
1128 }
1031 1129
1032 /* If buffer is not completely filled, clear window */ 1130 /* If buffer is not completely filled, clear window */
1033 if( sumlines < getmaxy(win) ) 1131 if (sumlines < getmaxy(win))
1034 wclear(win); 1132 wclear(win);
1035 1133
1036 /* Move pointer to bottom to let curses scroll */ 1134 /* Move pointer to bottom to let curses scroll */
1037 wmove(win, getmaxy(win) - 1, getmaxx(win) - 1); 1135 wmove(win, getmaxy(win) - 1, getmaxx(win) - 1);
1038 1136
1039 /* Plot visible lines */ 1137 /* Plot visible lines */
1040 while (sumbuffers--) writescr( win, vis[sumbuffers] ); 1138 while (sumbuffers--)
1139 writescr(win, vis[sumbuffers]);
1041 } 1140 }
1042} 1141}
1043 1142
1044/* initialize curses and display */ 1143/* initialize curses and display */
1045void 1144void initui(void) {
1046initui (void)
1047{
1048 Keymap keymap; 1145 Keymap keymap;
1049 1146
1050 /* init curses */ 1147 /* init curses */
1051 if (!ui_init) { 1148 if (!ui_init) {
1052 initscr (); 1149 initscr();
1053 ui_init = 1; 1150 ui_init = 1;
1054 } 1151 }
1055 1152
1056 /* install signalhandler */ 1153 /* install signalhandler */
@@ -1059,119 +1156,146 @@ initui (void)
1059 signal(SIGCONT, forceredraw_wrapper); 1156 signal(SIGCONT, forceredraw_wrapper);
1060 1157
1061 /* set options */ 1158 /* set options */
1062 keypad (stdscr, TRUE); 1159 keypad(stdscr, TRUE);
1063 nonl (); 1160 nonl();
1064 cbreak (); 1161 cbreak();
1065 1162
1066 /* color or monochome display? */ 1163 /* color or monochome display? */
1067 if (has_colors ()) 1164 if (has_colors()) {
1068 { 1165 /* start color and set a colorset */
1069 /* start color and set a colorset */ 1166 start_color();
1070 start_color (); 1167 use_default_colors();
1071 use_default_colors(); 1168 init_pair(1, COLOR_RED, -1);
1072 init_pair (1, COLOR_RED, -1); 1169 init_pair(2, COLOR_GREEN, -1);
1073 init_pair (2, COLOR_GREEN, -1); 1170 init_pair(3, COLOR_YELLOW, -1);
1074 init_pair (3, COLOR_YELLOW, -1); 1171 init_pair(4, COLOR_BLUE, -1);
1075 init_pair (4, COLOR_BLUE, -1); 1172 init_pair(5, COLOR_MAGENTA, -1);
1076 init_pair (5, COLOR_MAGENTA, -1); 1173 init_pair(6, COLOR_CYAN, -1);
1077 init_pair (6, COLOR_CYAN, -1); 1174 init_pair(7, COLOR_WHITE, -1);
1078 init_pair (7, COLOR_WHITE, -1); 1175 init_pair(8, COLOR_WHITE, COLOR_RED);
1079 init_pair (8, COLOR_WHITE, COLOR_RED); 1176 init_pair(9, COLOR_WHITE, COLOR_BLUE);
1080 init_pair (9, COLOR_WHITE, COLOR_BLUE); 1177 init_pair(10, COLOR_WHITE, COLOR_BLACK);
1081 } 1178 } else {
1082 else 1179 /* monochrome, start color and set a colorset anyways */
1083 { 1180 start_color();
1084 /* monochrome, start color and set a colorset anyways */ 1181 init_pair(1, -1, -1);
1085 start_color (); 1182 init_pair(2, -1, -1);
1086 init_pair (1, -1, -1); 1183 init_pair(3, -1, -1);
1087 init_pair (2, -1, -1); 1184 init_pair(4, -1, -1);
1088 init_pair (3, -1, -1); 1185 init_pair(5, -1, -1);
1089 init_pair (4, -1, -1); 1186 init_pair(6, -1, -1);
1090 init_pair (5, -1, -1); 1187 init_pair(7, -1, -1);
1091 init_pair (6, -1, -1); 1188 init_pair(8, -1, -1);
1092 init_pair (7, -1, -1); 1189 init_pair(9, -1, -1);
1093 init_pair (8, -1, -1); 1190 init_pair(10, -1, -1);
1094 init_pair (9, -1, -1); 1191 }
1095 }
1096 1192
1097 /* store screen-dimensions to local functions */ 1193 /* store screen-dimensions to local functions */
1098 getmaxyx (stdscr, screensy, screensx); 1194 getmaxyx(stdscr, screensy, screensx);
1099 1195
1100 if (!privheight_desired) privheight_desired = getintoption(CF_PRIVHEIGHT); 1196 if (!privheight_desired)
1101 if ( privheight_desired > screensy - 5) privheight = screensy - 5; else privheight = privheight_desired; 1197 privheight_desired = getintoption(CF_PRIVHEIGHT);
1198 if (privheight_desired > screensy - 5)
1199 privheight = screensy - 5;
1200 else
1201 privheight = privheight_desired;
1102 1202
1103 /* check dimensions or bump user */ 1203 /* check dimensions or bump user */
1104 if (screensy - privheight < 4) 1204 if (screensy - privheight < 4) {
1105 { 1205 fprintf(stderr,
1106 fprintf (stderr, "vchat-client: screen to short (only %d rows, at least %d expected), bailing out.\n", screensy, privheight + 6); 1206 "vchat-client: screen to short (only %d rows, at least %d "
1107 snprintf (errstr, ERRSTRSIZE, "vchat-client: screen to short (only %d rows, at least %d expected), bailing out.\n", screensy, privheight + 6); 1207 "expected), bailing out.\n",
1108 cleanup (0); 1208 screensy, privheight + 6);
1109 } 1209 snprintf(errstr, ERRSTRSIZE,
1110 if (screensx < 14) 1210 "vchat-client: screen to short (only %d rows, at least %d "
1111 { 1211 "expected), bailing out.\n",
1112 fprintf (stderr, "vchat-client: screen to thin (only %d cols, at least %d expected), bailing out.\n", screensx, 14); 1212 screensy, privheight + 6);
1113 snprintf (errstr, ERRSTRSIZE, "vchat-client: screen to thin (only %d cols, at least %d expected), bailing out.\n", screensx, 14); 1213 cleanup(0);
1114 cleanup (0); 1214 }
1115 } 1215 if (screensx < 14) {
1216 fprintf(stderr,
1217 "vchat-client: screen to thin (only %d cols, at least %d "
1218 "expected), bailing out.\n",
1219 screensx, 14);
1220 snprintf(errstr, ERRSTRSIZE,
1221 "vchat-client: screen to thin (only %d cols, at least %d "
1222 "expected), bailing out.\n",
1223 screensx, 14);
1224 cleanup(0);
1225 }
1116 1226
1117 /* setup our windows */ 1227 /* setup our windows */
1118 console = newwin (1, screensx, screensy - 2, 0); 1228 console = newwin(1, screensx, screensy - 2, 0);
1119 input = newwin (1, screensx, screensy - 1, 0); 1229 input = newwin(1, screensx, screensy - 1, 0);
1120 if (privheight) private = newwin (privheight, screensx, 0, 0); 1230 if (privheight)
1121 if( private || getintoption(CF_USETOPIC)) 1231 private
1122 topic = newwin (1, screensx, privheight, 0); 1232 = newwin(privheight, screensx, 0, 0);
1123 channel = newwin (screensy - (privheight+3), screensx, (privheight+1), 0); 1233 if (private || getintoption(CF_USETOPIC))
1124 output = newwin (1, screensx, 1, 0); 1234 topic = newwin(1, screensx, privheight, 0);
1235 channel = newwin(screensy - (privheight + 3), screensx, (privheight + 1), 0);
1236 output = newwin(1, screensx, 1, 0);
1125 1237
1126 /* promblems opening windows? bye! */ 1238 /* promblems opening windows? bye! */
1127 if (!console || !input || (!topic && getintoption(CF_USETOPIC))|| !channel || !output || ( !private && privheight )) 1239 if (!console || !input || (!topic && getintoption(CF_USETOPIC)) || !channel ||
1128 { 1240 !output || (!private && privheight)) {
1129 fprintf (stderr, "vchat-client: could not open windows, bailing out.\n"); 1241 fprintf(stderr, "vchat-client: could not open windows, bailing out.\n");
1130 cleanup (0); 1242 cleanup(0);
1131 } 1243 }
1132 1244
1133 /* Prepare our scrollback buffers */ 1245 /* Prepare our scrollback buffers */
1134 sb_pub = (struct sb_data*)malloc( sizeof(struct sb_data)); 1246 sb_pub = (struct sb_data *)malloc(sizeof(struct sb_data));
1135 sb_out = (struct sb_data*)malloc( sizeof(struct sb_data)); 1247 sb_out = (struct sb_data *)malloc(sizeof(struct sb_data));
1136 if( privheight) 1248 sb_connect = (struct sb_data *)malloc(sizeof(struct sb_data));
1137 sb_priv = (struct sb_data*)malloc( sizeof(struct sb_data)); 1249 if (privheight)
1250 sb_priv = (struct sb_data *)malloc(sizeof(struct sb_data));
1138 else 1251 else
1139 sb_priv = sb_pub; 1252 sb_priv = sb_pub;
1140 1253
1141 memset( sb_pub, 0, sizeof(struct sb_data)); 1254 memset(sb_pub, 0, sizeof(struct sb_data));
1142 memset( sb_priv, 0, sizeof(struct sb_data)); 1255 memset(sb_priv, 0, sizeof(struct sb_data));
1143 memset( sb_out, 0, sizeof(struct sb_data)); 1256 memset(sb_out, 0, sizeof(struct sb_data));
1257 memset(sb_connect, 0, sizeof(struct sb_data));
1144 1258
1145 /* set colors for windows */ 1259 /* set colors for windows */
1146 if (has_colors()) { 1260 if (has_colors()) {
1147 wattrset (console, COLOR_PAIR (9)); 1261 if (getintoption(CF_INVWINBAR)) {
1148 wattrset (input, COLOR_PAIR (0)); 1262 wbkgd(console, COLOR_PAIR(0));
1149 wbkgd (output, COLOR_PAIR(8)); 1263 wattron(console, A_REVERSE);
1150 wbkgd (console, COLOR_PAIR (9)); 1264 } else {
1151 wbkgd (channel, COLOR_PAIR (0)); 1265 wattrset(console, COLOR_PAIR(9));
1152 wbkgd (input, COLOR_PAIR (0)); 1266 wbkgd(console, COLOR_PAIR(9));
1153 if (private) 1267 }
1154 wbkgd (private, COLOR_PAIR (0)); 1268 wattrset(input, COLOR_PAIR(0));
1155 if( topic ) { 1269 wbkgd(output, COLOR_PAIR(8));
1156 wattrset (topic, COLOR_PAIR (9)); 1270 wbkgd(channel, COLOR_PAIR(0));
1157 wbkgd (topic, COLOR_PAIR (9)); 1271 wbkgd(input, COLOR_PAIR(0));
1158 } 1272 if (private)
1273 wbkgd(private, COLOR_PAIR(0));
1274 if (topic) {
1275 if (getintoption(CF_INVWINBAR)) {
1276 wbkgd(input, COLOR_PAIR(0));
1277 wattron(topic, A_REVERSE);
1278 } else {
1279 wattrset(topic, COLOR_PAIR(9));
1280 wbkgd(topic, COLOR_PAIR(9));
1281 }
1282 }
1159 } else { 1283 } else {
1160 wattron (console, A_REVERSE); 1284 wattron(console, A_REVERSE);
1161 wattron (output, A_REVERSE); 1285 wattron(output, A_REVERSE);
1162 wbkgd(output, A_REVERSE); 1286 wbkgd(output, A_REVERSE);
1163 if( topic ) 1287 if (topic)
1164 wattron (topic, A_REVERSE); 1288 wattron(topic, A_REVERSE);
1165 } 1289 }
1166 1290
1167 /* set some options */ 1291 /* set some options */
1168 scrollok (channel, TRUE); 1292 scrollok(channel, TRUE);
1169 if (private) 1293 if (private)
1170 scrollok (private, TRUE); 1294 scrollok(private, TRUE);
1171 scrollok (input, TRUE); 1295 scrollok(input, TRUE);
1172 scrollok (output, TRUE); 1296 scrollok(output, TRUE);
1173 //idlok(channel,TRUE); 1297 // idlok(channel,TRUE);
1174 wtimeout (input, 100); 1298 wtimeout(input, 100);
1175 1299
1176 /* setup readlines display */ 1300 /* setup readlines display */
1177 /* FIXME: present only in newer readline versions 1301 /* FIXME: present only in newer readline versions
@@ -1182,87 +1306,88 @@ initui (void)
1182 rl_redisplay_function = vciredraw; 1306 rl_redisplay_function = vciredraw;
1183 1307
1184 /* get keymap, throw out unwanted binding */ 1308 /* get keymap, throw out unwanted binding */
1185 keymap = rl_get_keymap (); 1309 keymap = rl_get_keymap();
1186 rl_unbind_command_in_map ("clear-screen", keymap); 1310 rl_unbind_command_in_map("clear-screen", keymap);
1187 rl_unbind_command_in_map ("complete", keymap); 1311 rl_unbind_command_in_map("complete", keymap);
1188 rl_unbind_command_in_map ("possible-completions", keymap); 1312 rl_unbind_command_in_map("possible-completions", keymap);
1189 rl_unbind_command_in_map ("insert-completions", keymap); 1313 rl_unbind_command_in_map("insert-completions", keymap);
1190 1314
1191 /* bind CTRL-L to clearmsg() */ 1315 /* bind CTRL-L to clearmsg() */
1192 rl_bind_key ('J'-'@', (rl_command_func_t *) clearpriv); 1316 rl_bind_key('J' - '@', (rl_command_func_t *)clearpriv);
1193 rl_bind_key ('O'-'@', (rl_command_func_t *) clearchan); 1317 rl_bind_key('O' - '@', (rl_command_func_t *)clearchan);
1194 rl_bind_key ('L'-'@', (rl_command_func_t *) forceredraw); 1318 rl_bind_key('L' - '@', (rl_command_func_t *)forceredraw);
1195 rl_bind_key ('B'-'@', (rl_command_func_t *) scrollup); 1319 rl_bind_key('B' - '@', (rl_command_func_t *)scrollup);
1196 rl_bind_key ('P'-'@', (rl_command_func_t *) scrollup); 1320 rl_bind_key('P' - '@', (rl_command_func_t *)scrollup);
1197 rl_bind_key ('F'-'@', (rl_command_func_t *) scrolldown); 1321 rl_bind_key('F' - '@', (rl_command_func_t *)scrolldown);
1198 rl_bind_key ('N'-'@', (rl_command_func_t *) scrolldown); 1322 rl_bind_key('N' - '@', (rl_command_func_t *)scrolldown);
1199 rl_bind_key ('R'-'@', (rl_command_func_t *) scrollwin); 1323 rl_bind_key('R' - '@', (rl_command_func_t *)scrollwin);
1200 rl_bind_key ('T'-'@', (rl_command_func_t *) shrinkprivwin); 1324 rl_bind_key('T' - '@', (rl_command_func_t *)shrinkprivwin);
1201 rl_bind_key ('G'-'@', (rl_command_func_t *) growprivwin); 1325 rl_bind_key('G' - '@', (rl_command_func_t *)growprivwin);
1202 rl_bind_key ('X'-'@', (rl_command_func_t *) toggleprivwin); 1326 rl_bind_key('X' - '@', (rl_command_func_t *)toggleprivwin);
1203 1327
1204 rl_generic_bind (ISFUNC, "\\M-[5~", (void *)scrollup, keymap); 1328 rl_generic_bind(ISFUNC, "\\M-[5~", (void *)scrollup, keymap);
1205 rl_generic_bind (ISFUNC, "\\M-[6~", (void *)scrolldown, keymap); 1329 rl_generic_bind(ISFUNC, "\\M-[6~", (void *)scrolldown, keymap);
1206 1330
1207 /* bind TAB to menu complete from readline */ 1331 /* bind TAB to menu complete from readline */
1208 rl_bind_key ('\t', (rl_command_func_t *) rl_menu_complete); 1332 rl_bind_key('\t', (rl_command_func_t *)rl_menu_complete);
1209 1333
1210 /* application name for .inputrc - err, we don't load it */ 1334 /* application name for .inputrc - err, we don't load it */
1211 rl_readline_name = "vchat-client"; 1335 rl_readline_name = "vchat-client";
1212 1336
1213 /* set up nick completion functions .. */ 1337 /* set up nick completion functions .. */
1214 rl_ignore_completion_duplicates = 0; 1338 rl_ignore_completion_duplicates = 0;
1215 rl_attempted_completion_function = (rl_completion_func_t *) ul_complete_user; 1339 rl_attempted_completion_function = (rl_completion_func_t *)ul_complete_user;
1216 1340
1217 /* .. and 'line completed' callback */ 1341 /* .. and 'line completed' callback */
1218 rl_callback_handler_install ("", (rl_vcpfunc_t *) linecomplete); 1342 rl_callback_handler_install("", (rl_vcpfunc_t *)linecomplete);
1219 1343
1220 if( getintoption(CF_PRIVCOLLAPS) ) 1344 if (getintoption(CF_PRIVCOLLAPS))
1221 toggleprivwin(); 1345 toggleprivwin();
1222 1346
1223 resize(0); 1347 resize(0);
1224} 1348}
1225 1349
1226/* render consoleline to screen */ 1350/* render consoleline to screen */
1227void 1351void consoleline(char *message) {
1228consoleline (char *message)
1229{
1230 /* clear console, set string (or default), redraw display */ 1352 /* clear console, set string (or default), redraw display */
1231 int i; 1353 int i;
1232 ncurs_attr old_att, new_att; 1354 ncurs_attr old_att, new_att;
1233 1355
1234 togglequery(); 1356 togglequery();
1235 1357
1236 memset( &new_att, 0, sizeof(new_att)); 1358 memset(&new_att, 0, sizeof(new_att));
1237 BCOLR_SET( (&new_att), 8 ); 1359 BCOLR_SET((&new_att), 8);
1238 wmove (console, 0, 0); 1360 wmove(console, 0, 0);
1239 WATTR_GET( console, old_att); 1361 WATTR_GET(console, old_att);
1240 if(sb_pub->scroll!=sb_pub->count) WATTR_SET( console, new_att); 1362 if (sb_pub->scroll != sb_pub->count)
1363 WATTR_SET(console, new_att);
1241 1364
1242 for (i = 0; i < getmaxx(console) - 1; i++) 1365 for (i = 0; i < getmaxx(console) - 1; i++)
1243 waddch (console, ' '); 1366 waddch(console, ' ');
1244 1367
1245 if( !message && usetime ) 1368 if (!message && usetime) {
1246 { 1369 char date[10];
1247 char date[10]; 1370 time_t now = time(NULL);
1248 time_t now = time(NULL); 1371 strftime(date, sizeof(date), getformatstr(FS_CONSOLETIME), localtime(&now));
1249 strftime( date, sizeof(date), getformatstr(FS_CONSOLETIME), localtime(&now)); 1372 snprintf(tmpstr, TMPSTRSIZE, "%s%s", date, consolestr);
1250 snprintf( tmpstr, TMPSTRSIZE, "%s%s", date, consolestr); 1373 mvwaddnstr(console, 0, 0, tmpstr, getmaxx(console) - 1);
1251 mvwaddnstr (console, 0, 0, tmpstr, getmaxx(console) - 1);
1252 } else { 1374 } else {
1253 mvwaddnstr (console, 0, 0, message ? message : consolestr, getmaxx(console) - 1); 1375 mvwaddnstr(console, 0, 0, message ? message : consolestr,
1376 getmaxx(console) - 1);
1254 } 1377 }
1255 1378
1256 snprintf(tmpstr,TMPSTRSIZE,getformatstr(FS_SBINF),sb_pub->scroll,sb_pub->count); 1379 snprintf(tmpstr, TMPSTRSIZE, getformatstr(FS_SBINF), sb_pub->scroll,
1257 mvwaddstr (console, 0, getmaxx(console) - 1 - (strlen(tmpstr)-1),tmpstr); 1380 sb_pub->count);
1258 if (sb_win == 0) mvwaddch (console, 0, getmaxx(console) - 1,'*'); 1381 mvwaddstr(console, 0, getmaxx(console) - 1 - (strlen(tmpstr) - 1), tmpstr);
1382 if (sb_win == 0)
1383 mvwaddch(console, 0, getmaxx(console) - 1, '*');
1259 1384
1260 WATTR_SET( console, old_att); 1385 WATTR_SET(console, old_att);
1261 1386
1262 wnoutrefresh(console); 1387 wnoutrefresh(console);
1263 if(outputshown) { 1388 if (outputshown) {
1264 redrawwin(output); 1389 redrawwin(output);
1265 wnoutrefresh(output); 1390 wnoutrefresh(output);
1266 } 1391 }
1267 1392
1268 togglequery(); 1393 togglequery();
@@ -1271,41 +1396,41 @@ consoleline (char *message)
1271} 1396}
1272 1397
1273/* render topicline to screen */ 1398/* render topicline to screen */
1274void 1399void topicline(char *message) {
1275topicline (char *message)
1276{
1277 int i; 1400 int i;
1278 ncurs_attr old_att, new_att; 1401 ncurs_attr old_att, new_att;
1279 1402
1280 if( !topic ) 1403 if (!topic)
1281 return; 1404 return;
1282 1405
1283 togglequery(); 1406 togglequery();
1284 1407
1285 memset( &new_att, 0, sizeof(new_att)); 1408 memset(&new_att, 0, sizeof(new_att));
1286 BCOLR_SET( (&new_att), 8 ); 1409 BCOLR_SET((&new_att), 8);
1287 1410
1288 /* clear topic, set string (or default), redraw display */ 1411 /* clear topic, set string (or default), redraw display */
1289 wmove (topic, 0, 0); 1412 wmove(topic, 0, 0);
1290 1413
1291 WATTR_GET( topic, old_att); 1414 WATTR_GET(topic, old_att);
1292 if( private && (sb_priv->scroll!=sb_priv->count)) 1415 if (private && (sb_priv->scroll != sb_priv->count))
1293 WATTR_SET( topic, new_att); 1416 WATTR_SET(topic, new_att);
1294 1417
1295 for (i = 0; i < getmaxx(topic) - 1; i++) 1418 for (i = 0; i < getmaxx(topic) - 1; i++)
1296 waddch (topic, ' '); 1419 waddch(topic, ' ');
1297 mvwaddnstr (topic, 0, 0, message ? message : topicstr, getmaxx(topic) - 1); 1420 mvwaddnstr(topic, 0, 0, message ? message : topicstr, getmaxx(topic) - 1);
1298 if (private) { 1421 if (private) {
1299 snprintf(tmpstr,TMPSTRSIZE,getformatstr(FS_SBINF),sb_priv->scroll,sb_priv->count); 1422 snprintf(tmpstr, TMPSTRSIZE, getformatstr(FS_SBINF), sb_priv->scroll,
1300 mvwaddstr (topic, 0, getmaxx(topic) - 1 - (strlen(tmpstr)-1),tmpstr); 1423 sb_priv->count);
1301 if (sb_win == 1) mvwaddch (topic, 0, getmaxx(topic) - 1,'*'); 1424 mvwaddstr(topic, 0, getmaxx(topic) - 1 - (strlen(tmpstr) - 1), tmpstr);
1425 if (sb_win == 1)
1426 mvwaddch(topic, 0, getmaxx(topic) - 1, '*');
1302 } 1427 }
1303 WATTR_SET( topic, old_att); 1428 WATTR_SET(topic, old_att);
1304 1429
1305 wnoutrefresh(topic); 1430 wnoutrefresh(topic);
1306 if(outputshown) { 1431 if (outputshown) {
1307 redrawwin(output); 1432 redrawwin(output);
1308 wnoutrefresh(output); 1433 wnoutrefresh(output);
1309 } 1434 }
1310 1435
1311 togglequery(); 1436 togglequery();
@@ -1314,23 +1439,19 @@ topicline (char *message)
1314} 1439}
1315 1440
1316/* end userinterface */ 1441/* end userinterface */
1317void 1442void exitui(void) {
1318exitui (void)
1319{
1320 if (ui_init) { 1443 if (ui_init) {
1321 rl_callback_handler_remove (); 1444 rl_callback_handler_remove();
1322 endwin (); 1445 endwin();
1323 ui_init = 0; 1446 ui_init = 0;
1324 } 1447 }
1325} 1448}
1326 1449
1327/* prompt for a nick */ 1450/* prompt for a nick */
1328/* FIXME: must not be called when used rl_callback_read_char()/userinput() 1451/* FIXME: must not be called when used rl_callback_read_char()/userinput()
1329 * before */ 1452 * before */
1330void 1453void nickprompt(void) {
1331nickprompt (void) 1454 char *newnick = 0;
1332{
1333 char * newnick = 0;
1334 1455
1335 if (own_nick_get()) 1456 if (own_nick_get())
1336 return; 1457 return;
@@ -1341,15 +1462,15 @@ nickprompt (void)
1341 newnick = readline(""); 1462 newnick = readline("");
1342 1463
1343 own_nick_set(newnick); 1464 own_nick_set(newnick);
1344 setstroption(CF_NICK,newnick); 1465 setstroption(CF_NICK, newnick);
1345 1466
1346 /* try to get readlines stats clean again */ 1467 /* try to get readlines stats clean again */
1347 //rl_free_line_state (); 1468 // rl_free_line_state ();
1348 memset( rl_line_buffer, 0, rl_end ); 1469 memset(rl_line_buffer, 0, rl_end);
1349 rl_point = rl_end = rl_done = 0; 1470 rl_point = rl_end = rl_done = 0;
1350 1471
1351 /* wipe input line and reset cursor */ 1472 /* wipe input line and reset cursor */
1352 rl_kill_full_line(0,0); 1473 rl_kill_full_line(0, 0);
1353 wclear(input); 1474 wclear(input);
1354 1475
1355 /* reset consoleline */ 1476 /* reset consoleline */
@@ -1357,20 +1478,18 @@ nickprompt (void)
1357} 1478}
1358 1479
1359/* special callback for readline, doesn't show the characters */ 1480/* special callback for readline, doesn't show the characters */
1360static void 1481static void vcnredraw(void) {
1361vcnredraw (void)
1362{
1363 int i; 1482 int i;
1364 char *passbof="-*-*-*-*-*-*-"; 1483 char *passbof = "-*-*-*-*-*-*-";
1365 1484
1366 /* wipe input line and reset cursor */ 1485 /* wipe input line and reset cursor */
1367 wmove(input, 0, 0); 1486 wmove(input, 0, 0);
1368 for (i = 0; i < getmaxx(input) - 1; i++) 1487 for (i = 0; i < getmaxx(input) - 1; i++)
1369 waddch(input, ' '); 1488 waddch(input, ' ');
1370 wmove(input, 0, 0); 1489 wmove(input, 0, 0);
1371 1490
1372 /* draw as many stars as there are characters */ 1491 /* draw as many stars as there are characters */
1373 mvwaddnstr(input, 0, 0, &passbof[rl_point%2], 12); 1492 mvwaddnstr(input, 0, 0, &passbof[rl_point % 2], 12);
1374 wmove(input, 0, getmaxx(input) - 1); 1493 wmove(input, 0, getmaxx(input) - 1);
1375 wrefresh(input); 1494 wrefresh(input);
1376} 1495}
@@ -1378,11 +1497,11 @@ vcnredraw (void)
1378/* passphrase callback for OpenSSL */ 1497/* passphrase callback for OpenSSL */
1379/* FIXME: must not be called when used rl_callback_read_char()/userinput() 1498/* FIXME: must not be called when used rl_callback_read_char()/userinput()
1380 * before */ 1499 * before */
1381int 1500int passprompt(char *buf, int size, int rwflag, void *userdata) {
1382passprompt (char *buf, int size, int rwflag, void *userdata)
1383{
1384 int i; 1501 int i;
1385 char *passphrase = NULL; 1502 char *passphrase = NULL;
1503 (void)rwflag;
1504 (void)userdata;
1386 1505
1387 /* use special non-revealing redraw function */ 1506 /* use special non-revealing redraw function */
1388 /* FIXME: passphrase isn't protected against e.g. swapping */ 1507 /* FIXME: passphrase isn't protected against e.g. swapping */
@@ -1390,45 +1509,43 @@ passprompt (char *buf, int size, int rwflag, void *userdata)
1390 1509
1391 /* prompt user for non-empty passphrase */ 1510 /* prompt user for non-empty passphrase */
1392 consoleline("Please enter PEM passphrase for private key:"); 1511 consoleline("Please enter PEM passphrase for private key:");
1393 while (!passphrase || !passphrase[0]) 1512 while (!passphrase || !passphrase[0]) {
1394 { 1513 if (passphrase)
1395 if (passphrase) 1514 free(passphrase);
1396 free (passphrase); 1515 passphrase = readline("");
1397 passphrase = readline (""); 1516 }
1398 }
1399 1517
1400 /* reset redrawing function to default, reset consoleline */ 1518 /* reset redrawing function to default, reset consoleline */
1401 rl_redisplay_function = vciredraw; 1519 rl_redisplay_function = vciredraw;
1402 consoleline(NULL); 1520 consoleline(NULL);
1403 1521
1404 /* copy passphrase to buffer */ 1522 /* copy passphrase to buffer */
1405 strncpy (buf, passphrase, size); 1523 strncpy(buf, passphrase, size);
1406 1524
1407 /* try to get readlines stats clean again */ 1525 /* try to get readlines stats clean again */
1408 //rl_free_line_state (); 1526 // rl_free_line_state ();
1409 memset( rl_line_buffer, 0, rl_end ); 1527 memset(rl_line_buffer, 0, rl_end);
1410 rl_point = rl_end = rl_done = 0; 1528 rl_point = rl_end = rl_done = 0;
1411 1529
1412 /* wipe input line and reset cursor */ 1530 /* wipe input line and reset cursor */
1413 wmove (input, 0, 0); 1531 wmove(input, 0, 0);
1414 for (i = 0; i < getmaxx(input) - 1; i++) 1532 for (i = 0; i < getmaxx(input) - 1; i++)
1415 waddch (input, ' '); 1533 waddch(input, ' ');
1416 wmove (input, 0, 0); 1534 wmove(input, 0, 0);
1417 wrefresh (input); 1535 wrefresh(input);
1418 1536
1419 /* return passphrase to OpenSSL */ 1537 /* return passphrase to OpenSSL */
1420 return strlen (buf); 1538 return strlen(buf);
1421} 1539}
1422 1540
1423/* Filter stuff */ 1541/* Filter stuff */
1424static int 1542static int check_valid_colour(char colour) {
1425check_valid_colour( char colour ) { 1543 return !((colour != '-') && (colour != '+') &&
1426 return !( (colour !='-')&&(colour !='+') && (colour < '0' || colour > '9') && 1544 (colour < '0' || colour > '9') &&
1427 (colour < 'A' || colour > 'Z' || !attributes[ colour-'A' ]) && 1545 (colour < 'A' || colour > 'Z' || !attributes[colour - 'A']) &&
1428 (colour < 'a' || colour > 'z' || !attributes[ colour-'a' ])); 1546 (colour < 'a' || colour > 'z' || !attributes[colour - 'a']));
1429} 1547}
1430 1548
1431
1432/* scans filterlist and removes possible matches 1549/* scans filterlist and removes possible matches
1433 test functions may return: 1550 test functions may return:
1434 RMFILTER_RMANDCONT 1551 RMFILTER_RMANDCONT
@@ -1437,101 +1554,101 @@ check_valid_colour( char colour ) {
1437 RMFILTER_KEEPANDSTOP 1554 RMFILTER_KEEPANDSTOP
1438 returns number of removed entries 1555 returns number of removed entries
1439*/ 1556*/
1440static int 1557static int removefromfilterlist(int (*test)(filt *flt, void *data, char colour),
1441removefromfilterlist( int(*test)(filt *flt, void *data, char colour), void *data, char colour) { 1558 void *data, char colour) {
1442 filt **flt = &filterlist, *tmp; 1559 filt **flt = &filterlist, *tmp;
1443 int removed = 0, stop = 0; 1560 int removed = 0, stop = 0;
1444 1561
1445 while( *flt && !stop ) { 1562 while (*flt && !stop) {
1446 switch( test( *flt, data, colour ) ) { 1563 switch (test(*flt, data, colour)) {
1447 case RMFILTER_RMANDSTOP: /* remove */ 1564 case RMFILTER_RMANDSTOP: /* remove */
1448 stop = 1; 1565 stop = 1;
1449 case RMFILTER_RMANDCONT: 1566 case RMFILTER_RMANDCONT:
1450 snprintf( tmpstr, TMPSTRSIZE, " Removed ID: [% 3d] Color: [%c] Regex: [%s] ", (*flt)->id, (*flt)->colour, (*flt)->text); 1567 snprintf(tmpstr, TMPSTRSIZE,
1451 writeout(tmpstr); 1568 " Removed ID: [% 3d] Color: [%c] Regex: [%s] ", (*flt)->id,
1452 /* Release regex.h resources */ 1569 (*flt)->colour, (*flt)->text);
1453 regfree( &((*flt)->regex)); 1570 writeout(tmpstr);
1454 /* free ASCII text memory */ 1571 /* Release regex.h resources */
1455 free( (*flt)->text); 1572 regfree(&((*flt)->regex));
1456 /* unlink from list */ 1573 /* free ASCII text memory */
1457 tmp = *flt; 1574 free((*flt)->text);
1458 *flt = (*flt)->next; 1575 /* unlink from list */
1459 /* free filter block itself */ 1576 tmp = *flt;
1460 free( tmp ); 1577 *flt = (*flt)->next;
1461 /* reflect changes on whole screen */ 1578 /* free filter block itself */
1462 removed++; 1579 free(tmp);
1463 break; 1580 /* reflect changes on whole screen */
1464 case RMFILTER_KEEPANDSTOP: /* don't remove but stop scanning */ 1581 removed++;
1465 stop = 1; 1582 break;
1466 break; 1583 case RMFILTER_KEEPANDSTOP: /* don't remove but stop scanning */
1467 default: 1584 stop = 1;
1468 /* advance in list */ 1585 break;
1469 if( *flt ) flt = &((*flt)->next); 1586 default:
1470 break; 1587 /* advance in list */
1471 } 1588 if (*flt)
1589 flt = &((*flt)->next);
1590 break;
1591 }
1472 } 1592 }
1473 /* return number of removed items */ 1593 /* return number of removed items */
1474 return removed; 1594 return removed;
1475} 1595}
1476 1596
1477static int 1597static int test_clear(filt *flt, void *data, char c) {
1478test_clear( filt *flt, void *data, char c ) { 1598 (void)data;
1479 if( !c || ( c == flt->colour ) || ( (c == '*') && (flt->colour != '-') && (flt->colour != '+') ) ) 1599 if (!c || (c == flt->colour) ||
1480 return RMFILTER_RMANDCONT; 1600 ((c == '*') && (flt->colour != '-') && (flt->colour != '+')))
1601 return RMFILTER_RMANDCONT;
1481 else 1602 else
1482 return RMFILTER_KEEPANDCONT; 1603 return RMFILTER_KEEPANDCONT;
1483} 1604}
1484 1605
1485static int 1606static int test_simplerm(filt *flt, void *data, char colour) {
1486test_simplerm( filt *flt, void *data, char colour) { 1607 if (!strcmp(flt->text, (char *)data))
1487 if( !strcmp( flt->text, (char*)data)) 1608 return test_clear(flt, NULL, colour);
1488 return test_clear(flt, NULL, colour);
1489 else 1609 else
1490 return RMFILTER_KEEPANDCONT; 1610 return RMFILTER_KEEPANDCONT;
1491} 1611}
1492 1612
1493static int 1613static int test_numericrm(filt *flt, void *data, char colour) {
1494test_numericrm( filt *flt, void *data, char colour) { 1614 if (flt->id == (long)data)
1495 if( flt->id == (long)data) 1615 return test_clear(flt, NULL, colour);
1496 return test_clear(flt, NULL, colour);
1497 else 1616 else
1498 return RMFILTER_KEEPANDCONT; 1617 return RMFILTER_KEEPANDCONT;
1499} 1618}
1500 1619
1501/* clears filter list */ 1620/* clears filter list */
1502void 1621void clearfilters(char colour) {
1503clearfilters( char colour ) { 1622 flushout();
1504 flushout( ); 1623 if (removefromfilterlist(test_clear, NULL, colour)) {
1505 if( removefromfilterlist( test_clear, NULL, colour ) ) { 1624 /* There actually WERE items removed */
1506 /* There actually WERE items removed */ 1625 filtertype = analyzefilters();
1507 filtertype = analyzefilters( );
1508 } else { 1626 } else {
1509 writeout(" No matches on filter list. "); 1627 writeout(" No matches on filter list. ");
1510 } 1628 }
1511 showout(); 1629 showout();
1512} 1630}
1513 1631
1514/* removes filter pattern */ 1632/* removes filter pattern */
1515void 1633void removefilter(char *tail) {
1516removefilter( char *tail ) {
1517 int rmv = 0, val; 1634 int rmv = 0, val;
1518 char* end; 1635 char *end;
1519 1636
1520 flushout( ); 1637 flushout();
1521 1638
1522 rmv = removefromfilterlist( test_simplerm, (void *)tail, 0 ); 1639 rmv = removefromfilterlist(test_simplerm, (void *)tail, 0);
1523 if(!rmv) { 1640 if (!rmv) {
1524 val = strtol(tail, &end, 10); 1641 val = strtol(tail, &end, 10);
1525 if( (tail != end) && (!*end) ) 1642 if ((tail != end) && (!*end))
1526 rmv = removefromfilterlist( test_numericrm, (void *)(uintptr_t)val, 0); 1643 rmv = removefromfilterlist(test_numericrm, (void *)(uintptr_t)val, 0);
1527 } 1644 }
1528 1645
1529 if( rmv ) { 1646 if (rmv) {
1530 /* There actually WERE items removed */ 1647 /* There actually WERE items removed */
1531 filtertype = analyzefilters( ); 1648 filtertype = analyzefilters();
1532 } else { 1649 } else {
1533 snprintf( tmpstr, TMPSTRSIZE, " Not on filter list: %s ", tail); 1650 snprintf(tmpstr, TMPSTRSIZE, " Not on filter list: %s ", tail);
1534 writeout( tmpstr ); 1651 writeout(tmpstr);
1535 } 1652 }
1536 showout(); 1653 showout();
1537} 1654}
@@ -1539,139 +1656,158 @@ removefilter( char *tail ) {
1539static unsigned int uniqueidpool = 1; 1656static unsigned int uniqueidpool = 1;
1540 1657
1541/* returns unique id for filter pattern or 0 for failure */ 1658/* returns unique id for filter pattern or 0 for failure */
1542unsigned int 1659unsigned int addfilter(char colour, char *regex) {
1543addfilter( char colour, char *regex ) { 1660 filt *newflt = malloc(sizeof(filt)), **flt = &filterlist;
1544 filt *newflt = malloc( sizeof(filt)), **flt = &filterlist;
1545 1661
1546 if( !newflt ) return 0; 1662 if (!newflt)
1547 flushout( ); 1663 return 0;
1664 flushout();
1548 1665
1549 /* check colour validity */ 1666 /* check colour validity */
1550 if( !check_valid_colour( colour ) ){ 1667 if (!check_valid_colour(colour)) {
1551 free( newflt ); 1668 free(newflt);
1552 writeout( " Not a valid colour code. " ); 1669 writeout(" Not a valid colour code. ");
1553 showout( ); 1670 showout();
1554 return 0; 1671 return 0;
1555 } 1672 }
1556 1673
1557 if( regcomp( &newflt->regex, regex, REG_ICASE | REG_EXTENDED | REG_NEWLINE) ) { 1674 if (regcomp(&newflt->regex, regex, REG_ICASE | REG_EXTENDED | REG_NEWLINE)) {
1558 /* couldn't compile regex ... print error, return */ 1675 /* couldn't compile regex ... print error, return */
1559 free( newflt ); 1676 free(newflt);
1560 1677
1561 snprintf( tmpstr, TMPSTRSIZE, " %s ", regex); 1678 snprintf(tmpstr, TMPSTRSIZE, " %s ", regex);
1562 writeout( " Bad regular expression: "); 1679 writeout(" Bad regular expression: ");
1563 writeout( tmpstr ); 1680 writeout(tmpstr);
1564 showout( ); 1681 showout();
1565 return 0; 1682 return 0;
1566 } else { 1683 } else {
1567 int len = strlen(regex) + 1; 1684 int len = strlen(regex) + 1;
1568 /* grab id from ID pool an increase free ID counter */ 1685 /* grab id from ID pool an increase free ID counter */
1569 newflt->id = uniqueidpool++; 1686 newflt->id = uniqueidpool++;
1570 newflt->colour = colour; 1687 newflt->colour = colour;
1571 newflt->next = NULL; 1688 newflt->next = NULL;
1572 /* take a copy of plain regex text for later identification by user */ 1689 /* take a copy of plain regex text for later identification by user */
1573 newflt->text = malloc( len ); 1690 newflt->text = malloc(len);
1574 memcpy( newflt->text, regex, len ); 1691 memcpy(newflt->text, regex, len);
1575 } 1692 }
1576 1693
1577 /* append new filter to filterlist */ 1694 /* append new filter to filterlist */
1578 while( *flt ) flt=&((*flt)->next); 1695 while (*flt)
1696 flt = &((*flt)->next);
1579 *flt = newflt; 1697 *flt = newflt;
1580 1698
1581 filtertype = analyzefilters( ); 1699 filtertype = analyzefilters();
1582 1700
1583 if ( colour == '-' ) { 1701 if (colour == '-') {
1584 snprintf( tmpstr, TMPSTRSIZE, " \"%s\" successfully added to ignorance list. ( ID = %d). ", (*flt)->text, (*flt)->id); 1702 snprintf(tmpstr, TMPSTRSIZE,
1585 } else if( colour == '+' ) { 1703 " \"%s\" successfully added to ignorance list. ( ID = %d). ",
1586 snprintf( tmpstr, TMPSTRSIZE, " \"%s\" successfully added to zoom list. ( ID = %d). ", (*flt)->text, (*flt)->id); 1704 (*flt)->text, (*flt)->id);
1705 } else if (colour == '+') {
1706 snprintf(tmpstr, TMPSTRSIZE,
1707 " \"%s\" successfully added to zoom list. ( ID = %d). ",
1708 (*flt)->text, (*flt)->id);
1587 } else { 1709 } else {
1588 snprintf( tmpstr, TMPSTRSIZE, " \"%s\" successfully added to hilitelist. (ID = %d). ", (*flt)->text, (*flt)->id); 1710 snprintf(tmpstr, TMPSTRSIZE,
1711 " \"%s\" successfully added to hilitelist. (ID = %d). ",
1712 (*flt)->text, (*flt)->id);
1589 } 1713 }
1590 writeout(tmpstr ); 1714 writeout(tmpstr);
1591 showout( ); 1715 showout();
1592 1716
1593 return newflt->id; 1717 return newflt->id;
1594} 1718}
1595 1719
1596void 1720void listfilters(void) {
1597listfilters( void ) { 1721 filt *flt = filterlist;
1598 filt *flt = filterlist; 1722 int shownhi = 0, shownign = 0, shownzoom = 0;
1599 int shownhi = 0, shownign = 0, shownzoom = 0;
1600 1723
1601 flushout( ); 1724 flushout();
1602 1725
1603 while( flt ) { 1726 while (flt) {
1604 if( (flt->colour != '-') && (flt->colour != '+')) { 1727 if ((flt->colour != '-') && (flt->colour != '+')) {
1605 if(!shownhi) { 1728 if (!shownhi) {
1606 writeout(" Your hilites:"); 1729 writeout(" Your hilites:");
1607 shownhi = 1; 1730 shownhi = 1;
1608 }
1609 snprintf( tmpstr, TMPSTRSIZE, " ID: [% 3d] Color: [%c] Regex: [%s]", flt->id, flt->colour, flt->text);
1610 writeout( tmpstr );
1611 } 1731 }
1612 flt = flt->next; 1732 snprintf(tmpstr, TMPSTRSIZE, " ID: [% 3d] Color: [%c] Regex: [%s]",
1733 flt->id, flt->colour, flt->text);
1734 writeout(tmpstr);
1735 }
1736 flt = flt->next;
1613 } 1737 }
1614 1738
1615 flt = filterlist; 1739 flt = filterlist;
1616 1740
1617 while( flt ) { 1741 while (flt) {
1618 if( flt->colour == '-') { 1742 if (flt->colour == '-') {
1619 if(!shownign) { 1743 if (!shownign) {
1620 if(shownhi) writeout(" "); 1744 if (shownhi)
1621 writeout(" You do ignore:"); 1745 writeout(" ");
1622 shownign = 1; 1746 writeout(" You do ignore:");
1623 } 1747 shownign = 1;
1624 snprintf( tmpstr, TMPSTRSIZE, " ID: [% 3d] Regex: [%s]", flt->id, flt->text);
1625 writeout( tmpstr );
1626 } 1748 }
1627 flt = flt->next; 1749 snprintf(tmpstr, TMPSTRSIZE, " ID: [% 3d] Regex: [%s]",
1750 flt->id, flt->text);
1751 writeout(tmpstr);
1752 }
1753 flt = flt->next;
1628 } 1754 }
1629 1755
1630 flt = filterlist; 1756 flt = filterlist;
1631 1757
1632 while( flt ) { 1758 while (flt) {
1633 if( flt->colour == '+') { 1759 if (flt->colour == '+') {
1634 if(!shownzoom) { 1760 if (!shownzoom) {
1635 if(shownhi || shownign) writeout(" "); 1761 if (shownhi || shownign)
1636 writeout(" On your whitelist:"); 1762 writeout(" ");
1637 shownzoom = 1; 1763 writeout(" On your whitelist:");
1638 } 1764 shownzoom = 1;
1639 snprintf( tmpstr, TMPSTRSIZE, " ID: [% 3d] Regex: [%s]", flt->id, flt->text);
1640 writeout( tmpstr );
1641 } 1765 }
1642 flt = flt->next; 1766 snprintf(tmpstr, TMPSTRSIZE, " ID: [% 3d] Regex: [%s]",
1767 flt->id, flt->text);
1768 writeout(tmpstr);
1769 }
1770 flt = flt->next;
1643 } 1771 }
1644 1772
1645 if( !shownign && !shownhi && !shownzoom) { 1773 if (!shownign && !shownhi && !shownzoom) {
1646 writeout(" No entries on your filter list. "); 1774 writeout(" No entries on your filter list. ");
1647 } 1775 }
1648 showout(); 1776 showout();
1649} 1777}
1650 1778
1651void 1779void handlequery(char *tail) {
1652handlequery( char *tail ) { 1780 if (*tail) {
1653 if( *tail ) {
1654 // ".m %s " -> string + 4 1781 // ".m %s " -> string + 4
1655 if( querypartner && private ) { 1782 if (querypartner && private) {
1656 WINDOW *tmp= private; private = channel; channel = tmp; 1783 WINDOW *tmp = private;
1784 private
1785 = channel;
1786 channel = tmp;
1657 } 1787 }
1658 querypartner = (char *)realloc( querypartner, 5 + strlen( tail )); 1788 querypartner = (char *)realloc(querypartner, 5 + strlen(tail));
1659 if( querypartner ) { 1789 if (querypartner) {
1660 snprintf( querypartner, 5 + strlen( tail ), ".m %s ", tail ); 1790 snprintf(querypartner, 5 + strlen(tail), ".m %s ", tail);
1661 if( private ) { 1791 if (private) {
1662 WINDOW *tmp= private; private = channel; channel = tmp; 1792 WINDOW *tmp = private;
1793 private
1794 = channel;
1795 channel = tmp;
1663 } 1796 }
1664 } 1797 }
1665 resize( 0 ); 1798 resize(0);
1666 } else { 1799 } else {
1667 // QUERY ends 1800 // QUERY ends
1668 if( querypartner ) { 1801 if (querypartner) {
1669 free( querypartner ); 1802 free(querypartner);
1670 querypartner = NULL; 1803 querypartner = NULL;
1671 if( private ) { 1804 if (private) {
1672 WINDOW *tmp= private; private = channel; channel = tmp; 1805 WINDOW *tmp = private;
1806 private
1807 = channel;
1808 channel = tmp;
1673 } 1809 }
1674 resize( 0 ); 1810 resize(0);
1675 } 1811 }
1676 } 1812 }
1677} 1813}