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