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