Mercurial > pidgin
annotate plugins/tcl/tcl_cmds.c @ 13810:a84523152a24
[gaim-migrate @ 16240]
This is not a completed update, but it has useful bits and bug fixes
and the completed update will take some more time.
This adds support for some of the status API to Tcl, as well as
improving the handling of several of the pointer types (by introducing
a gaim reference object type and appropriate string roundtrip
functions) and introducing some "type safety".
committer: Tailor Script <tailor@pidgin.im>
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sat, 10 Jun 2006 18:01:11 +0000 |
parents | ae682fa78d7f |
children | 724e4c08391a |
rev | line source |
---|---|
6694 | 1 /** |
2 * @file tcl_cmds.c Commands for the Gaim Tcl plugin bindings | |
3 * | |
4 * gaim | |
5 * | |
6 * Copyright (C) 2003 Ethan Blanton <eblanton@cs.purdue.edu> | |
7 * | |
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 | |
23 #include <tcl.h> | |
24 | |
25 #include "internal.h" | |
26 #include "conversation.h" | |
27 #include "connection.h" | |
28 #include "account.h" | |
29 #include "server.h" | |
30 #include "notify.h" | |
6700 | 31 #include "blist.h" |
6694 | 32 #include "debug.h" |
33 #include "prefs.h" | |
34 #include "core.h" | |
35 | |
36 #include "tcl_gaim.h" | |
37 | |
13810 | 38 static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); |
39 static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); | |
6694 | 40 static gboolean tcl_validate_gc(GaimConnection *gc); |
41 | |
13810 | 42 static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) |
6694 | 43 { |
13810 | 44 GaimAccount *account; |
6694 | 45 GList *cur; |
13810 | 46 |
47 account = gaim_tcl_ref_get(interp, obj, GaimTclRefAccount); | |
48 | |
49 if (account == NULL) | |
50 return NULL; | |
51 | |
6694 | 52 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { |
53 if (account == cur->data) | |
13810 | 54 return account; |
6694 | 55 } |
56 if (interp != NULL) | |
57 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); | |
13810 | 58 return NULL; |
6694 | 59 } |
60 | |
13810 | 61 static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp) |
6694 | 62 { |
13810 | 63 GaimConversation *convo; |
6694 | 64 GList *cur; |
65 | |
13810 | 66 convo = gaim_tcl_ref_get(interp, obj, GaimTclRefConversation); |
67 | |
68 if (convo == NULL) | |
69 return NULL; | |
70 | |
6694 | 71 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { |
72 if (convo == cur->data) | |
13810 | 73 return convo; |
6694 | 74 } |
75 if (interp != NULL) | |
76 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); | |
13810 | 77 return NULL; |
6694 | 78 } |
79 | |
80 static gboolean tcl_validate_gc(GaimConnection *gc) | |
81 { | |
82 GList *cur; | |
83 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
84 if (gc == cur->data) | |
85 return TRUE; | |
86 } | |
87 return FALSE; | |
88 } | |
89 | |
90 int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
91 { | |
92 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; | |
13810 | 93 const char *cmds[] = { "active_status", "alias", "connect", |
94 "connection", "disconnect", "enabled", "find", | |
95 "handle", "isconnected", "list", "protocol", | |
96 "status_type", "status_types", "username", NULL }; | |
97 enum { CMD_ACCOUNT_ACTIVE_STATUS, CMD_ACCOUNT_ALIAS, | |
98 CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, | |
99 CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, | |
100 CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, | |
101 CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS_TYPE, | |
102 CMD_ACCOUNT_STATUS_TYPES, CMD_ACCOUNT_USERNAME } cmd; | |
10339 | 103 const char *listopts[] = { "-all", "-online", NULL }; |
6694 | 104 enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; |
8834 | 105 const char *alias; |
13810 | 106 const GList *cur; |
6694 | 107 GaimAccount *account; |
13810 | 108 GaimStatusType *status_type; |
6694 | 109 int error; |
13810 | 110 int b; |
6694 | 111 |
112 if (objc < 2) { | |
113 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
114 return TCL_ERROR; | |
115 } | |
116 | |
117 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
118 return error; | |
119 | |
120 switch (cmd) { | |
13810 | 121 case CMD_ACCOUNT_ACTIVE_STATUS: |
122 if (objc != 3) { | |
123 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
124 return TCL_ERROR; | |
125 } | |
126 if ((account = tcl_validate_account(objv[2], interp)) == NULL) | |
127 return TCL_ERROR; | |
128 Tcl_SetObjResult(interp, | |
129 gaim_tcl_ref_new(GaimTclRefStatus, | |
130 gaim_account_get_active_status(account))); | |
131 break; | |
6694 | 132 case CMD_ACCOUNT_ALIAS: |
133 if (objc != 3) { | |
134 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
135 return TCL_ERROR; | |
136 } | |
13810 | 137 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 138 return TCL_ERROR; |
139 alias = gaim_account_get_alias(account); | |
140 Tcl_SetStringObj(result, alias ? (char *)alias : "", -1); | |
141 break; | |
142 case CMD_ACCOUNT_CONNECT: | |
143 if (objc != 3) { | |
144 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
145 return TCL_ERROR; | |
146 } | |
13810 | 147 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 148 return TCL_ERROR; |
10740 | 149 if (!gaim_account_is_connected(account)) |
150 gaim_account_connect(account); | |
151 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); | |
6694 | 152 break; |
153 case CMD_ACCOUNT_CONNECTION: | |
154 if (objc != 3) { | |
155 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
156 return TCL_ERROR; | |
157 } | |
13810 | 158 |
159 if ((account = tcl_validate_account(objv[2], interp)) == NULL) | |
6694 | 160 return TCL_ERROR; |
161 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); | |
162 break; | |
163 case CMD_ACCOUNT_DISCONNECT: | |
164 if (objc != 3) { | |
165 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
166 return TCL_ERROR; | |
167 } | |
13810 | 168 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 169 return TCL_ERROR; |
170 gaim_account_disconnect(account); | |
171 break; | |
13810 | 172 case CMD_ACCOUNT_ENABLED: |
173 if (objc != 3 && objc != 4) { | |
174 Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?"); | |
175 return TCL_ERROR; | |
176 } | |
177 if ((account = tcl_validate_account(objv[2], interp)) == NULL) | |
178 return TCL_ERROR; | |
179 if (objc == 3) { | |
180 Tcl_SetBooleanObj(result, | |
181 gaim_account_get_enabled(account, | |
182 gaim_core_get_ui())); | |
183 } else { | |
184 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK) | |
185 return TCL_ERROR; | |
186 gaim_account_set_enabled(account, gaim_core_get_ui(), b); | |
187 } | |
188 break; | |
6694 | 189 case CMD_ACCOUNT_FIND: |
190 if (objc != 4) { | |
191 Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); | |
192 return TCL_ERROR; | |
193 } | |
7156 | 194 Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), |
6694 | 195 Tcl_GetString(objv[3]))); |
196 break; | |
197 case CMD_ACCOUNT_HANDLE: | |
198 if (objc != 2) { | |
199 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
200 return TCL_ERROR; | |
201 } | |
202 Tcl_SetIntObj(result, (int)gaim_accounts_get_handle()); | |
203 break; | |
204 case CMD_ACCOUNT_ISCONNECTED: | |
205 if (objc != 3) { | |
206 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
207 return TCL_ERROR; | |
208 } | |
13810 | 209 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 210 return TCL_ERROR; |
211 Tcl_SetBooleanObj(result, gaim_account_is_connected(account)); | |
212 break; | |
213 case CMD_ACCOUNT_LIST: | |
214 listopt = CMD_ACCOUNTLIST_ALL; | |
215 if (objc > 3) { | |
216 Tcl_WrongNumArgs(interp, 2, objv, "?option?"); | |
217 return TCL_ERROR; | |
218 } | |
219 if (objc == 3) { | |
220 if ((error = Tcl_GetIndexFromObj(interp, objv[2], listopts, "option", 0, (int *)&listopt)) != TCL_OK) | |
221 return error; | |
222 } | |
223 list = Tcl_NewListObj(0, NULL); | |
224 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
225 account = cur->data; | |
226 if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account)) | |
227 continue; | |
13810 | 228 elem = gaim_tcl_ref_new(GaimTclRefAccount, account); |
6694 | 229 Tcl_ListObjAppendElement(interp, list, elem); |
230 } | |
231 Tcl_SetObjResult(interp, list); | |
232 break; | |
233 case CMD_ACCOUNT_PROTOCOL: | |
234 if (objc != 3) { | |
235 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
236 return TCL_ERROR; | |
237 } | |
13810 | 238 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 239 return TCL_ERROR; |
240 Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1); | |
241 break; | |
13810 | 242 case CMD_ACCOUNT_STATUS_TYPE: |
243 if (objc != 4 && objc != 5) { | |
244 Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?"); | |
245 return TCL_ERROR; | |
246 } | |
247 if ((account = tcl_validate_account(objv[2], interp)) == NULL) | |
248 return TCL_ERROR; | |
249 if (objc == 4) { | |
250 status_type = gaim_account_get_status_type(account, | |
251 Tcl_GetString(objv[3])); | |
252 } else { | |
253 GaimStatusPrimitive primitive; | |
254 if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { | |
255 Tcl_SetStringObj(result, "bad option \"", -1); | |
256 Tcl_AppendObjToObj(result, objv[3]); | |
257 Tcl_AppendToObj(result, | |
258 "\": should be -primitive", -1); | |
259 return TCL_ERROR; | |
260 } | |
261 primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); | |
262 status_type = gaim_account_get_status_type_with_primitive(account, | |
263 primitive); | |
264 } | |
265 if (status_type == NULL) { | |
266 Tcl_SetStringObj(result, "status type not found", -1); | |
267 return TCL_ERROR; | |
268 } | |
269 Tcl_SetObjResult(interp, | |
270 gaim_tcl_ref_new(GaimTclRefStatusType, | |
271 status_type)); | |
272 break; | |
273 case CMD_ACCOUNT_STATUS_TYPES: | |
274 if (objc != 3) { | |
275 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
276 return TCL_ERROR; | |
277 } | |
278 if ((account = tcl_validate_account(objv[2], interp)) == NULL) | |
279 return TCL_ERROR; | |
280 list = Tcl_NewListObj(0, NULL); | |
281 for (cur = gaim_account_get_status_types(account); cur != NULL; | |
282 cur = g_list_next(cur)) { | |
283 Tcl_ListObjAppendElement(interp, list, | |
284 gaim_tcl_ref_new(GaimTclRefStatusType, | |
285 cur->data)); | |
286 } | |
287 Tcl_SetObjResult(interp, list); | |
288 break; | |
6694 | 289 case CMD_ACCOUNT_USERNAME: |
290 if (objc != 3) { | |
291 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
292 return TCL_ERROR; | |
293 } | |
13810 | 294 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 295 return TCL_ERROR; |
296 Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1); | |
297 break; | |
298 } | |
299 | |
300 return TCL_OK; | |
301 } | |
302 | |
303 static GaimBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj **elems) | |
304 { | |
305 GaimBlistNode *node = NULL; | |
306 GaimAccount *account; | |
307 char *name; | |
308 char *type; | |
309 | |
310 if (count < 3) { | |
311 Tcl_SetStringObj(Tcl_GetObjResult(interp), "list too short", -1); | |
312 return NULL; | |
313 } | |
314 | |
315 type = Tcl_GetString(elems[0]); | |
316 name = Tcl_GetString(elems[1]); | |
13810 | 317 if ((account = tcl_validate_account(elems[2], interp)) == NULL) |
6694 | 318 return NULL; |
319 | |
320 if (!strcmp(type, "buddy")) { | |
321 node = (GaimBlistNode *)gaim_find_buddy(account, name); | |
322 } else if (!strcmp(type, "group")) { | |
323 node = (GaimBlistNode *)gaim_blist_find_chat(account, name); | |
324 } | |
325 | |
326 return node; | |
327 } | |
328 | |
329 int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
330 { | |
6746 | 331 Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result; |
10339 | 332 const char *cmds[] = { "alias", "handle", "info", "list", NULL }; |
6694 | 333 enum { CMD_BUDDY_ALIAS, CMD_BUDDY_HANDLE, CMD_BUDDY_INFO, CMD_BUDDY_LIST } cmd; |
7100
abdc55ffadba
[gaim-migrate @ 7665]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
334 GaimBuddyList *blist; |
6746 | 335 GaimBlistNode *node, *gnode, *bnode; |
6694 | 336 GaimAccount *account; |
6746 | 337 GaimBuddy *bud; |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
338 GaimChat *cnode; |
6694 | 339 int error, all = 0, count; |
340 | |
341 if (objc < 2) { | |
342 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
343 return TCL_ERROR; | |
344 } | |
345 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
346 return error; | |
347 | |
348 result = Tcl_GetObjResult(interp); | |
349 | |
350 switch (cmd) { | |
351 case CMD_BUDDY_ALIAS: | |
352 if (objc != 3) { | |
353 Tcl_WrongNumArgs(interp, 2, objv, "buddy"); | |
354 return TCL_ERROR; | |
355 } | |
356 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) | |
357 return error; | |
358 if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL) | |
359 return TCL_ERROR; | |
360 if (node->type == GAIM_BLIST_CHAT_NODE) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
361 Tcl_SetStringObj(result, ((GaimChat *)node)->alias, -1); |
6694 | 362 else if (node->type == GAIM_BLIST_BUDDY_NODE) |
9620 | 363 Tcl_SetStringObj(result, (char *)gaim_buddy_get_alias((GaimBuddy *)node), -1); |
6694 | 364 return TCL_OK; |
365 break; | |
366 case CMD_BUDDY_HANDLE: | |
367 if (objc != 2) { | |
368 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
369 return TCL_ERROR; | |
370 } | |
371 Tcl_SetIntObj(result, (int)gaim_blist_get_handle()); | |
372 break; | |
373 case CMD_BUDDY_INFO: | |
374 if (objc != 3 && objc != 4) { | |
375 Tcl_WrongNumArgs(interp, 2, objv, "( buddy | account username )"); | |
376 return TCL_ERROR; | |
377 } | |
378 if (objc == 3) { | |
379 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) | |
380 return error; | |
381 if (count < 3) { | |
382 Tcl_SetStringObj(result, "buddy too short", -1); | |
383 return TCL_ERROR; | |
384 } | |
385 if (strcmp("buddy", Tcl_GetString(elems[0]))) { | |
386 Tcl_SetStringObj(result, "invalid buddy", -1); | |
387 return TCL_ERROR; | |
388 } | |
13810 | 389 if ((account = tcl_validate_account(elems[2], interp)) == NULL) |
6694 | 390 return TCL_ERROR; |
391 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1])); | |
392 } else { | |
13810 | 393 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
6694 | 394 return TCL_ERROR; |
395 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3])); | |
396 } | |
397 break; | |
398 case CMD_BUDDY_LIST: | |
399 if (objc == 3) { | |
400 if (!strcmp("-all", Tcl_GetString(objv[2]))) { | |
401 all = 1; | |
402 } else { | |
403 Tcl_SetStringObj(result, "", -1); | |
404 Tcl_AppendStringsToObj(result, "unknown option: ", Tcl_GetString(objv[2]), NULL); | |
405 return TCL_ERROR; | |
406 } | |
407 } | |
408 list = Tcl_NewListObj(0, NULL); | |
409 blist = gaim_get_blist(); | |
410 for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { | |
411 tclgroup = Tcl_NewListObj(0, NULL); | |
412 Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1)); | |
413 Tcl_ListObjAppendElement(interp, tclgroup, | |
6700 | 414 Tcl_NewStringObj(((GaimGroup *)gnode)->name, -1)); |
6694 | 415 tclgrouplist = Tcl_NewListObj(0, NULL); |
416 for (node = gnode->child; node != NULL; node = node->next) { | |
417 switch (node->type) { | |
6746 | 418 case GAIM_BLIST_CONTACT_NODE: |
419 tclcontact = Tcl_NewListObj(0, NULL); | |
420 Tcl_IncrRefCount(tclcontact); | |
421 Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1)); | |
422 tclcontactlist = Tcl_NewListObj(0, NULL); | |
423 Tcl_IncrRefCount(tclcontactlist); | |
424 count = 0; | |
425 for (bnode = node->child; bnode != NULL; bnode = bnode ->next) { | |
426 if (bnode->type != GAIM_BLIST_BUDDY_NODE) | |
427 continue; | |
428 bud = (GaimBuddy *)bnode; | |
429 if (!all && !gaim_account_is_connected(bud->account)) | |
430 continue; | |
431 count++; | |
432 tclbud = Tcl_NewListObj(0, NULL); | |
433 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); | |
434 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1)); | |
13810 | 435 Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, bud->account)); |
6746 | 436 Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); |
437 } | |
438 if (count) { | |
439 Tcl_ListObjAppendElement(interp, tclcontact, tclcontactlist); | |
440 Tcl_ListObjAppendElement(interp, tclgrouplist, tclcontact); | |
441 } | |
442 Tcl_DecrRefCount(tclcontact); | |
443 Tcl_DecrRefCount(tclcontactlist); | |
6694 | 444 break; |
445 case GAIM_BLIST_CHAT_NODE: | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
446 cnode = (GaimChat *)node; |
6694 | 447 if (!all && !gaim_account_is_connected(cnode->account)) |
448 continue; | |
449 tclbud = Tcl_NewListObj(0, NULL); | |
450 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); | |
451 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1)); | |
13810 | 452 Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, cnode->account)); |
6746 | 453 Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); |
6694 | 454 break; |
455 default: | |
6746 | 456 gaim_debug(GAIM_DEBUG_WARNING, "tcl", "Unexpected buddy type %d", node->type); |
6694 | 457 continue; |
458 } | |
459 } | |
460 Tcl_ListObjAppendElement(interp, tclgroup, tclgrouplist); | |
461 Tcl_ListObjAppendElement(interp, list, tclgroup); | |
462 } | |
463 Tcl_SetObjResult(interp, list); | |
464 break; | |
465 } | |
466 | |
467 return TCL_OK; | |
468 } | |
469 | |
470 int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
471 { | |
472 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; | |
10339 | 473 const char *cmds[] = { "account", "displayname", "handle", "list", NULL }; |
7713 | 474 enum { CMD_CONN_ACCOUNT, CMD_CONN_DISPLAYNAME, CMD_CONN_HANDLE, CMD_CONN_LIST } cmd; |
6694 | 475 int error; |
476 GList *cur; | |
477 GaimConnection *gc; | |
478 | |
479 if (objc < 2) { | |
480 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
481 return TCL_ERROR; | |
482 } | |
483 | |
484 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
485 return error; | |
486 | |
487 switch (cmd) { | |
488 case CMD_CONN_ACCOUNT: | |
489 if (objc != 3) { | |
6864 | 490 Tcl_WrongNumArgs(interp, 2, objv, "gc"); |
6694 | 491 return TCL_ERROR; |
492 } | |
493 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); | |
494 if (error || !tcl_validate_gc(gc)) { | |
495 Tcl_SetStringObj(result, "invalid gc", -1); | |
496 return TCL_ERROR; | |
497 } | |
498 Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc)); | |
499 break; | |
7713 | 500 case CMD_CONN_DISPLAYNAME: |
501 if (objc != 3) { | |
502 Tcl_WrongNumArgs(interp, 2, objv, "gc"); | |
503 return TCL_ERROR; | |
504 } | |
505 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); | |
506 if (error || !tcl_validate_gc(gc)) { | |
507 Tcl_SetStringObj(result, "invalid gc", -1); | |
508 return TCL_ERROR; | |
509 } | |
510 Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1); | |
511 break; | |
6694 | 512 case CMD_CONN_HANDLE: |
513 if (objc != 2) { | |
514 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
515 return TCL_ERROR; | |
516 } | |
517 Tcl_SetIntObj(result, (int)gaim_connections_get_handle()); | |
518 break; | |
519 case CMD_CONN_LIST: | |
520 if (objc != 2) { | |
521 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
522 return TCL_ERROR; | |
523 } | |
524 list = Tcl_NewListObj(0, NULL); | |
525 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
526 elem = Tcl_NewIntObj((int)cur->data); | |
527 Tcl_ListObjAppendElement(interp, list, elem); | |
528 } | |
529 Tcl_SetObjResult(interp, list); | |
530 break; | |
531 } | |
532 | |
533 return TCL_OK; | |
534 } | |
535 | |
536 int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
537 { | |
538 Tcl_Obj *list, *elem, *result = Tcl_GetObjResult(interp); | |
10339 | 539 const char *cmds[] = { "find", "handle", "list", "new", "write", NULL }; |
6694 | 540 enum { CMD_CONV_FIND, CMD_CONV_HANDLE, CMD_CONV_LIST, CMD_CONV_NEW, CMD_CONV_WRITE } cmd; |
10339 | 541 const char *styles[] = { "send", "recv", "system", NULL }; |
6694 | 542 enum { CMD_CONV_WRITE_SEND, CMD_CONV_WRITE_RECV, CMD_CONV_WRITE_SYSTEM } style; |
10339 | 543 const char *newopts[] = { "-chat", "-im" }; |
6694 | 544 enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt; |
545 GaimConversation *convo; | |
546 GaimAccount *account; | |
547 GaimConversationType type; | |
548 GList *cur; | |
549 char *opt, *from, *what; | |
7156 | 550 int error, argsused, flags = 0; |
6694 | 551 |
552 if (objc < 2) { | |
553 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
554 return TCL_ERROR; | |
555 } | |
556 | |
557 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
558 return error; | |
559 | |
560 switch (cmd) { | |
561 case CMD_CONV_FIND: | |
10829 | 562 if (objc != 4) { |
563 Tcl_WrongNumArgs(interp, 2, objv, "account name"); | |
6694 | 564 return TCL_ERROR; |
565 } | |
566 account = NULL; | |
13810 | 567 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
10829 | 568 return TCL_ERROR; |
11338 | 569 convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, |
10829 | 570 Tcl_GetString(objv[3]), |
571 account); | |
6694 | 572 Tcl_SetIntObj(result, (int)convo); |
573 break; | |
574 case CMD_CONV_HANDLE: | |
575 if (objc != 2) { | |
576 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
577 return TCL_ERROR; | |
578 } | |
579 Tcl_SetIntObj(result, (int)gaim_conversations_get_handle()); | |
580 break; | |
581 case CMD_CONV_LIST: | |
582 list = Tcl_NewListObj(0, NULL); | |
583 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { | |
584 elem = Tcl_NewIntObj((int)cur->data); | |
585 Tcl_ListObjAppendElement(interp, list, elem); | |
586 } | |
587 Tcl_SetObjResult(interp, list); | |
588 break; | |
589 case CMD_CONV_NEW: | |
590 if (objc < 4) { | |
591 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); | |
592 return TCL_ERROR; | |
593 } | |
594 argsused = 2; | |
11338 | 595 type = GAIM_CONV_TYPE_IM; |
6694 | 596 while (argsused < objc) { |
597 opt = Tcl_GetString(objv[argsused]); | |
598 if (*opt == '-') { | |
599 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], newopts, | |
600 "option", 0, (int *)&newopt)) != TCL_OK) | |
601 return error; | |
602 argsused++; | |
603 switch (newopt) { | |
604 case CMD_CONV_NEW_CHAT: | |
11338 | 605 type = GAIM_CONV_TYPE_CHAT; |
6694 | 606 break; |
607 case CMD_CONV_NEW_IM: | |
11338 | 608 type = GAIM_CONV_TYPE_IM; |
6694 | 609 break; |
610 } | |
611 } else { | |
612 break; | |
613 } | |
614 } | |
615 if (objc - argsused != 2) { | |
616 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); | |
617 return TCL_ERROR; | |
618 } | |
13810 | 619 if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) |
6694 | 620 return TCL_ERROR; |
621 convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); | |
622 Tcl_SetIntObj(result, (int)convo); | |
623 break; | |
624 case CMD_CONV_WRITE: | |
625 if (objc != 6) { | |
626 Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); | |
627 return TCL_ERROR; | |
628 } | |
13810 | 629 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
630 return TCL_ERROR; | |
6694 | 631 if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) |
632 return error; | |
633 from = Tcl_GetString(objv[4]); | |
634 what = Tcl_GetString(objv[5]); | |
635 | |
636 switch (style) { | |
637 case CMD_CONV_WRITE_SEND: | |
638 flags = GAIM_MESSAGE_SEND; | |
639 break; | |
640 case CMD_CONV_WRITE_RECV: | |
641 flags = GAIM_MESSAGE_RECV; | |
642 break; | |
643 case CMD_CONV_WRITE_SYSTEM: | |
644 flags = GAIM_MESSAGE_SYSTEM; | |
645 break; | |
646 } | |
11338 | 647 if (gaim_conversation_get_type(convo) == GAIM_CONV_TYPE_CHAT) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
648 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), from, what, flags, time(NULL)); |
6694 | 649 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
650 gaim_conv_im_write(GAIM_CONV_IM(convo), from, what, flags, time(NULL)); |
6694 | 651 break; |
652 } | |
653 | |
654 return TCL_OK; | |
655 } | |
656 | |
657 int tcl_cmd_core(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
658 { | |
659 Tcl_Obj *result = Tcl_GetObjResult(interp); | |
10339 | 660 const char *cmds[] = { "handle", "quit", NULL }; |
6694 | 661 enum { CMD_CORE_HANDLE, CMD_CORE_QUIT } cmd; |
662 int error; | |
663 | |
664 if (objc < 2) { | |
665 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
666 return TCL_ERROR; | |
667 } | |
668 | |
669 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
670 return error; | |
671 | |
672 switch (cmd) { | |
673 case CMD_CORE_HANDLE: | |
674 if (objc != 2) { | |
675 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
676 return TCL_ERROR; | |
677 } | |
678 Tcl_SetIntObj(result, (int)gaim_get_core()); | |
679 break; | |
680 case CMD_CORE_QUIT: | |
681 if (objc != 2) { | |
682 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
683 return TCL_ERROR; | |
684 } | |
685 gaim_core_quit(); | |
686 break; | |
687 } | |
688 | |
689 return TCL_OK; | |
690 } | |
691 | |
692 int tcl_cmd_debug(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
693 { | |
694 char *category, *message; | |
695 int lev; | |
10339 | 696 const char *levels[] = { "-misc", "-info", "-warning", "-error", NULL }; |
6694 | 697 GaimDebugLevel levelind[] = { GAIM_DEBUG_MISC, GAIM_DEBUG_INFO, GAIM_DEBUG_WARNING, GAIM_DEBUG_ERROR }; |
698 int error; | |
699 | |
700 if (objc != 4) { | |
701 Tcl_WrongNumArgs(interp, 1, objv, "level category message"); | |
702 return TCL_ERROR; | |
703 } | |
704 | |
705 error = Tcl_GetIndexFromObj(interp, objv[1], levels, "debug level", 0, &lev); | |
706 if (error != TCL_OK) | |
707 return error; | |
708 | |
709 category = Tcl_GetString(objv[2]); | |
710 message = Tcl_GetString(objv[3]); | |
711 | |
712 gaim_debug(levelind[lev], category, "%s\n", message); | |
713 | |
714 return TCL_OK; | |
715 } | |
716 | |
717 int tcl_cmd_notify(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
718 { | |
719 int error, type; | |
10339 | 720 const char *opts[] = { "-error", "-warning", "-info", NULL }; |
6694 | 721 GaimNotifyMsgType optind[] = { GAIM_NOTIFY_MSG_ERROR, GAIM_NOTIFY_MSG_WARNING, GAIM_NOTIFY_MSG_INFO }; |
722 char *title, *msg1, *msg2; | |
723 | |
724 if (objc < 4 || objc > 5) { | |
725 Tcl_WrongNumArgs(interp, 1, objv, "?type? title primary secondary"); | |
726 return TCL_ERROR; | |
727 } | |
728 | |
729 if (objc == 4) { | |
13423 | 730 type = 1; /* Default to warning */ |
6694 | 731 title = Tcl_GetString(objv[1]); |
732 msg1 = Tcl_GetString(objv[2]); | |
733 msg2 = Tcl_GetString(objv[3]); | |
734 } else { | |
735 error = Tcl_GetIndexFromObj(interp, objv[1], opts, "message type", 0, &type); | |
736 if (error != TCL_OK) | |
737 return error; | |
738 title = Tcl_GetString(objv[2]); | |
739 msg1 = Tcl_GetString(objv[3]); | |
740 msg2 = Tcl_GetString(objv[4]); | |
741 } | |
742 | |
743 gaim_notify_message(_tcl_plugin, optind[type], title, msg1, msg2, NULL, NULL); | |
744 | |
745 return TCL_OK; | |
746 } | |
747 | |
748 int tcl_cmd_prefs(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
749 { | |
750 Tcl_Obj *result, *list, *elem, **elems; | |
10339 | 751 const char *cmds[] = { "get", "set", "type", NULL }; |
6694 | 752 enum { CMD_PREFS_GET, CMD_PREFS_SET, CMD_PREFS_TYPE } cmd; |
753 /* char *types[] = { "none", "boolean", "int", "string", "stringlist", NULL }; */ | |
754 /* enum { TCL_PREFS_NONE, TCL_PREFS_BOOL, TCL_PREFS_INT, TCL_PREFS_STRING, TCL_PREFS_STRINGLIST } type; */ | |
755 GaimPrefType preftype; | |
756 GList *cur; | |
757 int error, intval, nelem, i; | |
758 | |
759 if (objc < 2) { | |
760 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
761 return TCL_ERROR; | |
762 } | |
763 | |
764 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
765 return error; | |
766 | |
767 result = Tcl_GetObjResult(interp); | |
768 switch (cmd) { | |
769 case CMD_PREFS_GET: | |
770 if (objc != 3) { | |
771 Tcl_WrongNumArgs(interp, 1, objv, "path"); | |
772 return TCL_ERROR; | |
773 } | |
774 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
775 switch (preftype) { | |
776 case GAIM_PREF_NONE: | |
777 Tcl_SetStringObj(result, "pref type none", -1); | |
778 return TCL_ERROR; | |
779 break; | |
780 case GAIM_PREF_BOOLEAN: | |
781 Tcl_SetBooleanObj(result, gaim_prefs_get_bool(Tcl_GetString(objv[2]))); | |
782 break; | |
783 case GAIM_PREF_INT: | |
784 Tcl_SetIntObj(result, gaim_prefs_get_int(Tcl_GetString(objv[2]))); | |
785 break; | |
786 case GAIM_PREF_STRING: | |
787 Tcl_SetStringObj(result, (char *)gaim_prefs_get_string(Tcl_GetString(objv[2])), -1); | |
788 break; | |
789 case GAIM_PREF_STRING_LIST: | |
790 cur = gaim_prefs_get_string_list(Tcl_GetString(objv[2])); | |
791 list = Tcl_NewListObj(0, NULL); | |
792 while (cur != NULL) { | |
793 elem = Tcl_NewStringObj((char *)cur->data, -1); | |
794 Tcl_ListObjAppendElement(interp, list, elem); | |
795 cur = g_list_next(cur); | |
796 } | |
797 Tcl_SetObjResult(interp, list); | |
798 break; | |
799 default: | |
800 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
801 Tcl_SetStringObj(result, "unknown pref type", -1); | |
802 return TCL_ERROR; | |
803 } | |
804 break; | |
805 case CMD_PREFS_SET: | |
806 if (objc != 4) { | |
807 Tcl_WrongNumArgs(interp, 1, objv, "path value"); | |
808 return TCL_ERROR; | |
809 } | |
810 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
811 switch (preftype) { | |
812 case GAIM_PREF_NONE: | |
813 Tcl_SetStringObj(result, "bad path or pref type none", -1); | |
814 return TCL_ERROR; | |
815 break; | |
816 case GAIM_PREF_BOOLEAN: | |
817 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &intval)) != TCL_OK) | |
818 return error; | |
819 gaim_prefs_set_bool(Tcl_GetString(objv[2]), intval); | |
820 break; | |
821 case GAIM_PREF_INT: | |
822 if ((error = Tcl_GetIntFromObj(interp, objv[3], &intval)) != TCL_OK) | |
823 return error; | |
824 gaim_prefs_set_int(Tcl_GetString(objv[2]), intval); | |
825 break; | |
826 case GAIM_PREF_STRING: | |
827 gaim_prefs_set_string(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); | |
828 break; | |
829 case GAIM_PREF_STRING_LIST: | |
830 if ((error = Tcl_ListObjGetElements(interp, objv[3], &nelem, &elems)) != TCL_OK) | |
831 return error; | |
832 cur = NULL; | |
833 for (i = 0; i < nelem; i++) { | |
834 cur = g_list_append(cur, (gpointer)Tcl_GetString(elems[i])); | |
835 } | |
836 gaim_prefs_set_string_list(Tcl_GetString(objv[2]), cur); | |
837 g_list_free(cur); | |
838 break; | |
839 default: | |
840 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
841 return TCL_ERROR; | |
842 } | |
843 break; | |
844 case CMD_PREFS_TYPE: | |
845 if (objc != 3) { | |
846 Tcl_WrongNumArgs(interp, 1, objv, "path"); | |
847 return TCL_ERROR; | |
848 } | |
849 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
850 switch (preftype) { | |
851 case GAIM_PREF_NONE: | |
852 Tcl_SetStringObj(result, "none", -1); | |
853 break; | |
854 case GAIM_PREF_BOOLEAN: | |
855 Tcl_SetStringObj(result, "boolean", -1); | |
856 break; | |
857 case GAIM_PREF_INT: | |
858 Tcl_SetStringObj(result, "int", -1); | |
859 break; | |
860 case GAIM_PREF_STRING: | |
861 Tcl_SetStringObj(result, "string", -1); | |
862 break; | |
863 case GAIM_PREF_STRING_LIST: | |
864 Tcl_SetStringObj(result, "stringlist", -1); | |
865 break; | |
866 default: | |
867 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
868 Tcl_SetStringObj(result, "unknown", -1); | |
869 } | |
870 break; | |
871 } | |
872 | |
873 return TCL_OK; | |
874 } | |
875 | |
876 int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
877 { | |
878 GaimConnection *gc; | |
879 char *who, *text; | |
880 int error; | |
881 Tcl_Obj *result; | |
882 | |
883 if (objc != 4) { | |
884 Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); | |
885 return TCL_ERROR; | |
886 } | |
887 | |
888 if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK) | |
889 return error; | |
890 if (!tcl_validate_gc(gc)) { | |
891 result = Tcl_GetObjResult(interp); | |
892 Tcl_SetStringObj(result, "invalid gc", -1); | |
893 return TCL_ERROR; | |
894 } | |
895 | |
896 who = Tcl_GetString(objv[2]); | |
897 text = Tcl_GetString(objv[3]); | |
898 | |
6982 | 899 serv_send_im(gc, who, text, 0); |
6694 | 900 |
901 return TCL_OK; | |
902 } | |
903 | |
904 int tcl_cmd_signal(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
905 { | |
10339 | 906 const char *cmds[] = { "connect", "disconnect", NULL }; |
6694 | 907 enum { CMD_SIGNAL_CONNECT, CMD_SIGNAL_DISCONNECT } cmd; |
908 struct tcl_signal_handler *handler; | |
10597 | 909 Tcl_Obj *result = Tcl_GetObjResult(interp); |
6694 | 910 void *instance; |
10597 | 911 int error; |
6694 | 912 |
913 if (objc < 2) { | |
914 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
915 return TCL_ERROR; | |
916 } | |
917 | |
918 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
919 return error; | |
920 | |
921 switch (cmd) { | |
922 case CMD_SIGNAL_CONNECT: | |
923 if (objc != 6) { | |
924 Tcl_WrongNumArgs(interp, 2, objv, "instance signal args proc"); | |
925 return TCL_ERROR; | |
926 } | |
927 handler = g_new0(struct tcl_signal_handler, 1); | |
928 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&handler->instance)) != TCL_OK) { | |
929 g_free(handler); | |
930 return error; | |
931 } | |
10597 | 932 handler->signal = objv[3]; |
13810 | 933 Tcl_IncrRefCount(handler->signal); |
10597 | 934 handler->args = objv[4]; |
935 handler->proc = objv[5]; | |
6694 | 936 handler->interp = interp; |
937 if (!tcl_signal_connect(handler)) { | |
938 tcl_signal_handler_free(handler); | |
939 Tcl_SetIntObj(result, 1); | |
940 } else { | |
941 Tcl_SetIntObj(result, 0); | |
942 } | |
943 break; | |
944 case CMD_SIGNAL_DISCONNECT: | |
945 if (objc != 4) { | |
13810 | 946 Tcl_WrongNumArgs(interp, 2, objv, "instance signal"); |
6694 | 947 return TCL_ERROR; |
948 } | |
949 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK) | |
950 return error; | |
951 tcl_signal_disconnect(instance, Tcl_GetString(objv[3]), interp); | |
952 break; | |
953 } | |
954 | |
955 return TCL_OK; | |
956 } | |
957 | |
13810 | 958 int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
959 { | |
960 const char *cmds[] = { "attr", "type" }; | |
961 enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd; | |
962 Tcl_Obj *result = Tcl_GetObjResult(interp); | |
963 GaimStatus *status; | |
964 GaimStatusType *status_type; | |
965 GaimValue *value; | |
966 int error; | |
967 | |
968 if (objc < 2) { | |
969 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
970 return TCL_ERROR; | |
971 } | |
972 | |
973 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
974 return error; | |
975 | |
976 switch (cmd) { | |
977 case CMD_STATUS_ATTR: | |
978 if (objc != 4) { | |
979 Tcl_WrongNumArgs(interp, 2, objv, "status attr_id"); | |
980 return TCL_ERROR; | |
981 } | |
982 if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) | |
983 return TCL_ERROR; | |
984 value = gaim_status_get_attr_value(status, Tcl_GetString(objv[3])); | |
985 if (value == NULL) { | |
986 Tcl_SetStringObj(result, "no such attribute", -1); | |
987 return TCL_ERROR; | |
988 } | |
989 switch (gaim_value_get_type(value)) { | |
990 case GAIM_TYPE_BOOLEAN: | |
991 Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); | |
992 break; | |
993 case GAIM_TYPE_INT: | |
994 Tcl_SetIntObj(result, gaim_value_get_int(value)); | |
995 break; | |
996 case GAIM_TYPE_STRING: | |
997 Tcl_SetStringObj(result, gaim_value_get_string(value), -1); | |
998 break; | |
999 default: | |
1000 Tcl_SetStringObj(result, "attribute has unknown type", -1); | |
1001 return TCL_ERROR; | |
1002 } | |
1003 break; | |
1004 case CMD_STATUS_TYPE: | |
1005 if (objc != 3) { | |
1006 Tcl_WrongNumArgs(interp, 2, objv, "status"); | |
1007 return TCL_ERROR; | |
1008 } | |
1009 if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) | |
1010 return TCL_ERROR; | |
1011 status_type = gaim_status_get_type(status); | |
1012 Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefStatusType, | |
1013 status_type)); | |
1014 break; | |
1015 } | |
1016 | |
1017 return TCL_OK; | |
1018 } | |
1019 | |
1020 int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
1021 { | |
1022 const char *cmds[] = { "id", "name", NULL }; | |
1023 enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd; | |
1024 Tcl_Obj *result = Tcl_GetObjResult(interp); | |
1025 GaimStatusAttr *attr; | |
1026 int error; | |
1027 | |
1028 if (objc < 2) { | |
1029 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
1030 return TCL_ERROR; | |
1031 } | |
1032 | |
1033 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
1034 return error; | |
1035 | |
1036 switch (cmd) { | |
1037 case CMD_STATUS_ATTR_ID: | |
1038 if (objc != 3) { | |
1039 Tcl_WrongNumArgs(interp, 2, objv, "attr"); | |
1040 return TCL_ERROR; | |
1041 } | |
1042 if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) | |
1043 return TCL_ERROR; | |
1044 Tcl_SetStringObj(result, gaim_status_attr_get_id(attr), -1); | |
1045 break; | |
1046 case CMD_STATUS_ATTR_NAME: | |
1047 if (objc != 3) { | |
1048 Tcl_WrongNumArgs(interp, 2, objv, "attr"); | |
1049 return TCL_ERROR; | |
1050 } | |
1051 if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) | |
1052 return TCL_ERROR; | |
1053 Tcl_SetStringObj(result, gaim_status_attr_get_name(attr), -1); | |
1054 break; | |
1055 } | |
1056 | |
1057 return TCL_OK; | |
1058 } | |
1059 | |
1060 int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
1061 { | |
1062 const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", | |
1063 "independent", "name", "primary_attr", | |
1064 "primitive", "saveable", "user_settable", | |
1065 NULL }; | |
1066 enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, | |
1067 CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, | |
1068 CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, | |
1069 CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR, | |
1070 CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, | |
1071 CMD_STATUS_TYPE_USER_SETTABLE } cmd; | |
1072 Tcl_Obj *result = Tcl_GetObjResult(interp); | |
1073 GaimStatusType *status_type; | |
1074 Tcl_Obj *list, *elem; | |
1075 const GList *cur; | |
1076 int error; | |
1077 | |
1078 if (objc < 2) { | |
1079 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
1080 return TCL_ERROR; | |
1081 } | |
1082 | |
1083 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
1084 return error; | |
1085 | |
1086 switch (cmd) { | |
1087 case CMD_STATUS_TYPE_AVAILABLE: | |
1088 if (objc != 3) { | |
1089 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1090 return TCL_ERROR; | |
1091 } | |
1092 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1093 return TCL_ERROR; | |
1094 Tcl_SetBooleanObj(result, gaim_status_type_is_available(status_type)); | |
1095 break; | |
1096 case CMD_STATUS_TYPE_ATTR: | |
1097 if (objc != 4) { | |
1098 Tcl_WrongNumArgs(interp, 2, objv, "statustype attr"); | |
1099 return TCL_ERROR; | |
1100 } | |
1101 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1102 return TCL_ERROR; | |
1103 Tcl_SetObjResult(interp, | |
1104 gaim_tcl_ref_new(GaimTclRefStatusAttr, | |
1105 gaim_status_type_get_attr(status_type, | |
1106 Tcl_GetStringFromObj(objv[3], NULL)))); | |
1107 break; | |
1108 case CMD_STATUS_TYPE_ATTRS: | |
1109 if (objc != 3) { | |
1110 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1111 return TCL_ERROR; | |
1112 } | |
1113 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1114 return TCL_ERROR; | |
1115 list = Tcl_NewListObj(0, NULL); | |
1116 for (cur = gaim_status_type_get_attrs(status_type); | |
1117 cur != NULL; cur = g_list_next(cur)) { | |
1118 elem = gaim_tcl_ref_new(GaimTclRefStatusAttr, cur->data); | |
1119 Tcl_ListObjAppendElement(interp, list, elem); | |
1120 } | |
1121 Tcl_SetObjResult(interp, list); | |
1122 break; | |
1123 case CMD_STATUS_TYPE_EXCLUSIVE: | |
1124 if (objc != 3) { | |
1125 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1126 return TCL_ERROR; | |
1127 } | |
1128 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1129 return TCL_ERROR; | |
1130 Tcl_SetBooleanObj(result, gaim_status_type_is_exclusive(status_type)); | |
1131 break; | |
1132 case CMD_STATUS_TYPE_ID: | |
1133 if (objc != 3) { | |
1134 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1135 return TCL_ERROR; | |
1136 } | |
1137 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1138 return TCL_ERROR; | |
1139 Tcl_SetStringObj(result, gaim_status_type_get_id(status_type), -1); | |
1140 break; | |
1141 case CMD_STATUS_TYPE_INDEPENDENT: | |
1142 if (objc != 3) { | |
1143 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1144 return TCL_ERROR; | |
1145 } | |
1146 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1147 return TCL_ERROR; | |
1148 Tcl_SetBooleanObj(result, gaim_status_type_is_independent(status_type)); | |
1149 break; | |
1150 case CMD_STATUS_TYPE_NAME: | |
1151 if (objc != 3) { | |
1152 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1153 return TCL_ERROR; | |
1154 } | |
1155 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1156 return TCL_ERROR; | |
1157 Tcl_SetStringObj(result, gaim_status_type_get_name(status_type), -1); | |
1158 break; | |
1159 case CMD_STATUS_TYPE_PRIMITIVE: | |
1160 if (objc != 3) { | |
1161 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1162 return TCL_ERROR; | |
1163 } | |
1164 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1165 return TCL_ERROR; | |
1166 Tcl_SetStringObj(result, gaim_primitive_get_id_from_type(gaim_status_type_get_primitive(status_type)), -1); | |
1167 break; | |
1168 case CMD_STATUS_TYPE_PRIMARY_ATTR: | |
1169 if (objc != 3) { | |
1170 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1171 return TCL_ERROR; | |
1172 } | |
1173 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1174 return TCL_ERROR; | |
1175 Tcl_SetStringObj(result, gaim_status_type_get_primary_attr(status_type), -1); | |
1176 break; | |
1177 case CMD_STATUS_TYPE_SAVEABLE: | |
1178 if (objc != 3) { | |
1179 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1180 return TCL_ERROR; | |
1181 } | |
1182 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1183 return TCL_ERROR; | |
1184 Tcl_SetBooleanObj(result, gaim_status_type_is_saveable(status_type)); | |
1185 break; | |
1186 case CMD_STATUS_TYPE_USER_SETTABLE: | |
1187 if (objc != 3) { | |
1188 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); | |
1189 return TCL_ERROR; | |
1190 } | |
1191 if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) | |
1192 return TCL_ERROR; | |
1193 Tcl_SetBooleanObj(result, gaim_status_type_is_user_settable(status_type)); | |
1194 break; | |
1195 } | |
1196 | |
1197 return TCL_OK; | |
1198 } | |
1199 | |
6694 | 1200 static gboolean unload_self(gpointer data) |
1201 { | |
1202 GaimPlugin *plugin = data; | |
1203 gaim_plugin_unload(plugin); | |
1204 return FALSE; | |
1205 } | |
1206 | |
1207 int tcl_cmd_unload(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
1208 { | |
1209 GaimPlugin *plugin; | |
1210 if (objc != 1) { | |
1211 Tcl_WrongNumArgs(interp, 1, objv, ""); | |
1212 return TCL_ERROR; | |
1213 } | |
1214 | |
1215 if ((plugin = tcl_interp_get_plugin(interp)) == NULL) { | |
1216 /* This isn't exactly OK, but heh. What do you do? */ | |
1217 return TCL_OK; | |
1218 } | |
1219 /* We can't unload immediately, but we can unload at the first | |
1220 * known safe opportunity. */ | |
1221 g_idle_add(unload_self, (gpointer)plugin); | |
1222 | |
1223 return TCL_OK; | |
1224 } |