Mercurial > pidgin
annotate src/prpl.c @ 11052:8a68c933a5dd
[gaim-migrate @ 12990]
Patch #1227165 from sadrul
This patch probes plugins when the plugin page is loaded in preferences. This allows users to activate newly installed plugins without restarting Gaim.
The only way I can see this being a problem is if you installed a plugin which was version-compatible but binary incompatible. (For example, you're working on Gaim HEAD and change a public struct in a way that's binary backwards incompatible, build a plugin against it, install the plugin, and open the preferences page of a running copy of Gaim from before the change.) Even then, depending on the particular plugin and binary incompatibility, you might have to activate the plugin before Gaim would crash.
So, unless I'm missing something, this should be safe. Let's see how it goes.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 03 Jul 2005 05:28:57 +0000 |
parents | b75ce371c812 |
children | 90be432e8385 |
rev | line source |
---|---|
981 | 1 /* |
2 * gaim | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
6460
ff4551719cc7
[gaim-migrate @ 6969]
Christian Hammond <chipx86@chipx86.com>
parents:
6371
diff
changeset
|
7 * |
981 | 8 * This program is free software; you can redistribute it and/or modify |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
23 #include "internal.h" |
5945
2a18e7b5917e
[gaim-migrate @ 6386]
Christian Hammond <chipx86@chipx86.com>
parents:
5943
diff
changeset
|
24 #include "conversation.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
25 #include "debug.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
26 #include "notify.h" |
981 | 27 #include "prpl.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
28 #include "request.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5717
diff
changeset
|
29 #include "util.h" |
3738 | 30 |
9949 | 31 /**************************************************************************/ |
32 /** @name Protocol Plugin API */ | |
33 /**************************************************************************/ | |
34 void | |
35 gaim_prpl_got_account_idle(GaimAccount *account, gboolean idle, | |
36 time_t idle_time) | |
37 { | |
38 g_return_if_fail(account != NULL); | |
39 g_return_if_fail(gaim_account_is_connected(account)); | |
40 | |
41 gaim_presence_set_idle(gaim_account_get_presence(account), | |
42 idle, idle_time); | |
43 } | |
44 | |
45 void | |
10870 | 46 gaim_prpl_got_account_login_time(GaimAccount *account, time_t login_time) |
9949 | 47 { |
48 GaimPresence *presence; | |
49 | |
50 g_return_if_fail(account != NULL); | |
51 g_return_if_fail(gaim_account_is_connected(account)); | |
52 | |
53 if (login_time == 0) | |
54 login_time = time(NULL); | |
55 | |
56 presence = gaim_account_get_presence(account); | |
57 | |
10007 | 58 gaim_presence_set_login_time(presence, login_time); |
9949 | 59 } |
60 | |
61 static gboolean | |
62 set_value_from_arg(GaimStatus *status, const char *id, va_list *args) | |
63 { | |
64 GaimValue *value; | |
65 | |
66 value = gaim_status_get_attr_value(status, id); | |
67 | |
68 if (value == NULL) | |
69 { | |
70 gaim_debug_error("prpl", | |
71 "Attempted to set an unknown attribute %s on " | |
72 "status %s\n", | |
73 id, gaim_status_get_id(status)); | |
74 return FALSE; | |
75 } | |
76 | |
77 switch (gaim_value_get_type(value)) | |
78 { | |
79 case GAIM_TYPE_CHAR: | |
80 gaim_value_set_char(value, (char)va_arg(*args, int)); | |
81 break; | |
82 | |
83 case GAIM_TYPE_UCHAR: | |
84 gaim_value_set_uchar(value, | |
85 (unsigned char)va_arg(*args, unsigned int)); | |
86 break; | |
87 | |
88 case GAIM_TYPE_BOOLEAN: | |
89 gaim_value_set_boolean(value, va_arg(*args, gboolean)); | |
90 break; | |
91 | |
92 case GAIM_TYPE_SHORT: | |
93 gaim_value_set_short(value, (short)va_arg(*args, int)); | |
94 break; | |
95 | |
96 case GAIM_TYPE_USHORT: | |
97 gaim_value_set_ushort(value, | |
98 (unsigned short)va_arg(*args, unsigned int)); | |
99 break; | |
100 | |
101 case GAIM_TYPE_INT: | |
102 gaim_value_set_int(value, va_arg(*args, int)); | |
103 break; | |
104 | |
105 case GAIM_TYPE_UINT: | |
106 gaim_value_set_uint(value, va_arg(*args, unsigned int)); | |
107 break; | |
108 | |
109 case GAIM_TYPE_LONG: | |
110 gaim_value_set_long(value, va_arg(*args, long)); | |
111 break; | |
112 | |
113 case GAIM_TYPE_ULONG: | |
114 gaim_value_set_ulong(value, va_arg(*args, unsigned long)); | |
115 break; | |
116 | |
117 case GAIM_TYPE_INT64: | |
118 gaim_value_set_int64(value, va_arg(*args, gint64)); | |
119 break; | |
120 | |
121 case GAIM_TYPE_UINT64: | |
122 gaim_value_set_uint64(value, va_arg(*args, guint64)); | |
123 break; | |
124 | |
125 case GAIM_TYPE_STRING: | |
126 gaim_value_set_string(value, va_arg(*args, char *)); | |
127 break; | |
128 | |
129 case GAIM_TYPE_OBJECT: | |
130 gaim_value_set_object(value, va_arg(*args, void *)); | |
131 break; | |
132 | |
133 case GAIM_TYPE_POINTER: | |
134 gaim_value_set_pointer(value, va_arg(*args, void *)); | |
135 break; | |
136 | |
137 case GAIM_TYPE_ENUM: | |
138 gaim_value_set_enum(value, va_arg(*args, int)); | |
139 break; | |
140 | |
141 case GAIM_TYPE_BOXED: | |
142 gaim_value_set_boxed(value, va_arg(*args, void *)); | |
143 break; | |
144 | |
145 default: | |
146 return FALSE; | |
147 } | |
148 | |
149 return TRUE; | |
150 } | |
151 | |
152 void | |
153 gaim_prpl_got_account_status(GaimAccount *account, const char *status_id, | |
154 const char *attr_id, ...) | |
155 { | |
156 GaimPresence *presence; | |
157 GaimStatus *status; | |
158 | |
159 g_return_if_fail(account != NULL); | |
160 g_return_if_fail(status_id != NULL); | |
161 g_return_if_fail(gaim_account_is_connected(account)); | |
162 | |
163 presence = gaim_account_get_presence(account); | |
164 status = gaim_presence_get_status(presence, status_id); | |
165 | |
166 g_return_if_fail(status != NULL); | |
167 | |
168 if (attr_id != NULL) | |
169 { | |
170 va_list args; | |
171 | |
172 va_start(args, attr_id); | |
173 | |
174 while (attr_id != NULL) | |
175 { | |
176 set_value_from_arg(status, attr_id, &args); | |
177 | |
178 attr_id = va_arg(args, char *); | |
179 } | |
180 | |
181 va_end(args); | |
182 } | |
183 | |
184 gaim_presence_set_status_active(presence, status_id, TRUE); | |
185 } | |
186 | |
187 void | |
188 gaim_prpl_got_account_warning_level(GaimAccount *account, const char *username, | |
189 unsigned int level) | |
190 { | |
191 GaimPresence *presence; | |
192 unsigned int old_level; | |
10007 | 193 gchar *buf; |
9949 | 194 |
195 g_return_if_fail(account != NULL); | |
196 | |
197 presence = gaim_account_get_presence(account); | |
198 | |
199 gaim_signal_emit(gaim_accounts_get_handle(), "account-warned", | |
200 account, username, level); | |
201 | |
202 old_level = gaim_presence_get_warning_level(presence); | |
203 gaim_presence_set_warning_level(presence, level); | |
204 | |
205 if (old_level >= level) | |
206 return; | |
207 | |
10007 | 208 if (username == NULL) |
209 buf = g_strdup_printf(_("%s has just been warned by an anonymous " | |
210 "person.\nYour new warning level is %d%%"), | |
211 gaim_account_get_username(account), | |
212 level); | |
213 else | |
214 buf = g_strdup_printf(_("%s has just been warned by %s.\n" | |
215 "Your new warning level is %d%%"), | |
216 gaim_account_get_username(account), | |
217 username, level); | |
9949 | 218 |
10007 | 219 gaim_notify_info(NULL, NULL, buf, NULL); |
220 | |
221 g_free(buf); | |
9949 | 222 } |
223 | |
224 void | |
225 gaim_prpl_got_user_idle(GaimAccount *account, const char *name, | |
226 gboolean idle, time_t idle_time) | |
227 { | |
10554 | 228 GSList *l; |
9949 | 229 |
230 g_return_if_fail(account != NULL); | |
231 g_return_if_fail(name != NULL); | |
232 g_return_if_fail(gaim_account_is_connected(account)); | |
233 | |
10554 | 234 for (l = gaim_find_buddies(account, name); l != NULL; l = l->next) |
235 { | |
236 GaimBuddy *buddy; | |
237 GaimPresence *presence; | |
9949 | 238 |
10554 | 239 buddy = (GaimBuddy *)l->data; |
10007 | 240 |
10554 | 241 presence = gaim_buddy_get_presence(buddy); |
242 | |
243 gaim_presence_set_idle(presence, idle, idle_time); | |
244 } | |
9949 | 245 } |
246 | |
247 void | |
248 gaim_prpl_got_user_login_time(GaimAccount *account, const char *name, | |
249 time_t login_time) | |
250 { | |
10554 | 251 GSList *l; |
9949 | 252 |
253 g_return_if_fail(account != NULL); | |
254 g_return_if_fail(name != NULL); | |
255 | |
10554 | 256 for (l = gaim_find_buddies(account, name); l != NULL; l = l->next) |
257 { | |
258 GaimBuddy *buddy; | |
259 GaimPresence *presence; | |
260 | |
261 buddy = (GaimBuddy *)l->data; | |
9949 | 262 |
10554 | 263 if (login_time == 0) |
264 login_time = time(NULL); | |
9949 | 265 |
10554 | 266 presence = gaim_buddy_get_presence(buddy); |
9949 | 267 |
10554 | 268 gaim_presence_set_login_time(presence, login_time); |
269 } | |
9949 | 270 } |
271 | |
272 void | |
273 gaim_prpl_got_user_status(GaimAccount *account, const char *name, | |
274 const char *status_id, const char *attr_id, ...) | |
275 { | |
10554 | 276 GSList *l; |
9949 | 277 |
278 g_return_if_fail(account != NULL); | |
279 g_return_if_fail(name != NULL); | |
280 g_return_if_fail(status_id != NULL); | |
281 g_return_if_fail(gaim_account_is_connected(account)); | |
282 | |
10554 | 283 for (l = gaim_find_buddies(account, name); l != NULL; l = l->next) |
284 { | |
285 GaimBuddy *buddy; | |
286 GaimPresence *presence; | |
287 GaimStatus *status; | |
288 GaimStatus *old_status; | |
9949 | 289 |
10554 | 290 buddy = (GaimBuddy *)l->data; |
291 presence = gaim_buddy_get_presence(buddy); | |
292 status = gaim_presence_get_status(presence, status_id); | |
9949 | 293 |
10554 | 294 g_return_if_fail(status != NULL); |
9949 | 295 |
10554 | 296 if (attr_id != NULL) |
297 { | |
298 va_list args; | |
9949 | 299 |
10554 | 300 va_start(args, attr_id); |
9949 | 301 |
10554 | 302 while (attr_id != NULL) |
303 { | |
304 set_value_from_arg(status, attr_id, &args); | |
9949 | 305 |
10554 | 306 attr_id = va_arg(args, char *); |
307 } | |
308 | |
309 va_end(args); | |
9949 | 310 } |
311 | |
10554 | 312 old_status = gaim_presence_get_active_status(presence); |
313 gaim_presence_set_status_active(presence, status_id, TRUE); | |
314 gaim_blist_update_buddy_status(buddy, old_status); | |
9949 | 315 } |
316 } | |
317 | |
318 void | |
319 gaim_prpl_got_user_warning_level(GaimAccount *account, const char *name, | |
320 unsigned int level) | |
321 { | |
10554 | 322 GSList *l; |
9949 | 323 |
324 g_return_if_fail(account != NULL); | |
325 g_return_if_fail(name != NULL); | |
326 | |
10554 | 327 for (l = gaim_find_buddies(account, name); l != NULL; l = l->next) |
328 { | |
329 GaimBuddy *buddy; | |
330 GaimPresence *presence; | |
9949 | 331 |
10554 | 332 buddy = (GaimBuddy *)l->data; |
10007 | 333 |
10554 | 334 presence = gaim_buddy_get_presence(buddy); |
335 | |
336 gaim_presence_set_warning_level(presence, level); | |
337 } | |
9949 | 338 } |
339 | |
340 void | |
10447 | 341 gaim_prpl_change_account_status(GaimAccount *account, |
342 GaimStatus *old_status, GaimStatus *new_status) | |
9949 | 343 { |
344 GaimPlugin *prpl; | |
345 GaimPluginProtocolInfo *prpl_info; | |
346 | |
10447 | 347 g_return_if_fail(account != NULL); |
348 g_return_if_fail(old_status != NULL); | |
349 g_return_if_fail(new_status != NULL); | |
9949 | 350 |
351 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); | |
352 | |
353 if (prpl == NULL) | |
354 return; | |
355 | |
356 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); | |
357 | |
358 if (prpl_info->set_status != NULL) | |
10447 | 359 prpl_info->set_status(account, new_status); |
9949 | 360 } |
361 | |
10006 | 362 GList * |
363 gaim_prpl_get_statuses(GaimAccount *account, GaimPresence *presence) | |
364 { | |
365 GaimPlugin *prpl; | |
366 GaimPluginProtocolInfo *prpl_info; | |
367 GList *statuses = NULL; | |
368 GList *l; | |
369 GaimStatus *status; | |
370 | |
10447 | 371 g_return_val_if_fail(account != NULL, NULL); |
10006 | 372 g_return_val_if_fail(presence != NULL, NULL); |
373 | |
374 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); | |
10046 | 375 |
10006 | 376 if (prpl == NULL) |
377 return NULL; | |
10046 | 378 |
10006 | 379 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
380 if (prpl_info == NULL || prpl_info->status_types == NULL) | |
381 return NULL; | |
382 | |
383 for (l = prpl_info->status_types(account); l != NULL; l = l->next) | |
384 { | |
385 status = gaim_status_new((GaimStatusType *)l->data, presence); | |
386 statuses = g_list_append(statuses, status); | |
387 } | |
388 | |
389 return statuses; | |
390 } | |
391 | |
9949 | 392 |
393 /************************************************************************** | |
394 * Protocol Plugin Subsystem API | |
395 **************************************************************************/ | |
396 | |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
397 GaimPlugin * |
7956 | 398 gaim_find_prpl(const char *id) |
981 | 399 { |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5563
diff
changeset
|
400 GList *l; |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
401 GaimPlugin *plugin; |
981 | 402 |
10036
0ddc38f8db4a
[gaim-migrate @ 10995]
Luke Schierer <lschiere@pidgin.im>
parents:
10023
diff
changeset
|
403 g_return_val_if_fail(id != NULL, NULL); |
0ddc38f8db4a
[gaim-migrate @ 10995]
Luke Schierer <lschiere@pidgin.im>
parents:
10023
diff
changeset
|
404 |
5573
5e7de337a053
[gaim-migrate @ 5976]
Christian Hammond <chipx86@chipx86.com>
parents:
5563
diff
changeset
|
405 for (l = gaim_plugins_get_protocols(); l != NULL; l = l->next) { |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
406 plugin = (GaimPlugin *)l->data; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
407 |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
408 /* Just In Case (TM) */ |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
409 if (GAIM_IS_PROTOCOL_PLUGIN(plugin)) { |
7956 | 410 if (!strcmp(plugin->info->id, id)) |
5205
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
411 return plugin; |
fefad67de2c7
[gaim-migrate @ 5573]
Christian Hammond <chipx86@chipx86.com>
parents:
5161
diff
changeset
|
412 } |
981 | 413 } |
414 | |
415 return NULL; | |
416 } |