Mercurial > hg
annotate mcabber/src/screen.c @ 453:39e173645f9c
External command is called for MUC messages
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Mon, 26 Sep 2005 22:36:18 +0200 |
parents | 03bb57383cea |
children | 8827bbef84a1 |
rev | line source |
---|---|
307 | 1 /* |
2 * screen.c -- UI stuff | |
393 | 3 * |
307 | 4 * Copyright (C) 2005 Mikael Berthe <bmikael@lists.lilotux.net> |
5 * Parts of this file come from the Cabber project <cabber@ajmacias.com> | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or (at | |
10 * your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | |
20 * USA | |
21 */ | |
22 | |
24 | 23 #include <stdio.h> |
24 #include <stdlib.h> | |
25 #include <string.h> | |
26 #include <ncurses.h> | |
27 #include <panel.h> | |
28 #include <time.h> | |
29 #include <ctype.h> | |
30 #include <locale.h> | |
232 | 31 #include <langinfo.h> |
24 | 32 |
33 #include "screen.h" | |
81 | 34 #include "hbuf.h" |
47 | 35 #include "commands.h" |
95 | 36 #include "compl.h" |
81 | 37 #include "roster.h" |
180 | 38 #include "histolog.h" |
279
f5dd437c057b
Rewrite the settings system
Mikael Berthe <mikael@lilotux.net>
parents:
276
diff
changeset
|
39 #include "settings.h" |
81 | 40 #include "utils.h" |
24 | 41 #include "list.h" |
42 | |
43 #define window_entry(n) list_entry(n, window_entry_t, list) | |
44 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
45 static inline void check_offset(int); |
151 | 46 |
24 | 47 LIST_HEAD(window_list); |
48 | |
49 typedef struct _window_entry_t { | |
50 WINDOW *win; | |
108 | 51 PANEL *panel; |
52 char *name; | |
53 GList *hbuf; | |
181 | 54 GList *top; // If top is NULL, we'll display the last lines |
55 char cleared; // For ex, user has issued a /clear command... | |
24 | 56 struct list_head list; |
57 } window_entry_t; | |
58 | |
59 | |
60 static WINDOW *rosterWnd, *chatWnd, *inputWnd; | |
61 static WINDOW *logWnd, *logWnd_border; | |
62 static PANEL *rosterPanel, *chatPanel, *inputPanel; | |
63 static PANEL *logPanel, *logPanel_border; | |
64 static int maxY, maxX; | |
65 static window_entry_t *currentWindow; | |
66 | |
67 static int chatmode; | |
238 | 68 static int multimode; |
69 static char *multiline; | |
30 | 70 int update_roster; |
232 | 71 int utf8_mode = 0; |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
72 static bool Autoaway; |
332
a1901741890e
scr_LogPrint() can be called before ncurses initialization
Mikael Berthe <mikael@lilotux.net>
parents:
330
diff
changeset
|
73 static bool Curses; |
24 | 74 |
174 | 75 static char inputLine[INPUTLINE_LENGTH+1]; |
76 static char *ptr_inputline; | |
77 static short int inputline_offset; | |
78 static int completion_started; | |
173 | 79 static GList *cmdhisto; |
80 static GList *cmdhisto_cur; | |
174 | 81 static char cmdhisto_backup[INPUTLINE_LENGTH+1]; |
24 | 82 |
83 | |
99 | 84 /* Functions */ |
24 | 85 |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
86 static int scr_WindowWidth(WINDOW * win) |
24 | 87 { |
88 int x, y; | |
89 getmaxyx(win, y, x); | |
90 return x; | |
91 } | |
92 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
93 static void scr_draw_box(WINDOW * win, int y, int x, int height, int width, |
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
94 int Color, chtype box, chtype border) |
24 | 95 { |
96 int i, j; | |
97 | |
98 wattrset(win, COLOR_PAIR(Color)); | |
99 for (i = 0; i < height; i++) { | |
100 wmove(win, y + i, x); | |
101 for (j = 0; j < width; j++) | |
102 if (!i && !j) | |
103 waddch(win, border | ACS_ULCORNER); | |
104 else if (i == height - 1 && !j) | |
105 waddch(win, border | ACS_LLCORNER); | |
106 else if (!i && j == width - 1) | |
107 waddch(win, box | ACS_URCORNER); | |
108 else if (i == height - 1 && j == width - 1) | |
109 waddch(win, box | ACS_LRCORNER); | |
110 else if (!i) | |
111 waddch(win, border | ACS_HLINE); | |
112 else if (i == height - 1) | |
113 waddch(win, box | ACS_HLINE); | |
114 else if (!j) | |
115 waddch(win, border | ACS_VLINE); | |
116 else if (j == width - 1) | |
117 waddch(win, box | ACS_VLINE); | |
118 else | |
119 waddch(win, box | ' '); | |
120 } | |
121 } | |
122 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
123 static int FindColor(const char *name) |
24 | 124 { |
125 if (!strcmp(name, "default")) | |
126 return -1; | |
127 if (!strcmp(name, "black")) | |
128 return COLOR_BLACK; | |
129 if (!strcmp(name, "red")) | |
130 return COLOR_RED; | |
131 if (!strcmp(name, "green")) | |
132 return COLOR_GREEN; | |
133 if (!strcmp(name, "yellow")) | |
134 return COLOR_YELLOW; | |
135 if (!strcmp(name, "blue")) | |
136 return COLOR_BLUE; | |
137 if (!strcmp(name, "magenta")) | |
138 return COLOR_MAGENTA; | |
139 if (!strcmp(name, "cyan")) | |
140 return COLOR_CYAN; | |
141 if (!strcmp(name, "white")) | |
142 return COLOR_WHITE; | |
143 | |
144 return -1; | |
145 } | |
146 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
147 static void ParseColors(void) |
24 | 148 { |
281
f562b9af2de7
Add "const" specifier in prototypes
Mikael Berthe <mikael@lilotux.net>
parents:
279
diff
changeset
|
149 const char *colors[8] = { |
24 | 150 "", "", |
267 | 151 "general", |
139 | 152 "newmsg", |
267 | 153 "rosterselect", |
154 "rosternormal", | |
24 | 155 NULL |
156 }; | |
157 | |
158 char *tmp = malloc(1024); | |
281
f562b9af2de7
Add "const" specifier in prototypes
Mikael Berthe <mikael@lilotux.net>
parents:
279
diff
changeset
|
159 const char *color; |
f562b9af2de7
Add "const" specifier in prototypes
Mikael Berthe <mikael@lilotux.net>
parents:
279
diff
changeset
|
160 const char *background = settings_opt_get("color_background"); |
f562b9af2de7
Add "const" specifier in prototypes
Mikael Berthe <mikael@lilotux.net>
parents:
279
diff
changeset
|
161 const char *backselected = settings_opt_get("color_backselected"); |
24 | 162 int i = 0; |
163 | |
267 | 164 // Default values |
165 if (!background) background = "blue"; | |
166 if (!backselected) backselected = "cyan"; | |
167 | |
24 | 168 while (colors[i]) { |
169 sprintf(tmp, "color_%s", colors[i]); | |
279
f5dd437c057b
Rewrite the settings system
Mikael Berthe <mikael@lilotux.net>
parents:
276
diff
changeset
|
170 color = settings_opt_get(tmp); |
24 | 171 |
172 switch (i + 1) { | |
173 case 1: | |
174 init_pair(1, COLOR_BLACK, COLOR_WHITE); | |
175 break; | |
176 case 2: | |
177 init_pair(2, COLOR_WHITE, COLOR_BLACK); | |
178 break; | |
179 case 3: | |
267 | 180 init_pair(3, ((color) ? FindColor(color) : COLOR_WHITE), |
181 FindColor(background)); | |
24 | 182 break; |
183 case 4: | |
267 | 184 init_pair(4, ((color) ? FindColor(color) : COLOR_RED), |
185 FindColor(background)); | |
24 | 186 break; |
187 case 5: | |
267 | 188 init_pair(5, ((color) ? FindColor(color) : COLOR_BLACK), |
189 FindColor(backselected)); | |
24 | 190 break; |
191 case 6: | |
267 | 192 init_pair(6, ((color) ? FindColor(color) : COLOR_MAGENTA), |
193 FindColor(background)); | |
24 | 194 break; |
195 } | |
196 i++; | |
197 } | |
198 } | |
199 | |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
200 void scr_InitCurses(void) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
201 { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
202 initscr(); |
382
4c6e8392e465
Use nodelay() instead of halfdelay()
Mikael Berthe <mikael@lilotux.net>
parents:
374
diff
changeset
|
203 raw(); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
204 noecho(); |
389
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
205 nonl(); |
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
206 intrflush(stdscr, FALSE); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
207 start_color(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
208 use_default_colors(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
209 Curses = TRUE; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
210 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
211 ParseColors(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
212 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
213 getmaxyx(stdscr, maxY, maxX); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
214 if (maxY < LOG_WIN_HEIGHT+2) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
215 maxY = LOG_WIN_HEIGHT+2; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
216 inputLine[0] = 0; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
217 ptr_inputline = inputLine; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
218 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
219 setlocale(LC_CTYPE, ""); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
220 utf8_mode = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
221 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
222 return; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
223 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
224 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
225 void scr_TerminateCurses(void) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
226 { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
227 if (!Curses) return; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
228 clear(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
229 refresh(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
230 endwin(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
231 Curses = FALSE; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
232 return; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
233 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
234 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
235 // scr_LogPrint(...) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
236 // Display a message in the log window. |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
237 void scr_LogPrint(unsigned int flag, const char *fmt, ...) |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
238 { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
239 time_t timestamp; |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
240 char *buffer, *b2; |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
241 va_list ap; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
242 |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
243 if (!flag) return; |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
244 |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
245 do { |
412
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
246 buffer = (char *) malloc(1088); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
247 } while (!buffer); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
248 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
249 timestamp = time(NULL); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
250 strftime(buffer, 64, "[%H:%M:%S] ", localtime(×tamp)); |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
251 for (b2 = buffer ; *b2 ; b2++) |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
252 ; |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
253 va_start(ap, fmt); |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
254 vsnprintf(b2, 1024, fmt, ap); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
255 va_end(ap); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
256 |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
257 if (flag & LPRINT_NORMAL) { |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
258 if (Curses) { |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
259 wprintw(logWnd, "\n%s", buffer); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
260 update_panels(); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
261 doupdate(); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
262 } else { |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
263 printf("%s\n", buffer); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
264 } |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
265 } |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
266 if (flag & (LPRINT_LOG|LPRINT_DEBUG)) { |
412
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
267 char *buffer2 = malloc(1088); |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
268 |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
269 if (buffer2) { |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
270 strftime(buffer2, 23, "[%Y-%m-%d %H:%M:%S] ", localtime(×tamp)); |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
271 strcat(buffer2, b2); |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
272 } else { |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
273 buffer2 = buffer; |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
274 } |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
275 |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
276 strcat(buffer2, "\n"); |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
277 ut_WriteLog(flag, buffer2); |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
278 if (buffer2 != buffer) |
9c640ee3bae3
Display full date in the log file
Mikael Berthe <mikael@lilotux.net>
parents:
393
diff
changeset
|
279 free(buffer2); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
280 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
281 free(buffer); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
282 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
283 |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
284 static window_entry_t *scr_CreateBuddyPanel(const char *title, int dont_show) |
24 | 285 { |
151 | 286 int x; |
287 int y; | |
288 int lines; | |
289 int cols; | |
153 | 290 window_entry_t *tmp; |
393 | 291 |
153 | 292 do { |
293 tmp = calloc(1, sizeof(window_entry_t)); | |
294 } while (!tmp); | |
24 | 295 |
151 | 296 // Dimensions |
297 x = ROSTER_WIDTH; | |
298 y = 0; | |
299 lines = CHAT_WIN_HEIGHT; | |
300 cols = maxX - ROSTER_WIDTH; | |
301 | |
24 | 302 tmp->win = newwin(lines, cols, y, x); |
154 | 303 while (!tmp->win) { |
419 | 304 safe_usleep(250); |
154 | 305 tmp->win = newwin(lines, cols, y, x); |
306 } | |
168 | 307 wbkgd(tmp->win, COLOR_PAIR(COLOR_GENERAL)); |
24 | 308 tmp->panel = new_panel(tmp->win); |
153 | 309 tmp->name = (char *) calloc(1, 96); |
310 strncpy(tmp->name, title, 96); | |
24 | 311 |
143 | 312 if (!dont_show) { |
24 | 313 currentWindow = tmp; |
314 } else { | |
315 if (currentWindow) | |
316 top_panel(currentWindow->panel); | |
317 else | |
318 top_panel(chatPanel); | |
319 } | |
143 | 320 update_panels(); |
24 | 321 |
181 | 322 // Load buddy history from file (if enabled) |
185 | 323 hlog_read_history(title, &tmp->hbuf, maxX - ROSTER_WIDTH - PREFIX_WIDTH); |
181 | 324 |
24 | 325 list_add_tail(&tmp->list, &window_list); |
326 | |
327 return tmp; | |
328 } | |
329 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
330 static window_entry_t *scr_SearchWindow(const char *winId) |
24 | 331 { |
332 struct list_head *pos, *n; | |
333 window_entry_t *search_entry = NULL; | |
334 | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
335 if (!winId) return NULL; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
336 |
24 | 337 list_for_each_safe(pos, n, &window_list) { |
338 search_entry = window_entry(pos); | |
339 if (search_entry->name) { | |
340 if (!strcasecmp(search_entry->name, winId)) { | |
341 return search_entry; | |
342 } | |
343 } | |
344 } | |
345 return NULL; | |
346 } | |
347 | |
143 | 348 // scr_UpdateWindow() |
349 // (Re-)Display the given chat window. | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
350 static void scr_UpdateWindow(window_entry_t *win_entry) |
74 | 351 { |
352 int n; | |
353 int width; | |
184 | 354 hbb_line **lines, *line; |
74 | 355 GList *hbuf_head; |
184 | 356 char date[32]; |
74 | 357 |
108 | 358 width = scr_WindowWidth(win_entry->win); |
359 | |
360 // Should the window be empty? | |
361 if (win_entry->cleared) { | |
168 | 362 werase(win_entry->win); |
108 | 363 return; |
364 } | |
365 | |
105 | 366 // win_entry->top is the top message of the screen. If it set to NULL, we |
367 // are displaying the last messages. | |
368 | |
74 | 369 // We will show the last CHAT_WIN_HEIGHT lines. |
370 // Let's find out where it begins. | |
105 | 371 if (!win_entry->top || |
372 (g_list_position(g_list_first(win_entry->hbuf), win_entry->top) == -1)) { | |
373 // Move up CHAT_WIN_HEIGHT lines | |
374 win_entry->hbuf = g_list_last(win_entry->hbuf); | |
375 hbuf_head = win_entry->hbuf; | |
376 win_entry->top = NULL; // (Just to make sure) | |
377 n = 0; | |
378 while (hbuf_head && (n < CHAT_WIN_HEIGHT-1) && g_list_previous(hbuf_head)) { | |
379 hbuf_head = g_list_previous(hbuf_head); | |
380 n++; | |
381 } | |
382 } else | |
383 hbuf_head = win_entry->top; | |
74 | 384 |
385 // Get the last CHAT_WIN_HEIGHT lines. | |
386 lines = hbuf_get_lines(hbuf_head, CHAT_WIN_HEIGHT); | |
387 | |
388 // Display these lines | |
389 for (n = 0; n < CHAT_WIN_HEIGHT; n++) { | |
168 | 390 wmove(win_entry->win, n, 0); |
184 | 391 line = *(lines+n); |
185 | 392 // NOTE: update PREFIX_WIDTH if you change the date format!! |
393 // You need to set it to the whole prefix length + 1 | |
184 | 394 if (line) { |
395 if (line->timestamp) { | |
419 | 396 strftime(date, 30, "%m-%d %H:%M", localtime(&line->timestamp)); |
184 | 397 } else |
185 | 398 strcpy(date, " "); |
197 | 399 if (line->flags & HBB_PREFIX_INFO) { |
400 char dir = '*'; | |
401 if (line->flags & HBB_PREFIX_IN) | |
402 dir = '<'; | |
403 else if (line->flags & HBB_PREFIX_OUT) | |
404 dir = '>'; | |
405 wprintw(win_entry->win, "%.11s *%c* ", date, dir); | |
325
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
406 } else if (line->flags & HBB_PREFIX_ERR) { |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
407 char dir = '#'; |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
408 if (line->flags & HBB_PREFIX_IN) |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
409 dir = '<'; |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
410 else if (line->flags & HBB_PREFIX_OUT) |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
411 dir = '>'; |
ff6fb51bfd78
Handle "error" message type
Mikael Berthe <mikael@lilotux.net>
parents:
322
diff
changeset
|
412 wprintw(win_entry->win, "%.11s #%c# ", date, dir); |
197 | 413 } else if (line->flags & HBB_PREFIX_IN) |
185 | 414 wprintw(win_entry->win, "%.11s <== ", date); |
184 | 415 else if (line->flags & HBB_PREFIX_OUT) |
185 | 416 wprintw(win_entry->win, "%.11s --> ", date); |
75 | 417 else { |
185 | 418 wprintw(win_entry->win, "%.11s ", date); |
75 | 419 } |
184 | 420 wprintw(win_entry->win, "%s", line->text); // line |
168 | 421 wclrtoeol(win_entry->win); |
184 | 422 g_free(line->text); |
168 | 423 } else { |
424 wclrtobot(win_entry->win); | |
425 break; | |
75 | 426 } |
74 | 427 } |
428 g_free(lines); | |
429 } | |
430 | |
143 | 431 // scr_ShowWindow() |
432 // Display the chat window with the given identifier. | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
433 static void scr_ShowWindow(const char *winId) |
24 | 434 { |
74 | 435 window_entry_t *win_entry = scr_SearchWindow(winId); |
436 | |
181 | 437 if (!win_entry) |
180 | 438 win_entry = scr_CreateBuddyPanel(winId, FALSE); |
74 | 439 |
180 | 440 top_panel(win_entry->panel); |
441 currentWindow = win_entry; | |
442 chatmode = TRUE; | |
443 roster_msg_setflag(winId, FALSE); | |
444 roster_setflags(winId, ROSTER_FLAG_LOCK, TRUE); | |
445 update_roster = TRUE; | |
74 | 446 |
180 | 447 // Refresh the window |
448 scr_UpdateWindow(win_entry); | |
449 | |
450 // Finished :) | |
451 update_panels(); | |
142 | 452 |
453 top_panel(inputPanel); | |
24 | 454 } |
455 | |
143 | 456 // scr_ShowBuddyWindow() |
457 // Display the chat window buffer for the current buddy. | |
24 | 458 void scr_ShowBuddyWindow(void) |
459 { | |
105 | 460 const gchar *jid; |
140 | 461 |
105 | 462 if (!current_buddy) |
140 | 463 jid = NULL; |
464 else | |
465 jid = CURRENT_JID; | |
466 | |
467 if (!jid) { | |
468 top_panel(chatPanel); | |
143 | 469 top_panel(inputPanel); |
140 | 470 currentWindow = NULL; |
105 | 471 return; |
140 | 472 } |
473 | |
105 | 474 scr_ShowWindow(jid); |
24 | 475 } |
476 | |
143 | 477 // scr_WriteInWindow() |
478 // Write some text in the winId window (this usually is a jid). | |
479 // Lines are splitted when they are too long to fit in the chat window. | |
480 // If this window doesn't exist, it is created. | |
184 | 481 void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp, |
482 unsigned int prefix_flags, int force_show) | |
24 | 483 { |
74 | 484 window_entry_t *win_entry; |
24 | 485 int dont_show = FALSE; |
486 | |
74 | 487 // Look for the window entry. |
488 win_entry = scr_SearchWindow(winId); | |
489 | |
490 // Do we have to really show the window? | |
24 | 491 if (!chatmode) |
492 dont_show = TRUE; | |
74 | 493 else if ((!force_show) && ((!currentWindow || (currentWindow != win_entry)))) |
24 | 494 dont_show = TRUE; |
495 | |
74 | 496 // If the window entry doesn't exist yet, let's create it. |
497 if (win_entry == NULL) { | |
151 | 498 win_entry = scr_CreateBuddyPanel(winId, dont_show); |
24 | 499 } |
500 | |
220 | 501 // The message must be displayed -> update top pointer |
502 if (win_entry->cleared) | |
503 win_entry->top = g_list_last(win_entry->hbuf); | |
504 | |
184 | 505 hbuf_add_line(&win_entry->hbuf, text, timestamp, prefix_flags, |
185 | 506 maxX - ROSTER_WIDTH - PREFIX_WIDTH); |
74 | 507 |
108 | 508 if (win_entry->cleared) { |
220 | 509 win_entry->cleared = FALSE; |
510 if (g_list_next(win_entry->top)) | |
511 win_entry->top = g_list_next(win_entry->top); | |
512 } | |
513 | |
514 // Make sure the last line appears in the window; update top if necessary | |
515 if (win_entry->top) { | |
516 int dist; | |
517 GList *first = g_list_first(win_entry->hbuf); | |
518 dist = g_list_position(first, g_list_last(win_entry->hbuf)) - | |
519 g_list_position(first, win_entry->top); | |
520 if (dist >= CHAT_WIN_HEIGHT) | |
521 win_entry->top = NULL; | |
108 | 522 } |
523 | |
24 | 524 if (!dont_show) { |
74 | 525 // Show and refresh the window |
526 top_panel(win_entry->panel); | |
527 scr_UpdateWindow(win_entry); | |
142 | 528 top_panel(inputPanel); |
24 | 529 update_panels(); |
530 doupdate(); | |
531 } else { | |
148 | 532 roster_msg_setflag(winId, TRUE); |
30 | 533 update_roster = TRUE; |
24 | 534 } |
535 } | |
536 | |
151 | 537 // scr_DrawMainWindow() |
157 | 538 // Set fullinit to TRUE to also create panels. Set it to FALSE for a resize. |
151 | 539 // |
540 // I think it could be improved a _lot_ but I'm really not an ncurses | |
541 // expert... :-\ Mikael. | |
542 // | |
543 void scr_DrawMainWindow(unsigned int fullinit) | |
24 | 544 { |
157 | 545 if (fullinit) { |
546 /* Create windows */ | |
547 rosterWnd = newwin(CHAT_WIN_HEIGHT, ROSTER_WIDTH, 0, 0); | |
548 chatWnd = newwin(CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH, 0, ROSTER_WIDTH); | |
549 logWnd_border = newwin(LOG_WIN_HEIGHT, maxX, CHAT_WIN_HEIGHT, 0); | |
550 logWnd = newwin(LOG_WIN_HEIGHT-2, maxX-2, CHAT_WIN_HEIGHT+1, 1); | |
551 inputWnd = newwin(1, maxX, maxY-1, 0); | |
358
6e4e667c5571
Fix a segfault when starting mcabber in a really small terminal
Mikael Berthe <mikael@lilotux.net>
parents:
339
diff
changeset
|
552 if (!rosterWnd || !chatWnd || !logWnd || !inputWnd) { |
6e4e667c5571
Fix a segfault when starting mcabber in a really small terminal
Mikael Berthe <mikael@lilotux.net>
parents:
339
diff
changeset
|
553 scr_TerminateCurses(); |
6e4e667c5571
Fix a segfault when starting mcabber in a really small terminal
Mikael Berthe <mikael@lilotux.net>
parents:
339
diff
changeset
|
554 fprintf(stderr, "Cannot create windows!\n"); |
6e4e667c5571
Fix a segfault when starting mcabber in a really small terminal
Mikael Berthe <mikael@lilotux.net>
parents:
339
diff
changeset
|
555 exit(EXIT_FAILURE); |
6e4e667c5571
Fix a segfault when starting mcabber in a really small terminal
Mikael Berthe <mikael@lilotux.net>
parents:
339
diff
changeset
|
556 } |
168 | 557 wbkgd(rosterWnd, COLOR_PAIR(COLOR_GENERAL)); |
558 wbkgd(chatWnd, COLOR_PAIR(COLOR_GENERAL)); | |
559 wbkgd(logWnd_border, COLOR_PAIR(COLOR_GENERAL)); | |
560 wbkgd(logWnd, COLOR_PAIR(COLOR_GENERAL)); | |
157 | 561 } else { |
562 /* Resize windows */ | |
563 wresize(rosterWnd, CHAT_WIN_HEIGHT, ROSTER_WIDTH); | |
564 wresize(chatWnd, CHAT_WIN_HEIGHT, maxX - ROSTER_WIDTH); | |
565 | |
566 wresize(logWnd_border, LOG_WIN_HEIGHT, maxX); | |
567 wresize(logWnd, LOG_WIN_HEIGHT-2, maxX-2); | |
568 mvwin(logWnd_border, CHAT_WIN_HEIGHT, 0); | |
569 mvwin(logWnd, CHAT_WIN_HEIGHT+1, 1); | |
570 | |
571 wresize(inputWnd, 1, maxX); | |
572 mvwin(inputWnd, maxY-1, 0); | |
168 | 573 |
574 werase(chatWnd); | |
157 | 575 } |
151 | 576 |
577 /* Draw/init windows */ | |
578 | |
74 | 579 mvwprintw(chatWnd, 0, 0, "This is the status window"); |
24 | 580 |
151 | 581 // - Draw/clear the log window |
24 | 582 scr_draw_box(logWnd_border, 0, 0, LOG_WIN_HEIGHT, maxX, COLOR_GENERAL, 0, 0); |
157 | 583 // Auto-scrolling in log window |
74 | 584 scrollok(logWnd, TRUE); |
24 | 585 |
586 | |
151 | 587 if (fullinit) { |
157 | 588 // Enable keypad (+ special keys) |
589 keypad(inputWnd, TRUE); | |
382
4c6e8392e465
Use nodelay() instead of halfdelay()
Mikael Berthe <mikael@lilotux.net>
parents:
374
diff
changeset
|
590 nodelay(inputWnd, TRUE); |
157 | 591 |
151 | 592 // Create panels |
593 rosterPanel = new_panel(rosterWnd); | |
594 chatPanel = new_panel(chatWnd); | |
595 logPanel_border = new_panel(logWnd_border); | |
596 logPanel = new_panel(logWnd); | |
597 inputPanel = new_panel(inputWnd); | |
232 | 598 |
599 if (utf8_mode) | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
600 scr_LogPrint(LPRINT_NORMAL, "WARNING: UTF-8 not yet supported!"); |
157 | 601 } else { |
602 // Update panels | |
603 replace_panel(rosterPanel, rosterWnd); | |
604 replace_panel(chatPanel, chatWnd); | |
605 replace_panel(logPanel, logWnd); | |
606 replace_panel(logPanel_border, logWnd_border); | |
607 replace_panel(inputPanel, inputWnd); | |
151 | 608 } |
609 | |
610 // We'll need to redraw the roster | |
149 | 611 update_roster = TRUE; |
24 | 612 return; |
613 } | |
614 | |
151 | 615 // scr_Resize() |
616 // Function called when the window is resized. | |
157 | 617 // - Resize windows |
151 | 618 // - Rewrap lines in each buddy buffer |
619 void scr_Resize() | |
620 { | |
621 struct list_head *pos, *n; | |
622 window_entry_t *search_entry; | |
623 int x, y, lines, cols; | |
624 | |
625 // First, update the global variables | |
626 getmaxyx(stdscr, maxY, maxX); | |
167 | 627 if (maxY < LOG_WIN_HEIGHT+2) |
628 maxY = LOG_WIN_HEIGHT+2; | |
151 | 629 // Make sure the cursor stays inside the window |
630 check_offset(0); | |
631 | |
157 | 632 // Resize windows and update panels |
151 | 633 scr_DrawMainWindow(FALSE); |
634 | |
635 // Resize all buddy windows | |
636 x = ROSTER_WIDTH; | |
637 y = 0; | |
638 lines = CHAT_WIN_HEIGHT; | |
639 cols = maxX - ROSTER_WIDTH; | |
640 | |
641 list_for_each_safe(pos, n, &window_list) { | |
642 search_entry = window_entry(pos); | |
643 if (search_entry->win) { | |
189 | 644 GList *rescue_top; |
157 | 645 // Resize buddy window (no need to move it) |
646 wresize(search_entry->win, lines, cols); | |
168 | 647 werase(search_entry->win); |
151 | 648 // If a panel exists, replace the old window with the new |
649 if (search_entry->panel) { | |
650 replace_panel(search_entry->panel, search_entry->win); | |
651 } | |
652 // Redo line wrapping | |
189 | 653 rescue_top = hbuf_previous_persistent(search_entry->top); |
151 | 654 hbuf_rebuild(&search_entry->hbuf, |
185 | 655 maxX - ROSTER_WIDTH - PREFIX_WIDTH); |
388
f211238d5812
Ctrl-l does a full refresh
Mikael Berthe <mikael@lilotux.net>
parents:
384
diff
changeset
|
656 if (g_list_position(g_list_first(search_entry->hbuf), |
f211238d5812
Ctrl-l does a full refresh
Mikael Berthe <mikael@lilotux.net>
parents:
384
diff
changeset
|
657 search_entry->top) == -1) { |
189 | 658 search_entry->top = rescue_top; |
388
f211238d5812
Ctrl-l does a full refresh
Mikael Berthe <mikael@lilotux.net>
parents:
384
diff
changeset
|
659 } |
151 | 660 } |
661 } | |
662 | |
663 // Refresh current buddy window | |
157 | 664 if (chatmode) |
151 | 665 scr_ShowBuddyWindow(); |
666 } | |
667 | |
143 | 668 // scr_DrawRoster() |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
669 // Display the buddylist (not really the roster) on the screen |
81 | 670 void scr_DrawRoster(void) |
24 | 671 { |
81 | 672 static guint offset = 0; |
673 char name[ROSTER_WIDTH]; | |
674 int maxx, maxy; | |
675 GList *buddy; | |
676 int i, n; | |
677 int rOffset; | |
164 | 678 enum imstatus currentstatus = jb_getstatus(); |
81 | 679 |
123 | 680 // We can reset update_roster |
681 update_roster = FALSE; | |
682 | |
81 | 683 getmaxyx(rosterWnd, maxy, maxx); |
684 maxx --; // last char is for vertical border | |
685 name[ROSTER_WIDTH-7] = 0; | |
686 | |
687 // cleanup of roster window | |
168 | 688 werase(rosterWnd); |
689 // Redraw the vertical line (not very good...) | |
81 | 690 wattrset(rosterWnd, COLOR_PAIR(COLOR_GENERAL)); |
168 | 691 for (i=0 ; i < CHAT_WIN_HEIGHT ; i++) |
692 mvwaddch(rosterWnd, i, ROSTER_WIDTH-1, ACS_VLINE); | |
81 | 693 |
694 // Leave now if buddylist is empty | |
695 if (!buddylist) { | |
696 offset = 0; | |
123 | 697 update_panels(); |
698 doupdate(); | |
81 | 699 return; |
700 } | |
701 | |
84 | 702 // Update offset if necessary |
703 i = g_list_position(buddylist, current_buddy); | |
704 if (i == -1) { // This is bad | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
705 scr_LogPrint(LPRINT_NORMAL, "Doh! Can't find current selected buddy!!"); |
84 | 706 return; |
707 } else if (i < offset) { | |
708 offset = i; | |
709 } else if (i+1 > offset + maxy) { | |
710 offset = i + 1 - maxy; | |
711 } | |
81 | 712 |
713 buddy = buddylist; | |
714 rOffset = offset; | |
715 | |
84 | 716 for (i=0; i<maxy && buddy; buddy = g_list_next(buddy)) { |
81 | 717 |
718 char status = '?'; | |
719 char pending = ' '; | |
720 enum imstatus budstate; | |
149 | 721 unsigned short ismsg = buddy_getflags(BUDDATA(buddy)) & ROSTER_FLAG_MSG; |
722 unsigned short isgrp = buddy_gettype(BUDDATA(buddy)) & ROSTER_TYPE_GROUP; | |
447
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
445
diff
changeset
|
723 unsigned short ismuc = buddy_gettype(BUDDATA(buddy)) & ROSTER_TYPE_ROOM; |
149 | 724 unsigned short ishid = buddy_getflags(BUDDATA(buddy)) & ROSTER_FLAG_HIDE; |
81 | 725 |
726 if (rOffset > 0) { | |
727 rOffset--; | |
728 continue; | |
729 } | |
730 | |
149 | 731 // Display message notice if there is a message flag, but not |
732 // for unfolded groups. | |
733 if (ismsg && (!isgrp || ishid)) { | |
81 | 734 pending = '#'; |
735 } | |
736 | |
438
b44be19d6229
Handle multiple resources for the same buddy
Mikael Berthe <mikael@lilotux.net>
parents:
419
diff
changeset
|
737 budstate = buddy_getstatus(BUDDATA(buddy), NULL); |
164 | 738 if (budstate >= 0 && budstate < imstatus_size && currentstatus != offline) |
81 | 739 status = imstatus2char[budstate]; |
740 if (buddy == current_buddy) { | |
741 wattrset(rosterWnd, COLOR_PAIR(COLOR_BD_DESSEL)); | |
742 // The 3 following lines aim to color the whole line | |
743 wmove(rosterWnd, i, 0); | |
744 for (n = 0; n < maxx; n++) | |
745 waddch(rosterWnd, ' '); | |
746 } else { | |
149 | 747 if (pending == '#') |
139 | 748 wattrset(rosterWnd, COLOR_PAIR(COLOR_NMSG)); |
749 else | |
750 wattrset(rosterWnd, COLOR_PAIR(COLOR_BD_DES)); | |
81 | 751 } |
752 | |
447
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
445
diff
changeset
|
753 if (ismuc) status = 'C'; |
03bb57383cea
Initial Multi-User Chat support
Mikael Berthe <mikael@lilotux.net>
parents:
445
diff
changeset
|
754 |
81 | 755 strncpy(name, buddy_getname(BUDDATA(buddy)), ROSTER_WIDTH-7); |
149 | 756 if (isgrp) { |
133 | 757 char *sep; |
149 | 758 if (ishid) |
133 | 759 sep = "+++"; |
760 else | |
761 sep = "---"; | |
762 mvwprintw(rosterWnd, i, 0, " %c%s %s", pending, sep, name); | |
763 } | |
126 | 764 else |
765 mvwprintw(rosterWnd, i, 0, " %c[%c] %s", pending, status, name); | |
84 | 766 |
767 i++; | |
81 | 768 } |
769 | |
142 | 770 top_panel(inputPanel); |
81 | 771 update_panels(); |
772 doupdate(); | |
24 | 773 } |
774 | |
184 | 775 void scr_WriteMessage(const char *jid, const char *text, time_t timestamp, |
776 guint prefix_flags) | |
24 | 777 { |
184 | 778 if (!timestamp) timestamp = time(NULL); |
779 | |
780 scr_WriteInWindow(jid, text, timestamp, prefix_flags, FALSE); | |
47 | 781 } |
782 | |
190 | 783 // If prefix is NULL, HBB_PREFIX_IN is supposed. |
184 | 784 void scr_WriteIncomingMessage(const char *jidfrom, const char *text, |
190 | 785 time_t timestamp, guint prefix) |
47 | 786 { |
190 | 787 if (!prefix) prefix = HBB_PREFIX_IN; |
75 | 788 // FIXME expand tabs / filter out special chars... |
190 | 789 scr_WriteMessage(jidfrom, text, timestamp, prefix); |
24 | 790 update_panels(); |
791 doupdate(); | |
792 } | |
793 | |
50 | 794 void scr_WriteOutgoingMessage(const char *jidto, const char *text) |
47 | 795 { |
184 | 796 scr_WriteMessage(jidto, text, 0, HBB_PREFIX_OUT); |
47 | 797 scr_ShowWindow(jidto); |
798 } | |
799 | |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
800 void inline set_autoaway(bool setaway) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
801 { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
802 static enum imstatus oldstatus; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
803 Autoaway = setaway; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
804 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
805 if (setaway) { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
806 const char *msg; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
807 oldstatus = jb_getstatus(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
808 msg = settings_opt_get("message_autoaway"); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
809 if (!msg) msg = MSG_AUTOAWAY; |
444 | 810 jb_setstatus(away, NULL, msg); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
811 } else { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
812 // Back |
444 | 813 jb_setstatus(oldstatus, NULL, NULL); |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
814 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
815 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
816 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
817 // Check if we should enter/leave automatic away status |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
818 void scr_CheckAutoAway(bool activity) |
24 | 819 { |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
820 static time_t LastActivity; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
821 enum imstatus cur_st; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
822 unsigned int autoaway_timeout = settings_opt_get_int("autoaway"); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
823 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
824 if (Autoaway && activity) set_autoaway(FALSE); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
825 if (!autoaway_timeout) return; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
826 if (!LastActivity || activity) time(&LastActivity); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
827 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
828 cur_st = jb_getstatus(); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
829 // Auto-away is disabled for the following states |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
830 if ((cur_st != available) && (cur_st != freeforchat)) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
831 return; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
832 |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
833 if (!activity) { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
834 time_t now; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
835 time(&now); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
836 if (!Autoaway && (now > LastActivity + autoaway_timeout)) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
837 set_autoaway(TRUE); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
838 } |
24 | 839 } |
840 | |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
841 // set_current_buddy(newbuddy) |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
842 // Set the current_buddy to newbuddy (if not NULL) |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
843 // Lock the newbuddy, and unlock the previous current_buddy |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
844 static void set_current_buddy(GList *newbuddy) |
24 | 845 { |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
846 enum imstatus prev_st = imstatus_size; |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
847 /* prev_st initialized to imstatus_size, which is used as "undef" value. |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
848 * We are sure prev_st will get a different status value after the |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
849 * buddy_getstatus() call. |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
850 */ |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
851 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
852 if (!current_buddy || !newbuddy) return; |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
853 if (newbuddy == current_buddy) return; |
24 | 854 |
438
b44be19d6229
Handle multiple resources for the same buddy
Mikael Berthe <mikael@lilotux.net>
parents:
419
diff
changeset
|
855 prev_st = buddy_getstatus(BUDDATA(current_buddy), NULL); |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
856 buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, FALSE); |
330 | 857 if (chatmode) |
858 alternate_buddy = current_buddy; | |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
859 current_buddy = newbuddy; |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
860 // Lock the buddy in the buddylist if we're in chat mode |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
861 if (chatmode) |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
862 buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, TRUE); |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
863 // We should rebuild the buddylist but not everytime |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
864 // Here we check if we were locking a buddy who is actually offline, |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
865 // and hide_offline_buddies is TRUE. In which case we need to rebuild. |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
866 if (prev_st == offline && buddylist_get_hide_offline_buddies()) |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
867 buddylist_build(); |
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
868 update_roster = TRUE; |
24 | 869 } |
870 | |
143 | 871 // scr_RosterTop() |
872 // Go to the first buddy in the buddylist | |
105 | 873 void scr_RosterTop(void) |
104 | 874 { |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
875 set_current_buddy(buddylist); |
104 | 876 if (chatmode) |
877 scr_ShowBuddyWindow(); | |
878 } | |
879 | |
143 | 880 // scr_RosterBottom() |
881 // Go to the last buddy in the buddylist | |
105 | 882 void scr_RosterBottom(void) |
104 | 883 { |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
884 set_current_buddy(g_list_last(buddylist)); |
104 | 885 if (chatmode) |
886 scr_ShowBuddyWindow(); | |
887 } | |
888 | |
143 | 889 // scr_RosterUp() |
890 // Go to the previous buddy in the buddylist | |
105 | 891 void scr_RosterUp(void) |
81 | 892 { |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
893 set_current_buddy(g_list_previous(current_buddy)); |
104 | 894 if (chatmode) |
895 scr_ShowBuddyWindow(); | |
81 | 896 } |
897 | |
143 | 898 // scr_RosterDown() |
899 // Go to the next buddy in the buddylist | |
105 | 900 void scr_RosterDown(void) |
81 | 901 { |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
902 set_current_buddy(g_list_next(current_buddy)); |
104 | 903 if (chatmode) |
904 scr_ShowBuddyWindow(); | |
81 | 905 } |
906 | |
265 | 907 // scr_RosterSearch(str) |
908 // Look forward for a buddy with jid/name containing str. | |
909 void scr_RosterSearch(char *str) | |
910 { | |
328
83d129adde03
Add set_current_buddy() function, to reduce code duplication
Mikael Berthe <mikael@lilotux.net>
parents:
325
diff
changeset
|
911 set_current_buddy(buddy_search(str)); |
265 | 912 if (chatmode) |
913 scr_ShowBuddyWindow(); | |
914 } | |
915 | |
236 | 916 // scr_RosterUnreadMessage(next) |
917 // Go to a new message. If next is not null, try to go to the next new | |
918 // message. If it is not possible or if next is NULL, go to the first new | |
919 // message from unread_list. | |
920 void scr_RosterUnreadMessage(int next) | |
921 { | |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
922 gpointer unread_ptr; |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
923 gpointer refbuddata; |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
924 gpointer ngroup; |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
925 GList *nbuddy; |
236 | 926 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
927 if (!current_buddy) return; |
236 | 928 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
929 if (next) refbuddata = BUDDATA(current_buddy); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
930 else refbuddata = NULL; |
236 | 931 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
932 unread_ptr = unread_msg(refbuddata); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
933 if (!unread_ptr) return; |
236 | 934 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
935 // If buddy is in a folded group, we need to expand it |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
936 ngroup = buddy_getgroup(unread_ptr); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
937 if (buddy_getflags(ngroup) & ROSTER_FLAG_HIDE) { |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
938 buddy_setflags(ngroup, ROSTER_FLAG_HIDE, FALSE); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
939 buddylist_build(); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
940 } |
236 | 941 |
329
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
942 nbuddy = g_list_find(buddylist, unread_ptr); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
943 if (nbuddy) { |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
944 set_current_buddy(nbuddy); |
7c53bf62a2a2
scr_RosterUnreadMessage() uses set_current_buddy()
Mikael Berthe <mikael@lilotux.net>
parents:
328
diff
changeset
|
945 if (chatmode) scr_ShowBuddyWindow(); |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
946 } else |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
947 scr_LogPrint(LPRINT_LOGNORM, "Error: nbuddy == NULL"); // should not happen |
236 | 948 } |
949 | |
330 | 950 // scr_RosterJumpAlternate() |
951 // Try to jump to alternate (== previous) buddy | |
952 void scr_RosterJumpAlternate(void) | |
105 | 953 { |
330 | 954 if (!alternate_buddy || g_list_position(buddylist, alternate_buddy) == -1) |
955 return; | |
956 set_current_buddy(alternate_buddy); | |
957 if (chatmode) | |
958 scr_ShowBuddyWindow(); | |
959 } | |
960 | |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
961 // scr_BufferScrollUpDown() |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
962 // Scroll up/down the current buddy window, half a screen. |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
963 // (up if updown == -1, down if updown == 1) |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
964 void scr_BufferScrollUpDown(int updown) |
105 | 965 { |
966 window_entry_t *win_entry; | |
967 int n, nblines; | |
968 GList *hbuf_top; | |
969 | |
970 // Get win_entry | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
971 if (!current_buddy) return; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
972 win_entry = scr_SearchWindow(CURRENT_JID); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
973 if (!win_entry) return; |
105 | 974 |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
975 // Scroll half a screen (or less) |
105 | 976 nblines = CHAT_WIN_HEIGHT/2-1; |
977 hbuf_top = win_entry->top; | |
978 | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
979 if (updown == -1) { // UP |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
980 if (!hbuf_top) { |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
981 hbuf_top = g_list_last(win_entry->hbuf); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
982 if (!win_entry->cleared) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
983 nblines *= 3; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
984 else |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
985 win_entry->cleared = FALSE; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
986 } |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
987 for (n=0 ; hbuf_top && n < nblines && g_list_previous(hbuf_top) ; n++) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
988 hbuf_top = g_list_previous(hbuf_top); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
989 win_entry->top = hbuf_top; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
990 } else { // DOWN |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
991 for (n=0 ; hbuf_top && n < nblines ; n++) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
992 hbuf_top = g_list_next(hbuf_top); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
993 win_entry->top = hbuf_top; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
994 // Check if we are at the bottom |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
995 for (n=0 ; hbuf_top && n < CHAT_WIN_HEIGHT-1 ; n++) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
996 hbuf_top = g_list_next(hbuf_top); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
997 if (!hbuf_top) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
998 win_entry->top = NULL; // End reached |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
999 } |
105 | 1000 |
1001 // Refresh the window | |
1002 scr_UpdateWindow(win_entry); | |
1003 | |
1004 // Finished :) | |
1005 update_panels(); | |
1006 doupdate(); | |
1007 } | |
1008 | |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
1009 // scr_BufferClear() |
143 | 1010 // Clear the current buddy window (used for the /clear command) |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
1011 void scr_BufferClear(void) |
108 | 1012 { |
1013 window_entry_t *win_entry; | |
1014 | |
1015 // Get win_entry | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1016 if (!current_buddy) return; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1017 win_entry = scr_SearchWindow(CURRENT_JID); |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1018 if (!win_entry) return; |
108 | 1019 |
1020 win_entry->cleared = TRUE; | |
109 | 1021 win_entry->top = NULL; |
108 | 1022 |
1023 // Refresh the window | |
1024 scr_UpdateWindow(win_entry); | |
1025 | |
1026 // Finished :) | |
1027 update_panels(); | |
1028 doupdate(); | |
1029 } | |
1030 | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1031 // scr_BufferTopBottom() |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1032 // Jump to the head/tail of the current buddy window |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1033 // (top if topbottom == -1, bottom topbottom == 1) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1034 void scr_BufferTopBottom(int topbottom) |
187 | 1035 { |
1036 window_entry_t *win_entry; | |
1037 | |
1038 // Get win_entry | |
1039 if (!current_buddy) return; | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1040 win_entry = scr_SearchWindow(CURRENT_JID); |
187 | 1041 if (!win_entry) return; |
1042 | |
1043 win_entry->cleared = FALSE; | |
361
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1044 if (topbottom == 1) |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1045 win_entry->top = NULL; |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1046 else |
51ff319947c3
Code cleanup/optimization
Mikael Berthe <mikael@lilotux.net>
parents:
358
diff
changeset
|
1047 win_entry->top = g_list_first(win_entry->hbuf); |
187 | 1048 |
1049 // Refresh the window | |
1050 scr_UpdateWindow(win_entry); | |
1051 | |
1052 // Finished :) | |
1053 update_panels(); | |
1054 doupdate(); | |
1055 } | |
1056 | |
370
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1057 // scr_BufferSearch(direction, text) |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1058 // Jump to the next line containing text |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1059 // (backward search if direction == -1, forward if topbottom == 1) |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1060 void scr_BufferSearch(int direction, const char *text) |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1061 { |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1062 window_entry_t *win_entry; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1063 GList *current_line, *search_res; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1064 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1065 // Get win_entry |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1066 if (!current_buddy) return; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1067 win_entry = scr_SearchWindow(CURRENT_JID); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1068 if (!win_entry) return; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1069 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1070 if (win_entry->top) |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1071 current_line = win_entry->top; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1072 else |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1073 current_line = g_list_last(win_entry->hbuf); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1074 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1075 search_res = hbuf_search(current_line, direction, text); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1076 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1077 if (search_res) { |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1078 win_entry->cleared = FALSE; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1079 win_entry->top = search_res; |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1080 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1081 // Refresh the window |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1082 scr_UpdateWindow(win_entry); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1083 |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1084 // Finished :) |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1085 update_panels(); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1086 doupdate(); |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1087 } else |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1088 scr_LogPrint(LPRINT_NORMAL, "Search string not found"); |
370
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1089 } |
dd9e2eb52916
Add /buffer search_{backward,forward}
Mikael Berthe <mikael@lilotux.net>
parents:
369
diff
changeset
|
1090 |
143 | 1091 // scr_set_chatmode() |
261 | 1092 // Public function to (un)set chatmode... |
129 | 1093 inline void scr_set_chatmode(int enable) |
1094 { | |
1095 chatmode = enable; | |
1096 } | |
1097 | |
238 | 1098 // scr_get_multimode() |
261 | 1099 // Public function to get multimode status... |
238 | 1100 inline int scr_get_multimode() |
1101 { | |
1102 return multimode; | |
1103 } | |
1104 | |
1105 // scr_set_multimode() | |
261 | 1106 // Public function to (un)set multimode... |
260
33e1a05864a6
Add "verbatim multi-line" mode, with commands disabled
mikael@frmp8452
parents:
252
diff
changeset
|
1107 // Convention: |
33e1a05864a6
Add "verbatim multi-line" mode, with commands disabled
mikael@frmp8452
parents:
252
diff
changeset
|
1108 // 0 = disabled / 1 = multimode / 2 = multimode verbatim (commands disabled) |
238 | 1109 inline void scr_set_multimode(int enable) |
1110 { | |
1111 if (multiline) { | |
1112 g_free(multiline); | |
1113 multiline = NULL; | |
1114 } | |
260
33e1a05864a6
Add "verbatim multi-line" mode, with commands disabled
mikael@frmp8452
parents:
252
diff
changeset
|
1115 multimode = enable; |
238 | 1116 } |
1117 | |
1118 // scr_get_multiline() | |
261 | 1119 // Public function to get the current multi-line. |
238 | 1120 inline const char *scr_get_multiline() |
1121 { | |
1122 if (multimode && multiline) | |
1123 return multiline; | |
1124 else | |
1125 return ""; | |
1126 } | |
1127 | |
1128 // scr_append_multiline(line) | |
1129 // Public function to append a line to the current multi-line message. | |
1130 // Skip empty leading lines. | |
1131 void scr_append_multiline(const char *line) | |
1132 { | |
1133 static int num; | |
1134 | |
1135 if (!multimode) { | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1136 scr_LogPrint(LPRINT_NORMAL, "Error: Not in multi-line message mode!"); |
238 | 1137 return; |
1138 } | |
1139 if (multiline) { | |
1140 int len = strlen(multiline)+strlen(line)+2; | |
252 | 1141 if (len >= HBB_BLOCKSIZE - 1) { |
238 | 1142 // We don't handle single messages with size > HBB_BLOCKSIZE |
1143 // (see hbuf) | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1144 scr_LogPrint(LPRINT_NORMAL, "Your multi-line message is too big, " |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1145 "this line has not been added."); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1146 scr_LogPrint(LPRINT_NORMAL, "Please send this part now..."); |
238 | 1147 return; |
1148 } | |
276
627925d885de
Limit the number of lines in multi-line messages
Mikael Berthe <mikael@lilotux.net>
parents:
271
diff
changeset
|
1149 if (num >= MULTILINE_MAX_LINE_NUMBER) { |
627925d885de
Limit the number of lines in multi-line messages
Mikael Berthe <mikael@lilotux.net>
parents:
271
diff
changeset
|
1150 // We don't allow too many lines; however the maximum is arbitrary |
627925d885de
Limit the number of lines in multi-line messages
Mikael Berthe <mikael@lilotux.net>
parents:
271
diff
changeset
|
1151 // (It should be < 1000 yet) |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1152 scr_LogPrint(LPRINT_NORMAL, "Your message has too many lines, " |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1153 "this one has not been added."); |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1154 scr_LogPrint(LPRINT_NORMAL, "Please send this part now..."); |
276
627925d885de
Limit the number of lines in multi-line messages
Mikael Berthe <mikael@lilotux.net>
parents:
271
diff
changeset
|
1155 return; |
627925d885de
Limit the number of lines in multi-line messages
Mikael Berthe <mikael@lilotux.net>
parents:
271
diff
changeset
|
1156 } |
238 | 1157 multiline = g_renew(char, multiline, len); |
1158 strcat(multiline, "\n"); | |
1159 strcat(multiline, line); | |
1160 num++; | |
1161 } else { | |
1162 // First message line (we skip leading empty lines) | |
1163 num = 0; | |
1164 if (line[0]) { | |
419 | 1165 multiline = g_strdup(line); |
238 | 1166 num++; |
1167 } else | |
1168 return; | |
1169 } | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1170 scr_LogPrint(LPRINT_NORMAL, "Multi-line mode: line #%d added [%.25s...", |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1171 num, line); |
238 | 1172 } |
1173 | |
173 | 1174 // scr_cmdhisto_addline() |
1175 // Add a line to the inputLine history | |
1176 inline void scr_cmdhisto_addline(char *line) | |
1177 { | |
1178 if (!line || !*line) return; | |
1179 | |
1180 cmdhisto = g_list_append(cmdhisto, g_strdup(line)); | |
1181 } | |
1182 | |
1183 // scr_cmdhisto_prev() | |
1184 // Look for previous line beginning w/ the given mask in the inputLine history | |
175 | 1185 // Returns NULL if none found |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1186 static const char *scr_cmdhisto_prev(char *mask, guint len) |
173 | 1187 { |
1188 GList *hl; | |
1189 if (!cmdhisto_cur) { | |
1190 hl = g_list_last(cmdhisto); | |
174 | 1191 if (hl) { // backup current line |
1192 strncpy(cmdhisto_backup, mask, INPUTLINE_LENGTH); | |
1193 } | |
173 | 1194 } else { |
1195 hl = g_list_previous(cmdhisto_cur); | |
1196 } | |
1197 while (hl) { | |
1198 if (!strncmp((char*)hl->data, mask, len)) { | |
1199 // Found a match | |
1200 cmdhisto_cur = hl; | |
1201 return (const char*)hl->data; | |
1202 } | |
1203 hl = g_list_previous(hl); | |
1204 } | |
1205 return NULL; | |
1206 } | |
1207 | |
1208 // scr_cmdhisto_next() | |
1209 // Look for next line beginning w/ the given mask in the inputLine history | |
175 | 1210 // Returns NULL if none found |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1211 static const char *scr_cmdhisto_next(char *mask, guint len) |
173 | 1212 { |
1213 GList *hl; | |
1214 if (!cmdhisto_cur) return NULL; | |
1215 hl = cmdhisto_cur; | |
1216 while ((hl = g_list_next(hl)) != NULL) | |
1217 if (!strncmp((char*)hl->data, mask, len)) { | |
1218 // Found a match | |
1219 cmdhisto_cur = hl; | |
1220 return (const char*)hl->data; | |
1221 } | |
175 | 1222 // If the "backuped" line matches, we'll use it |
1223 if (strncmp(cmdhisto_backup, mask, len)) return NULL; // No match | |
174 | 1224 cmdhisto_cur = NULL; |
1225 return cmdhisto_backup; | |
173 | 1226 } |
1227 | |
195 | 1228 // readline_transpose_chars() |
1229 // Drag the character before point forward over the character at | |
1230 // point, moving point forward as well. If point is at the end of | |
1231 // the line, then this transposes the two characters before point. | |
1232 void readline_transpose_chars() | |
1233 { | |
1234 char swp; | |
1235 | |
1236 if (ptr_inputline == inputLine) return; | |
1237 | |
1238 if (!*ptr_inputline) { // We're at EOL | |
1239 // If line is only 1 char long, nothing to do... | |
1240 if (ptr_inputline == inputLine+1) return; | |
1241 // Transpose the two previous characters | |
1242 swp = *(ptr_inputline-2); | |
1243 *(ptr_inputline-2) = *(ptr_inputline-1); | |
1244 *(ptr_inputline-1) = swp; | |
1245 } else { | |
196 | 1246 // Swap the two characters before the cursor and move right. |
195 | 1247 swp = *(ptr_inputline-1); |
1248 *(ptr_inputline-1) = *ptr_inputline; | |
1249 *ptr_inputline++ = swp; | |
1250 check_offset(1); | |
1251 } | |
1252 } | |
1253 | |
1254 // readline_backward_kill_word() | |
194 | 1255 // Kill the word before the cursor, in input line |
195 | 1256 void readline_backward_kill_word() |
194 | 1257 { |
1258 char *c, *old = ptr_inputline; | |
1259 int spaceallowed = 1; | |
1260 | |
1261 if (ptr_inputline == inputLine) return; | |
1262 | |
1263 for (c = ptr_inputline-1 ; c > inputLine ; c--) | |
1264 if (!isalnum(*c)) { | |
1265 if (*c == ' ') | |
1266 if (!spaceallowed) break; | |
1267 } else spaceallowed = 0; | |
1268 | |
1269 if (c != inputLine || *c != ' ') | |
1270 if ((c < ptr_inputline-1) && (!isalnum(*c))) | |
1271 c++; | |
1272 | |
1273 // Modify the line | |
1274 ptr_inputline = c; | |
1275 for (;;) { | |
1276 *c = *old++; | |
1277 if (!*c++) break; | |
1278 } | |
195 | 1279 check_offset(-1); |
194 | 1280 } |
1281 | |
98 | 1282 // which_row() |
1283 // Tells which row our cursor is in, in the command line. | |
1284 // -1 -> normal text | |
1285 // 0 -> command | |
1286 // 1 -> parameter 1 (etc.) | |
102 | 1287 // If > 0, then *p_row is set to the beginning of the row |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1288 static int which_row(char **p_row) |
98 | 1289 { |
1290 int row = -1; | |
1291 char *p; | |
1292 int quote = FALSE; | |
1293 | |
1294 // Not a command? | |
1295 if ((ptr_inputline == inputLine) || (inputLine[0] != '/')) | |
1296 return -1; | |
1297 | |
1298 // This is a command | |
1299 row = 0; | |
1300 for (p = inputLine ; p < ptr_inputline ; p++) { | |
1301 if (quote) { | |
1302 if (*p == '"' && *(p-1) != '\\') | |
1303 quote = FALSE; | |
1304 continue; | |
1305 } | |
1306 if (*p == '"' && *(p-1) != '\\') { | |
1307 quote = TRUE; | |
121 | 1308 } else if (*p == ' ') { |
1309 if (*(p-1) != ' ') | |
1310 row++; | |
102 | 1311 *p_row = p+1; |
1312 } | |
98 | 1313 } |
1314 return row; | |
1315 } | |
1316 | |
143 | 1317 // scr_insert_text() |
1318 // Insert the given text at the current cursor position. | |
1319 // The cursor is moved. We don't check if the cursor still is in the screen | |
1320 // after, the caller should do that. | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1321 static void scr_insert_text(const char *text) |
98 | 1322 { |
1323 char tmpLine[INPUTLINE_LENGTH+1]; | |
1324 int len = strlen(text); | |
1325 // Check the line isn't too long | |
1326 if (strlen(inputLine) + len >= INPUTLINE_LENGTH) { | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1327 scr_LogPrint(LPRINT_LOGNORM, "Cannot insert text, line too long."); |
98 | 1328 return; |
1329 } | |
1330 | |
1331 strcpy(tmpLine, ptr_inputline); | |
419 | 1332 strcpy(ptr_inputline, text); |
1333 ptr_inputline += len; | |
98 | 1334 strcpy(ptr_inputline, tmpLine); |
1335 } | |
1336 | |
143 | 1337 // scr_handle_tab() |
1338 // Function called when tab is pressed. | |
1339 // Initiate or continue a completion... | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1340 static void scr_handle_tab(void) |
98 | 1341 { |
102 | 1342 int nrow; |
1343 char *row; | |
1344 const char *cchar; | |
103 | 1345 guint compl_categ; |
98 | 1346 |
102 | 1347 nrow = which_row(&row); |
98 | 1348 |
103 | 1349 // a) No completion if no leading slash ('cause not a command) |
1350 // b) We can't have more than 2 parameters (we use 2 flags) | |
445
7bf6c0c6a714
Fix command completion (2nd argument)
Mikael Berthe <mikael@lilotux.net>
parents:
444
diff
changeset
|
1351 if (nrow < 0 || (nrow == 3 && !completion_started) || nrow > 3) return; |
102 | 1352 |
103 | 1353 if (nrow == 0) { // Command completion |
1354 row = &inputLine[1]; | |
1355 compl_categ = COMPL_CMD; | |
1356 } else { // Other completion, depending on the command | |
285 | 1357 int alias = FALSE; |
1358 cmd *com; | |
1359 char *xpline = expandalias(inputLine); | |
1360 com = cmd_get(xpline); | |
1361 if (xpline != inputLine) { | |
1362 // This is an alias, so we can't complete rows > 0 | |
1363 alias = TRUE; | |
1364 g_free(xpline); | |
1365 } | |
1366 if ((!com && (!alias || !completion_started)) || !row) { | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1367 scr_LogPrint(LPRINT_NORMAL, "I cannot complete that..."); |
103 | 1368 return; |
1369 } | |
285 | 1370 if (!alias) |
1371 compl_categ = com->completion_flags[nrow-1]; | |
1372 else | |
1373 compl_categ = 0; | |
103 | 1374 } |
1375 | |
1376 if (!completion_started) { | |
1377 GSList *list = compl_get_category_list(compl_categ); | |
1378 if (list) { | |
1379 char *prefix = g_strndup(row, ptr_inputline-row); | |
1380 // Init completion | |
1381 new_completion(prefix, list); | |
1382 g_free(prefix); | |
1383 // Now complete | |
98 | 1384 cchar = complete(); |
1385 if (cchar) | |
1386 scr_insert_text(cchar); | |
103 | 1387 completion_started = TRUE; |
98 | 1388 } |
103 | 1389 } else { // Completion already initialized |
1390 char *c; | |
1391 guint back = cancel_completion(); | |
1392 // Remove $back chars | |
1393 ptr_inputline -= back; | |
1394 c = ptr_inputline; | |
1395 for ( ; *c ; c++) | |
1396 *c = *(c+back); | |
1397 // Now complete again | |
1398 cchar = complete(); | |
1399 if (cchar) | |
1400 scr_insert_text(cchar); | |
102 | 1401 } |
98 | 1402 } |
1403 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1404 static void scr_cancel_current_completion(void) |
98 | 1405 { |
1406 char *c; | |
1407 guint back = cancel_completion(); | |
1408 // Remove $back chars | |
1409 ptr_inputline -= back; | |
1410 c = ptr_inputline; | |
1411 for ( ; *c ; c++) | |
1412 *c = *(c+back); | |
1413 } | |
1414 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1415 static void scr_end_current_completion(void) |
98 | 1416 { |
1417 done_completion(); | |
1418 completion_started = FALSE; | |
1419 } | |
1420 | |
24 | 1421 // check_offset(int direction) |
1422 // Check inputline_offset value, and make sure the cursor is inside the | |
1423 // screen. | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1424 static inline void check_offset(int direction) |
24 | 1425 { |
1426 // Left side | |
1427 if (inputline_offset && direction <= 0) { | |
1428 while (ptr_inputline <= (char*)&inputLine + inputline_offset) { | |
1429 if (inputline_offset) { | |
1430 inputline_offset -= 5; | |
1431 if (inputline_offset < 0) | |
1432 inputline_offset = 0; | |
1433 } | |
1434 } | |
1435 } | |
1436 // Right side | |
1437 if (direction >= 0) { | |
1438 while (ptr_inputline >= inputline_offset + (char*)&inputLine + maxX) | |
1439 inputline_offset += 5; | |
1440 } | |
1441 } | |
1442 | |
336
eb994ee40029
Make some functions static
Mikael Berthe <mikael@lilotux.net>
parents:
332
diff
changeset
|
1443 static inline void refresh_inputline(void) |
312
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1444 { |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1445 mvwprintw(inputWnd, 0,0, "%s", inputLine + inputline_offset); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1446 wclrtoeol(inputWnd); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1447 if (*ptr_inputline) |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1448 wmove(inputWnd, 0, ptr_inputline - (char*)&inputLine - inputline_offset); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1449 } |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1450 |
389
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1451 void scr_handle_CtrlC(void) |
312
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1452 { |
365
ddb6593bedc9
Fix segfault when mcabber receives an INT signal (Ctrl-C) early
Mikael Berthe <mikael@lilotux.net>
parents:
364
diff
changeset
|
1453 if (!Curses) return; |
315
65aa05520556
First Ctrl-C now also leaves multi-line message mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1454 // Leave multi-line mode |
65aa05520556
First Ctrl-C now also leaves multi-line message mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1455 process_command("/msay abort"); |
312
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1456 // Same as Ctrl-g, now |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1457 scr_cancel_current_completion(); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1458 scr_end_current_completion(); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1459 check_offset(-1); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1460 refresh_inputline(); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1461 } |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1462 |
373
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1463 int scr_Getch(void) |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1464 { |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1465 int ch; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1466 ch = wgetch(inputWnd); |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1467 return ch; |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1468 } |
af2f8ddf6a1b
Move (reorganize) functions
Mikael Berthe <mikael@lilotux.net>
parents:
370
diff
changeset
|
1469 |
44 | 1470 // process_key(key) |
1471 // Handle the pressed key, in the command line (bottom). | |
29 | 1472 int process_key(int key) |
24 | 1473 { |
1474 if (isprint(key)) { | |
1475 char tmpLine[INPUTLINE_LENGTH+1]; | |
1476 | |
1477 // Check the line isn't too long | |
1478 if (strlen(inputLine) >= INPUTLINE_LENGTH) | |
1479 return 0; | |
1480 | |
1481 // Insert char | |
1482 strcpy(tmpLine, ptr_inputline); | |
1483 *ptr_inputline++ = key; | |
1484 strcpy(ptr_inputline, tmpLine); | |
1485 check_offset(1); | |
1486 } else { | |
1487 switch(key) { | |
232 | 1488 case 8: // Ctrl-h |
1489 case 127: // Backspace too | |
24 | 1490 case KEY_BACKSPACE: |
1491 if (ptr_inputline != (char*)&inputLine) { | |
42 | 1492 char *c = --ptr_inputline; |
1493 for ( ; *c ; c++) | |
1494 *c = *(c+1); | |
24 | 1495 check_offset(-1); |
1496 } | |
1497 break; | |
238 | 1498 case KEY_DC:// Del |
24 | 1499 if (*ptr_inputline) |
1500 strcpy(ptr_inputline, ptr_inputline+1); | |
1501 break; | |
1502 case KEY_LEFT: | |
1503 if (ptr_inputline != (char*)&inputLine) { | |
1504 ptr_inputline--; | |
1505 check_offset(-1); | |
1506 } | |
1507 break; | |
1508 case KEY_RIGHT: | |
1509 if (*ptr_inputline) | |
1510 ptr_inputline++; | |
1511 check_offset(1); | |
1512 break; | |
98 | 1513 case 7: // Ctrl-g |
1514 scr_cancel_current_completion(); | |
1515 scr_end_current_completion(); | |
1516 check_offset(-1); | |
1517 break; | |
24 | 1518 case 9: // Tab |
98 | 1519 scr_handle_tab(); |
1520 check_offset(0); | |
24 | 1521 break; |
389
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1522 case 13: // Enter |
263 | 1523 case 15: // Ctrl-o ("accept-line-and-down-history") |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1524 scr_CheckAutoAway(TRUE); |
29 | 1525 if (process_line(inputLine)) |
24 | 1526 return 255; |
173 | 1527 // Add line to history |
1528 scr_cmdhisto_addline(inputLine); | |
1529 // Reset the line | |
24 | 1530 ptr_inputline = inputLine; |
1531 *ptr_inputline = 0; | |
1532 inputline_offset = 0; | |
263 | 1533 |
389
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1534 if (key == 13) // Enter |
263 | 1535 { |
1536 // Reset history line pointer | |
1537 cmdhisto_cur = NULL; | |
1538 } else { // down-history | |
1539 // Use next history line instead of a blank line | |
1540 const char *l = scr_cmdhisto_next("", 0); | |
419 | 1541 if (l) strcpy(inputLine, l); |
263 | 1542 // Reset backup history line |
1543 cmdhisto_backup[0] = 0; | |
1544 } | |
24 | 1545 break; |
1546 case KEY_UP: | |
175 | 1547 { |
1548 const char *l = scr_cmdhisto_prev(inputLine, | |
1549 ptr_inputline-inputLine); | |
419 | 1550 if (l) strcpy(inputLine, l); |
175 | 1551 } |
24 | 1552 break; |
1553 case KEY_DOWN: | |
175 | 1554 { |
1555 const char *l = scr_cmdhisto_next(inputLine, | |
1556 ptr_inputline-inputLine); | |
419 | 1557 if (l) strcpy(inputLine, l); |
175 | 1558 } |
24 | 1559 break; |
1560 case KEY_PPAGE: | |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1561 scr_CheckAutoAway(TRUE); |
175 | 1562 scr_RosterUp(); |
24 | 1563 break; |
1564 case KEY_NPAGE: | |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1565 scr_CheckAutoAway(TRUE); |
175 | 1566 scr_RosterDown(); |
24 | 1567 break; |
1568 case KEY_HOME: | |
1569 case 1: | |
1570 ptr_inputline = inputLine; | |
1571 inputline_offset = 0; | |
1572 break; | |
389
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1573 case 3: // Ctrl-C |
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1574 scr_handle_CtrlC(); |
6e895f397474
Ncurses changes + Ctrl-C does not send a signal anylore
Mikael Berthe <mikael@lilotux.net>
parents:
388
diff
changeset
|
1575 break; |
24 | 1576 case KEY_END: |
1577 case 5: | |
1578 for (; *ptr_inputline; ptr_inputline++) ; | |
1579 check_offset(1); | |
1580 break; | |
1581 case 21: // Ctrl-u | |
1582 strcpy(inputLine, ptr_inputline); | |
1583 ptr_inputline = inputLine; | |
1584 inputline_offset = 0; | |
1585 break; | |
1586 case KEY_EOL: | |
1587 case 11: // Ctrl-k | |
1588 *ptr_inputline = 0; | |
1589 break; | |
1590 case 16: // Ctrl-p | |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
1591 scr_BufferScrollUpDown(-1); |
24 | 1592 break; |
1593 case 14: // Ctrl-n | |
369
499170ed71c9
Rename some buffer commands, for homogeneity
Mikael Berthe <mikael@lilotux.net>
parents:
365
diff
changeset
|
1594 scr_BufferScrollUpDown(1); |
24 | 1595 break; |
196 | 1596 case 17: // Ctrl-q |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1597 scr_CheckAutoAway(TRUE); |
236 | 1598 scr_RosterUnreadMessage(1); // next unread message |
196 | 1599 break; |
195 | 1600 case 20: // Ctrl-t |
1601 readline_transpose_chars(); | |
1602 break; | |
194 | 1603 case 23: // Ctrl-w |
195 | 1604 readline_backward_kill_word(); |
194 | 1605 break; |
24 | 1606 case 27: // ESC |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1607 scr_CheckAutoAway(TRUE); |
24 | 1608 currentWindow = NULL; |
1609 chatmode = FALSE; | |
119 | 1610 if (current_buddy) |
1611 buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, FALSE); | |
24 | 1612 top_panel(chatPanel); |
1613 top_panel(inputPanel); | |
157 | 1614 update_panels(); |
24 | 1615 break; |
151 | 1616 case 12: // Ctrl-l |
388
f211238d5812
Ctrl-l does a full refresh
Mikael Berthe <mikael@lilotux.net>
parents:
384
diff
changeset
|
1617 scr_CheckAutoAway(TRUE); |
f211238d5812
Ctrl-l does a full refresh
Mikael Berthe <mikael@lilotux.net>
parents:
384
diff
changeset
|
1618 redrawwin(stdscr); |
151 | 1619 case KEY_RESIZE: |
1620 scr_Resize(); | |
1621 break; | |
24 | 1622 default: |
288 | 1623 { |
1624 const gchar *boundcmd = isbound(key); | |
1625 if (boundcmd) { | |
1626 gchar *cmd = g_strdup_printf("/%s", boundcmd); | |
322
da138cdebf04
Implement auto-away mode
Mikael Berthe <mikael@lilotux.net>
parents:
314
diff
changeset
|
1627 scr_CheckAutoAway(TRUE); |
288 | 1628 if (process_command(cmd)) |
1629 return 255; | |
1630 g_free(cmd); | |
1631 } else { | |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1632 scr_LogPrint(LPRINT_NORMAL, "Unknown key=%d", key); |
288 | 1633 if (utf8_mode) |
374
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1634 scr_LogPrint(LPRINT_NORMAL, |
bd5638c21834
Improve logging system (traces)
Mikael Berthe <mikael@lilotux.net>
parents:
373
diff
changeset
|
1635 "WARNING: UTF-8 not yet supported!"); |
288 | 1636 } |
1637 } | |
24 | 1638 } |
1639 } | |
157 | 1640 if (completion_started && key != 9 && key != KEY_RESIZE) |
98 | 1641 scr_end_current_completion(); |
312
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1642 refresh_inputline(); |
f0b7ff2df7e8
Ctrl-C does not terminate mcabber
Mikael Berthe <mikael@lilotux.net>
parents:
307
diff
changeset
|
1643 if (!update_roster) |
157 | 1644 doupdate(); |
24 | 1645 return 0; |
1646 } |