Mercurial > pidgin
annotate src/protocols/icq/gaim_icq.c @ 2138:cfa83a1b3d49
[gaim-migrate @ 2148]
hopefully fixes any problems we might have with icq. also makes it so we can receive messages from people whose names are longer than 64 characters. this should be arbitrary.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Wed, 08 Aug 2001 20:09:57 +0000 |
parents | 18722ae5b882 |
children | cff133e0ec0c |
rev | line source |
---|---|
2086 | 1 #include <gtk/gtk.h> |
2 #include <string.h> | |
3 #include <stdlib.h> | |
4 #include "icq.h" /* well, we're doing ICQ, right? */ | |
5 #include "multi.h" /* needed for gaim_connection */ | |
6 #include "prpl.h" /* needed for prpl */ | |
7 #include "gaim.h" /* needed for every other damn thing */ | |
8 #include "proxy.h" | |
9 | |
10 #include "pixmaps/gnomeicu-online.xpm" | |
11 #include "pixmaps/gnomeicu-away.xpm" | |
12 #include "pixmaps/gnomeicu-dnd.xpm" | |
13 #include "pixmaps/gnomeicu-na.xpm" | |
14 #include "pixmaps/gnomeicu-occ.xpm" | |
15 #include "pixmaps/gnomeicu-ffc.xpm" | |
16 | |
17 #define USEROPT_NICK 0 | |
18 | |
19 struct icq_data { | |
20 icq_Link *link; | |
21 int cur_status; | |
22 GSList *thru_serv; | |
23 }; | |
24 | |
25 static guint ack_timer = 0; | |
26 | |
27 static char *icq_name() { | |
28 return "ICQ"; | |
29 } | |
30 | |
31 static void icq_do_log(icq_Link *link, time_t time, unsigned char level, const char *log) { | |
32 debug_printf("ICQ debug %d: %s", level, log); | |
33 } | |
34 | |
35 GList *sockets = NULL; | |
36 struct gaim_sock { | |
37 int socket; | |
38 int type; | |
39 gint inpa; | |
40 }; | |
41 | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
42 static void gaim_icq_handler(gpointer data, gint source, GaimInputCondition cond) { |
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
43 if (cond & GAIM_INPUT_READ) |
2086 | 44 icq_HandleReadySocket(source, ICQ_SOCKET_READ); |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
45 if (cond & GAIM_INPUT_WRITE) |
2086 | 46 icq_HandleReadySocket(source, ICQ_SOCKET_WRITE); |
47 } | |
48 | |
49 static void icq_sock_notify(int socket, int type, int status) { | |
50 struct gaim_sock *gs = NULL; | |
51 if (status) { | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
52 GaimInputCondition cond; |
2086 | 53 if (type == ICQ_SOCKET_READ) |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
54 cond = GAIM_INPUT_READ; |
2086 | 55 else |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
56 cond = GAIM_INPUT_WRITE; |
2086 | 57 gs = g_new0(struct gaim_sock, 1); |
58 gs->socket = socket; | |
59 gs->type = type; | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
60 gs->inpa = gaim_input_add(socket, cond, gaim_icq_handler, NULL); |
2086 | 61 sockets = g_list_append(sockets, gs); |
62 debug_printf("Adding socket notifier: %d %d (%d)\n", socket, type, gs->inpa); | |
63 } else { | |
64 GList *m = sockets; | |
65 while (m) { | |
66 gs = m->data; | |
67 if ((gs->socket == socket) && (gs->type == type)) | |
68 break; | |
69 m = g_list_next(m); | |
70 } | |
71 if (m) { | |
2090
b66aca8e8dce
[gaim-migrate @ 2100]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
72 gaim_input_remove(gs->inpa); |
2086 | 73 sockets = g_list_remove(sockets, gs); |
74 debug_printf("Removing socket notifier: %d %d (%d)\n", socket, type, gs->inpa); | |
75 g_free(gs); | |
76 } | |
77 } | |
78 } | |
79 | |
80 static void icq_online(icq_Link *link) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
81 struct gaim_connection *gc = link->icq_UserData; |
2086 | 82 struct icq_data *id = (struct icq_data *)gc->proto_data; |
83 debug_printf("%s is now online.\n", gc->username); | |
84 account_online(gc); | |
85 /*gc->options |= OPT_USR_KEEPALV; this is always-on now */ | |
86 serv_finish_login(gc); | |
87 | |
88 icq_ChangeStatus(id->link, STATUS_ONLINE); | |
89 } | |
90 | |
91 static void icq_logged_off(icq_Link *link) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
92 struct gaim_connection *gc = link->icq_UserData; |
2086 | 93 struct icq_data *id = (struct icq_data *)gc->proto_data; |
94 | |
95 if (icq_Connect(link, "icq.mirabilis.com", 4000) < 1) { | |
96 hide_login_progress(gc, "Unable to connect"); | |
97 signoff(gc); | |
98 return; | |
99 } | |
100 | |
101 icq_Login(link, STATUS_ONLINE); | |
102 id->cur_status = STATUS_ONLINE; | |
103 } | |
104 | |
105 void strip_linefeed(gchar *text) | |
106 { | |
107 int i, j; | |
108 gchar *text2 = g_malloc(strlen(text) + 1); | |
109 | |
110 for (i = 0, j = 0; text[i]; i++) | |
111 if (text[i] != '\r') | |
112 text2[j++] = text[i]; | |
113 text2[j] = '\0'; | |
114 | |
115 strcpy(text, text2); | |
116 g_free(text2); | |
117 } | |
118 | |
119 static void icq_msg_incoming(icq_Link *link, unsigned long uin, unsigned char hour, unsigned char minute, | |
120 unsigned char day, unsigned char month, unsigned short year, const char *data) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
121 struct gaim_connection *gc = link->icq_UserData; |
2086 | 122 char buf[256], *tmp = g_malloc(BUF_LONG); |
123 g_snprintf(tmp, BUF_LONG, "%s", data); | |
124 g_snprintf(buf, sizeof buf, "%lu", uin); | |
125 strip_linefeed(tmp); | |
126 serv_got_im(gc, buf, tmp, 0, time((time_t)NULL)); | |
127 g_free(tmp); | |
128 } | |
129 | |
130 static void icq_user_online(icq_Link *link, unsigned long uin, unsigned long st, | |
131 unsigned long ip, unsigned short port, unsigned long real_ip, | |
132 unsigned char tcp_flags) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
133 struct gaim_connection *gc = link->icq_UserData; |
2086 | 134 guint status; |
135 char buf[256]; | |
136 | |
137 g_snprintf(buf, sizeof buf, "%lu", uin); | |
138 status = (st == STATUS_ONLINE) ? UC_NORMAL : UC_UNAVAILABLE | (st << 5); | |
139 serv_got_update(gc, buf, 1, 0, 0, 0, status, 0); | |
140 } | |
141 | |
142 static void icq_user_offline(icq_Link *link, unsigned long uin) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
143 struct gaim_connection *gc = link->icq_UserData; |
2086 | 144 char buf[256]; g_snprintf(buf, sizeof buf, "%lu", uin); |
145 serv_got_update(gc, buf, 0, 0, 0, 0, 0, 0); | |
146 } | |
147 | |
148 static void icq_user_status(icq_Link *link, unsigned long uin, unsigned long st) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
149 struct gaim_connection *gc = link->icq_UserData; |
2086 | 150 guint status; |
151 char buf[256]; | |
152 | |
153 g_snprintf(buf, sizeof buf, "%lu", uin); | |
154 status = (st == STATUS_ONLINE) ? UC_NORMAL : UC_UNAVAILABLE | (st << 5); | |
155 serv_got_update(gc, buf, 1, 0, 0, 0, status, 0); | |
156 } | |
157 | |
2130
50c7a704ee56
[gaim-migrate @ 2140]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
158 static gboolean icq_set_timeout_cb(gpointer data) { |
2086 | 159 icq_HandleTimeout(); |
160 ack_timer = 0; | |
161 return FALSE; | |
162 } | |
163 | |
164 static void icq_set_timeout(long interval) { | |
165 debug_printf("icq_SetTimeout: %ld\n", interval); | |
166 if (interval > 0 && ack_timer == 0) | |
2130
50c7a704ee56
[gaim-migrate @ 2140]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
167 ack_timer = g_timeout_add(interval * 1000, icq_set_timeout_cb, NULL); |
2086 | 168 else if (ack_timer > 0) { |
2130
50c7a704ee56
[gaim-migrate @ 2140]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2123
diff
changeset
|
169 g_source_remove(ack_timer); |
2086 | 170 ack_timer = 0; |
171 } | |
172 } | |
173 | |
174 static void icq_url_incoming(icq_Link *link, unsigned long uin, unsigned char hour, | |
175 unsigned char minute, unsigned char day, unsigned char month, | |
176 unsigned short year, const char *url, const char *descr) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
177 struct gaim_connection *gc = link->icq_UserData; |
2086 | 178 char *msg = g_malloc(BUF_LONG), buf[256]; |
179 g_snprintf(msg, BUF_LONG, "<A HREF=\"%s\">%s</A>", url, descr); | |
180 g_snprintf(buf, 256, "%lu", uin); | |
181 serv_got_im(gc, buf, msg, 0, time((time_t)NULL)); | |
182 g_free(msg); | |
183 } | |
184 | |
185 static void icq_wrong_passwd(icq_Link *link) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
186 struct gaim_connection *gc = link->icq_UserData; |
2086 | 187 hide_login_progress(gc, "Invalid password."); |
188 signoff(gc); | |
189 } | |
190 | |
191 static void icq_invalid_uin(icq_Link *link) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
192 struct gaim_connection *gc = link->icq_UserData; |
2086 | 193 hide_login_progress(gc, "Invalid UIN."); |
194 signoff(gc); | |
195 } | |
196 | |
197 static void icq_info_reply(icq_Link *link, unsigned long uin, const char *nick, | |
198 const char *first, const char *last, const char *email, char auth) { | |
199 char buf[16 * 1024]; | |
200 | |
201 g_snprintf(buf, sizeof buf, | |
202 "<B>UIN:</B> %lu<BR>" | |
203 "<B>Nick:</B> %s<BR>" | |
204 "<B>Name:</B> %s %s<BR>" | |
205 "<B>Email:</B> %s\n", | |
206 uin, | |
207 nick, | |
208 first, last, | |
209 email); | |
2137
18722ae5b882
[gaim-migrate @ 2147]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2130
diff
changeset
|
210 g_show_info_text(buf, NULL); |
2086 | 211 } |
212 | |
213 static void icq_web_pager(icq_Link *link, unsigned char hour, unsigned char minute, | |
214 unsigned char day, unsigned char month, unsigned short year, const char *nick, | |
215 const char *email, const char *msg) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
216 struct gaim_connection *gc = link->icq_UserData; |
2086 | 217 char *who = g_strdup_printf("ICQ Web Pager: %s (%s)", nick, email); |
218 char *what = g_malloc(BUF_LONG); | |
219 g_snprintf(what, BUF_LONG, "%s", msg); | |
220 serv_got_im(gc, who, what, 0, time((time_t)NULL)); | |
221 g_free(who); | |
222 g_free(what); | |
223 } | |
224 | |
225 static void icq_mail_express(icq_Link *link, unsigned char hour, unsigned char minute, | |
226 unsigned char day, unsigned char month, unsigned short year, const char *nick, | |
227 const char *email, const char *msg) { | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
228 struct gaim_connection *gc = link->icq_UserData; |
2086 | 229 char *who = g_strdup_printf("ICQ Mail Express: %s (%s)", nick, email); |
230 char *what = g_malloc(BUF_LONG); | |
231 g_snprintf(what, BUF_LONG, "%s", msg); | |
232 serv_got_im(gc, who, what, 0, time((time_t)NULL)); | |
233 g_free(who); | |
234 g_free(what); | |
235 } | |
236 | |
237 static void icq_req_not(icq_Link *link, unsigned long id, int type, int arg, void *data) { | |
238 if (type == ICQ_NOTIFY_FAILED) | |
239 do_error_dialog("Failure in sending packet", "ICQ error"); | |
240 return; | |
241 } | |
242 | |
243 struct icq_auth { | |
244 icq_Link *link; | |
245 unsigned long uin; | |
246 }; | |
247 | |
248 static void icq_den_auth(gpointer x, struct icq_auth *iq) | |
249 { | |
250 g_free(iq); | |
251 } | |
252 | |
253 static void icq_acc_auth(gpointer x, struct icq_auth *iq) | |
254 { | |
255 icq_SendAuthMsg(iq->link, iq->uin); | |
256 } | |
257 | |
258 static void icq_auth_req(icq_Link *link, unsigned long uin, unsigned char hour, unsigned char minute, | |
259 unsigned char day, unsigned char month, unsigned short year, const char *nick, | |
260 const char *first, const char *last, const char *email, const char *reason) | |
261 { | |
262 char msg[8192]; | |
263 struct icq_auth *iq = g_new0(struct icq_auth, 1); | |
264 iq->link = link; | |
265 iq->uin = uin; | |
266 | |
267 g_snprintf(msg, sizeof(msg), "The user %s (%s%s%s%s%s) wants you to authorize them.", | |
268 nick, first ? first : "", first && last ? " " : "", last ? last : "", | |
269 (first || last) && email ? ", " : "", email ? email : ""); | |
270 do_ask_dialog(msg, iq, icq_acc_auth, icq_den_auth); | |
271 } | |
272 | |
273 static void icq_login(struct aim_user *user) { | |
274 struct gaim_connection *gc = new_gaim_conn(user); | |
275 struct icq_data *id = gc->proto_data = g_new0(struct icq_data, 1); | |
276 icq_Link *link; | |
277 char ps[9]; | |
278 | |
279 icq_LogLevel = ICQ_LOG_MESSAGE; | |
280 | |
281 g_snprintf(ps, sizeof(ps), "%s", user->password); | |
282 link = id->link = icq_ICQLINKNew(atol(user->username), ps, | |
283 user->proto_opt[USEROPT_NICK][0] ? user->proto_opt[USEROPT_NICK] : "gaim user", | |
284 TRUE); | |
285 | |
286 link->icq_Logged = icq_online; | |
287 link->icq_Disconnected = icq_logged_off; | |
288 link->icq_RecvMessage = icq_msg_incoming; | |
289 link->icq_RecvURL = icq_url_incoming; | |
290 link->icq_RecvWebPager = icq_web_pager; | |
291 link->icq_RecvMailExpress = icq_mail_express; | |
292 link->icq_RecvAuthReq = icq_auth_req; | |
293 link->icq_UserOnline = icq_user_online; | |
294 link->icq_UserOffline = icq_user_offline; | |
295 link->icq_UserStatusUpdate = icq_user_status; | |
296 link->icq_InfoReply = icq_info_reply; | |
297 link->icq_WrongPassword = icq_wrong_passwd; | |
298 link->icq_InvalidUIN = icq_invalid_uin; | |
299 link->icq_Log = icq_do_log; | |
300 link->icq_RequestNotify = icq_req_not; | |
2138
cfa83a1b3d49
[gaim-migrate @ 2148]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2137
diff
changeset
|
301 link->icq_UserData = gc; |
2086 | 302 |
303 if (proxytype == PROXY_SOCKS5) | |
304 icq_SetProxy(link, proxyhost, proxyport, proxyuser[0], proxyuser, proxypass); | |
305 | |
306 icq_ContactClear(id->link); | |
307 if (bud_list_cache_exists(gc)) | |
308 do_import(NULL, gc); | |
309 | |
310 if (icq_Connect(link, "icq.mirabilis.com", 4000) < 1) { | |
311 hide_login_progress(gc, "Unable to connect"); | |
312 signoff(gc); | |
313 return; | |
314 } | |
315 | |
316 icq_Login(link, STATUS_ONLINE); | |
317 id->cur_status = STATUS_ONLINE; | |
318 | |
319 set_login_progress(gc, 0, "Connecting..."); | |
320 } | |
321 | |
322 static void icq_close(struct gaim_connection *gc) { | |
323 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
324 | |
325 icq_Logout(id->link); | |
326 icq_Disconnect(id->link); | |
327 icq_ICQLINKDelete(id->link); | |
328 g_slist_free(id->thru_serv); | |
329 g_free(id); | |
330 } | |
331 | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
332 static int icq_send_msg(struct gaim_connection *gc, char *who, char *msg, int away) { |
2086 | 333 if (!away && (strlen(msg) > 0)) { |
334 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
335 GSList *l = id->thru_serv; | |
336 long w = atol(who); | |
337 while (l) { | |
338 if (w == (long)l->data) | |
339 break; | |
340 l = l->next; | |
341 } | |
342 icq_SendMessage(id->link, w, msg, l ? ICQ_SEND_THRUSERVER : ICQ_SEND_BESTWAY); | |
343 } | |
2123
56c4382f2909
[gaim-migrate @ 2133]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2090
diff
changeset
|
344 return 0; |
2086 | 345 } |
346 | |
347 static void icq_keepalive(struct gaim_connection *gc) { | |
348 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
349 icq_KeepAlive(id->link); | |
350 } | |
351 | |
352 static void icq_add_buddy(struct gaim_connection *gc, char *who) { | |
353 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
354 icq_ContactAdd(id->link, atol(who)); | |
355 icq_ContactSetVis(id->link, atol(who), TRUE); | |
356 } | |
357 | |
358 static void icq_add_buddies(struct gaim_connection *gc, GList *whos) { | |
359 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
360 while (whos) { | |
361 icq_ContactAdd(id->link, atol(whos->data)); | |
362 icq_ContactSetVis(id->link, atol(whos->data), TRUE); | |
363 whos = whos->next; | |
364 } | |
365 } | |
366 | |
367 static void icq_rem_buddy(struct gaim_connection *gc, char *who) { | |
368 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
369 icq_ContactRemove(id->link, atol(who)); | |
370 } | |
371 | |
372 static void icq_set_away(struct gaim_connection *gc, char *state, char *msg) { | |
373 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
374 | |
375 if (gc->away) | |
376 gc->away = NULL; | |
377 | |
378 if (!strcmp(state, "Online")) | |
379 icq_ChangeStatus(id->link, STATUS_ONLINE); | |
380 else if (!strcmp(state, "Away")) { | |
381 icq_ChangeStatus(id->link, STATUS_AWAY); | |
382 gc->away = ""; | |
383 } else if (!strcmp(state, "Do Not Disturb")) { | |
384 icq_ChangeStatus(id->link, STATUS_DND); | |
385 gc->away = ""; | |
386 } else if (!strcmp(state, "Not Available")) { | |
387 icq_ChangeStatus(id->link, STATUS_NA); | |
388 gc->away = ""; | |
389 } else if (!strcmp(state, "Occupied")) { | |
390 icq_ChangeStatus(id->link, STATUS_OCCUPIED); | |
391 gc->away = ""; | |
392 } else if (!strcmp(state, "Free For Chat")) { | |
393 icq_ChangeStatus(id->link, STATUS_FREE_CHAT); | |
394 gc->away = ""; | |
395 } else if (!strcmp(state, "Invisible")) { | |
396 icq_ChangeStatus(id->link, STATUS_INVISIBLE); | |
397 gc->away = ""; | |
398 } else if (!strcmp(state, GAIM_AWAY_CUSTOM)) { | |
399 if (msg) { | |
400 icq_ChangeStatus(id->link, STATUS_NA); | |
401 gc->away = ""; | |
402 } else { | |
403 icq_ChangeStatus(id->link, STATUS_ONLINE); | |
404 } | |
405 } | |
406 } | |
407 | |
408 static char **icq_list_icon(int uc) { | |
409 guint status; | |
410 if (uc == UC_NORMAL) | |
411 return icon_online_xpm; | |
412 status = uc >> 5; | |
413 if (status & STATUS_NA) | |
414 return icon_na_xpm; | |
415 if (status & STATUS_DND) | |
416 return icon_dnd_xpm; | |
417 if (status & STATUS_OCCUPIED) | |
418 return icon_occ_xpm; | |
419 if (status & STATUS_AWAY) | |
420 return icon_away_xpm; | |
421 if (status & STATUS_FREE_CHAT) | |
422 return icon_ffc_xpm; | |
423 if (status & STATUS_INVISIBLE) | |
424 return NULL; | |
425 return icon_online_xpm; | |
426 } | |
427 | |
428 static void icq_get_info(struct gaim_connection *gc, char *who) { | |
429 struct icq_data *id = (struct icq_data *)gc->proto_data; | |
430 icq_SendInfoReq(id->link, atol(who)); | |
431 } | |
432 | |
433 static void icq_info(GtkObject *obj, char *who) { | |
434 serv_get_info(gtk_object_get_user_data(obj), who); | |
435 } | |
436 | |
437 static void icq_buddy_menu(GtkWidget *menu, struct gaim_connection *gc, char *who) { | |
438 GtkWidget *button; | |
439 | |
440 button = gtk_menu_item_new_with_label(_("Get Info")); | |
441 gtk_signal_connect(GTK_OBJECT(button), "activate", | |
442 GTK_SIGNAL_FUNC(icq_info), who); | |
443 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
444 gtk_menu_append(GTK_MENU(menu), button); | |
445 gtk_widget_show(button); | |
446 } | |
447 | |
448 static void icq_print_option(GtkEntry *entry, struct aim_user *user) { | |
449 int entrynum; | |
450 | |
451 entrynum = (int) gtk_object_get_user_data(GTK_OBJECT(entry)); | |
452 | |
453 if (entrynum == USEROPT_NICK) | |
454 g_snprintf(user->proto_opt[USEROPT_NICK], | |
455 sizeof(user->proto_opt[USEROPT_NICK]), | |
456 "%s", gtk_entry_get_text(entry)); | |
457 } | |
458 | |
459 static void icq_user_opts(GtkWidget *book, struct aim_user *user) { | |
460 GtkWidget *vbox; | |
461 GtkWidget *hbox; | |
462 GtkWidget *label; | |
463 GtkWidget *entry; | |
464 | |
465 vbox = gtk_vbox_new(FALSE, 5); | |
466 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); | |
467 gtk_notebook_append_page(GTK_NOTEBOOK(book), vbox, | |
468 gtk_label_new("ICQ Options")); | |
469 gtk_widget_show(vbox); | |
470 | |
471 hbox = gtk_hbox_new(FALSE, 5); | |
472 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
473 gtk_widget_show(hbox); | |
474 | |
475 label = gtk_label_new("Nick"); | |
476 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
477 gtk_widget_show(label); | |
478 | |
479 entry = gtk_entry_new(); | |
480 gtk_box_pack_end(GTK_BOX(hbox), entry, FALSE, FALSE, 0); | |
481 gtk_object_set_user_data(GTK_OBJECT(entry), (void *)USEROPT_NICK); | |
482 gtk_signal_connect(GTK_OBJECT(entry), "changed", | |
483 GTK_SIGNAL_FUNC(icq_print_option), user); | |
484 if (user->proto_opt[USEROPT_NICK][0]) | |
485 gtk_entry_set_text(GTK_ENTRY(entry), user->proto_opt[USEROPT_NICK]); | |
486 else | |
487 gtk_entry_set_text(GTK_ENTRY(entry), "gaim user"); | |
488 gtk_widget_show(entry); | |
489 | |
490 hbox = gtk_hbox_new(FALSE, 5); | |
491 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
492 gtk_widget_show(hbox); | |
493 } | |
494 | |
495 static GList *icq_away_states() { | |
496 GList *m = NULL; | |
497 | |
498 m = g_list_append(m, "Online"); | |
499 m = g_list_append(m, "Away"); | |
500 m = g_list_append(m, "Do Not Disturb"); | |
501 m = g_list_append(m, "Not Available"); | |
502 m = g_list_append(m, "Occupied"); | |
503 m = g_list_append(m, "Free For Chat"); | |
504 m = g_list_append(m, "Invisible"); | |
505 | |
506 return m; | |
507 } | |
508 | |
509 static void toggle_thru_serv(GtkToggleButton *button, struct conversation *c) | |
510 { | |
511 struct gaim_connection *gc = gtk_object_get_user_data(GTK_OBJECT(button)); | |
512 struct icq_data *id = gc->proto_data; | |
513 GSList *l = id->thru_serv; | |
514 long who = atol(c->name); | |
515 | |
516 while (l) { | |
517 if (who == (long)l->data) | |
518 break; | |
519 l = l->next; | |
520 } | |
521 if (l) | |
522 id->thru_serv = g_slist_remove(id->thru_serv, (void *)who); | |
523 else | |
524 id->thru_serv = g_slist_append(id->thru_serv, (void *)who); | |
525 } | |
526 | |
527 static void icq_insert_convo(struct gaim_connection *gc, struct conversation *c) | |
528 { | |
529 GtkWidget *button; | |
530 struct icq_data *id = gc->proto_data; | |
531 GSList *l = id->thru_serv; | |
532 long who = atol(c->name); | |
533 | |
534 button = gtk_check_button_new_with_label("Send message through server"); | |
535 gtk_box_pack_start(GTK_BOX(c->lbox), button, FALSE, FALSE, 5); | |
536 gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(toggle_thru_serv), c); | |
537 gtk_object_set_user_data(GTK_OBJECT(button), gc); | |
538 while (l) { | |
539 if (who == (long)l->data) | |
540 break; | |
541 l = l->next; | |
542 } | |
543 if (l) | |
544 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | |
545 gtk_widget_show(button); | |
546 } | |
547 | |
548 static void icq_remove_convo(struct gaim_connection *gc, struct conversation *c) | |
549 { | |
550 while (GTK_BOX(c->lbox)->children) | |
551 gtk_container_remove(GTK_CONTAINER(c->lbox), | |
552 ((GtkBoxChild *)GTK_BOX(c->lbox)->children->data)->widget); | |
553 } | |
554 | |
555 static struct prpl *my_protocol = NULL; | |
556 | |
557 void icq_init(struct prpl *ret) { | |
558 ret->protocol = PROTO_ICQ; | |
559 ret->name = icq_name; | |
560 ret->list_icon = icq_list_icon; | |
561 ret->away_states = icq_away_states; | |
562 ret->buddy_menu = icq_buddy_menu; | |
563 ret->user_opts = icq_user_opts; | |
564 ret->insert_convo = icq_insert_convo; | |
565 ret->remove_convo = icq_remove_convo; | |
566 ret->login = icq_login; | |
567 ret->close = icq_close; | |
568 ret->send_im = icq_send_msg; | |
569 ret->add_buddy = icq_add_buddy; | |
570 ret->add_buddies = icq_add_buddies; | |
571 ret->remove_buddy = icq_rem_buddy; | |
572 ret->get_info = icq_get_info; | |
573 ret->set_away = icq_set_away; | |
574 ret->keepalive = icq_keepalive; | |
575 | |
576 my_protocol = ret; | |
577 | |
578 icq_SocketNotify = icq_sock_notify; | |
579 icq_SetTimeout = icq_set_timeout; | |
580 } | |
581 | |
582 #ifndef STATIC | |
583 | |
584 char *gaim_plugin_init(GModule *handle) | |
585 { | |
586 load_protocol(icq_init, sizeof(struct prpl)); | |
587 return NULL; | |
588 } | |
589 | |
590 void gaim_plugin_remove() | |
591 { | |
592 struct prpl *p = find_prpl(PROTO_ICQ); | |
593 if (p == my_protocol) | |
594 unload_protocol(p); | |
595 } | |
596 | |
597 char *name() | |
598 { | |
599 return "ICQ"; | |
600 } | |
601 | |
602 char *description() | |
603 { | |
604 return "Allows gaim to use the ICQ protocol"; | |
605 } | |
606 | |
607 #endif |