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