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