Mercurial > pidgin.yaz
annotate plugins/tcl/tcl_cmds.c @ 10581:59a2807e10bb
[gaim-migrate @ 11981]
I'm not sure when using --class broke (though it was probably when we added -c) but this fixes it for me and is arguable more correct anyway since according to the gtk docs gtk_init (and gtk_init_check) "will initialize everything needed to operate the toolkit and parses some standard command line options. argc and argv are adjusted accordingly so your own code will never see those standard arguments."
committer: Tailor Script <tailor@pidgin.im>
author | Etan Reisner <pidgin@unreliablesource.net> |
---|---|
date | Tue, 08 Feb 2005 04:59:35 +0000 |
parents | 3e4ecbdf8d0a |
children | 0e886a234d92 |
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 | |
38 static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp); | |
39 static gboolean tcl_validate_gc(GaimConnection *gc); | |
40 | |
41 static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp) | |
42 { | |
43 GList *cur; | |
44 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
45 if (account == cur->data) | |
46 return TRUE; | |
47 } | |
48 if (interp != NULL) | |
49 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); | |
50 return FALSE; | |
51 } | |
52 | |
53 static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp) | |
54 { | |
55 GList *cur; | |
56 | |
57 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { | |
58 if (convo == cur->data) | |
59 return TRUE; | |
60 } | |
61 if (interp != NULL) | |
62 Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); | |
63 return FALSE; | |
64 } | |
65 | |
66 static gboolean tcl_validate_gc(GaimConnection *gc) | |
67 { | |
68 GList *cur; | |
69 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
70 if (gc == cur->data) | |
71 return TRUE; | |
72 } | |
73 return FALSE; | |
74 } | |
75 | |
76 int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
77 { | |
78 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; | |
10339 | 79 const char *cmds[] = { "alias", "connect", "connection", "disconnect", "find", |
8834 | 80 "handle", "isconnected", "list", |
6737 | 81 "protocol", "username", NULL }; |
6694 | 82 enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, |
83 CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, | |
8834 | 84 CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, |
6737 | 85 CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd; |
10339 | 86 const char *listopts[] = { "-all", "-online", NULL }; |
6694 | 87 enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; |
8834 | 88 const char *alias; |
6694 | 89 GList *cur; |
90 GaimAccount *account; | |
91 int error; | |
92 | |
93 if (objc < 2) { | |
94 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
95 return TCL_ERROR; | |
96 } | |
97 | |
98 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
99 return error; | |
100 | |
101 switch (cmd) { | |
102 case CMD_ACCOUNT_ALIAS: | |
103 if (objc != 3) { | |
104 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
105 return TCL_ERROR; | |
106 } | |
107 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
108 if (error || !tcl_validate_account(account, interp)) | |
109 return TCL_ERROR; | |
110 alias = gaim_account_get_alias(account); | |
111 Tcl_SetStringObj(result, alias ? (char *)alias : "", -1); | |
112 break; | |
113 case CMD_ACCOUNT_CONNECT: | |
114 if (objc != 3) { | |
115 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
116 return TCL_ERROR; | |
117 } | |
118 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
119 if (error || !tcl_validate_account(account, interp)) | |
120 return TCL_ERROR; | |
121 if (gaim_account_is_connected(account)) | |
122 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); | |
123 else | |
10401 | 124 #warning Someone who knows TCL (Ethan!) fix this so TCL plugins can specify the status |
125 Tcl_SetIntObj(result, (int)gaim_account_connect(account, | |
126 gaim_account_get_status(account, "online"))); | |
6694 | 127 break; |
128 case CMD_ACCOUNT_CONNECTION: | |
129 if (objc != 3) { | |
130 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
131 return TCL_ERROR; | |
132 } | |
133 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
134 if (error || !tcl_validate_account(account, interp)) | |
135 return TCL_ERROR; | |
136 Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); | |
137 break; | |
138 case CMD_ACCOUNT_DISCONNECT: | |
139 if (objc != 3) { | |
140 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
141 return TCL_ERROR; | |
142 } | |
143 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
144 if (error || !tcl_validate_account(account, interp)) | |
145 return TCL_ERROR; | |
146 gaim_account_disconnect(account); | |
147 break; | |
148 case CMD_ACCOUNT_FIND: | |
149 if (objc != 4) { | |
150 Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); | |
151 return TCL_ERROR; | |
152 } | |
7156 | 153 Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), |
6694 | 154 Tcl_GetString(objv[3]))); |
155 break; | |
156 case CMD_ACCOUNT_HANDLE: | |
157 if (objc != 2) { | |
158 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
159 return TCL_ERROR; | |
160 } | |
161 Tcl_SetIntObj(result, (int)gaim_accounts_get_handle()); | |
162 break; | |
163 case CMD_ACCOUNT_ISCONNECTED: | |
164 if (objc != 3) { | |
165 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
166 return TCL_ERROR; | |
167 } | |
168 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
169 if (error || !tcl_validate_account(account, interp)) | |
170 return TCL_ERROR; | |
171 Tcl_SetBooleanObj(result, gaim_account_is_connected(account)); | |
172 break; | |
173 case CMD_ACCOUNT_LIST: | |
174 listopt = CMD_ACCOUNTLIST_ALL; | |
175 if (objc > 3) { | |
176 Tcl_WrongNumArgs(interp, 2, objv, "?option?"); | |
177 return TCL_ERROR; | |
178 } | |
179 if (objc == 3) { | |
180 if ((error = Tcl_GetIndexFromObj(interp, objv[2], listopts, "option", 0, (int *)&listopt)) != TCL_OK) | |
181 return error; | |
182 } | |
183 list = Tcl_NewListObj(0, NULL); | |
184 for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
185 account = cur->data; | |
186 if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account)) | |
187 continue; | |
188 elem = Tcl_NewIntObj((int)account); | |
189 Tcl_ListObjAppendElement(interp, list, elem); | |
190 } | |
191 Tcl_SetObjResult(interp, list); | |
192 break; | |
193 case CMD_ACCOUNT_PROTOCOL: | |
194 if (objc != 3) { | |
195 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
196 return TCL_ERROR; | |
197 } | |
198 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
199 if (error || !tcl_validate_account(account, interp)) | |
200 return TCL_ERROR; | |
201 Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1); | |
202 break; | |
203 case CMD_ACCOUNT_USERNAME: | |
204 if (objc != 3) { | |
205 Tcl_WrongNumArgs(interp, 2, objv, "account"); | |
206 return TCL_ERROR; | |
207 } | |
208 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); | |
209 if (error || !tcl_validate_account(account, interp)) | |
210 return TCL_ERROR; | |
211 Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1); | |
212 break; | |
213 } | |
214 | |
215 return TCL_OK; | |
216 } | |
217 | |
218 static GaimBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj **elems) | |
219 { | |
220 GaimBlistNode *node = NULL; | |
221 GaimAccount *account; | |
222 char *name; | |
223 char *type; | |
224 | |
225 if (count < 3) { | |
226 Tcl_SetStringObj(Tcl_GetObjResult(interp), "list too short", -1); | |
227 return NULL; | |
228 } | |
229 | |
230 type = Tcl_GetString(elems[0]); | |
231 name = Tcl_GetString(elems[1]); | |
232 if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK) | |
233 return NULL; | |
234 if (!tcl_validate_account(account, interp)) | |
235 return NULL; | |
236 | |
237 if (!strcmp(type, "buddy")) { | |
238 node = (GaimBlistNode *)gaim_find_buddy(account, name); | |
239 } else if (!strcmp(type, "group")) { | |
240 node = (GaimBlistNode *)gaim_blist_find_chat(account, name); | |
241 } | |
242 | |
243 return node; | |
244 } | |
245 | |
246 int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
247 { | |
6746 | 248 Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result; |
10339 | 249 const char *cmds[] = { "alias", "handle", "info", "list", NULL }; |
6694 | 250 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
|
251 GaimBuddyList *blist; |
6746 | 252 GaimBlistNode *node, *gnode, *bnode; |
6694 | 253 GaimAccount *account; |
6746 | 254 GaimBuddy *bud; |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
255 GaimChat *cnode; |
6694 | 256 int error, all = 0, count; |
257 | |
258 if (objc < 2) { | |
259 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
260 return TCL_ERROR; | |
261 } | |
262 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
263 return error; | |
264 | |
265 result = Tcl_GetObjResult(interp); | |
266 | |
267 switch (cmd) { | |
268 case CMD_BUDDY_ALIAS: | |
269 if (objc != 3) { | |
270 Tcl_WrongNumArgs(interp, 2, objv, "buddy"); | |
271 return TCL_ERROR; | |
272 } | |
273 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) | |
274 return error; | |
275 if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL) | |
276 return TCL_ERROR; | |
277 if (node->type == GAIM_BLIST_CHAT_NODE) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
278 Tcl_SetStringObj(result, ((GaimChat *)node)->alias, -1); |
6694 | 279 else if (node->type == GAIM_BLIST_BUDDY_NODE) |
9620 | 280 Tcl_SetStringObj(result, (char *)gaim_buddy_get_alias((GaimBuddy *)node), -1); |
6694 | 281 return TCL_OK; |
282 break; | |
283 case CMD_BUDDY_HANDLE: | |
284 if (objc != 2) { | |
285 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
286 return TCL_ERROR; | |
287 } | |
288 Tcl_SetIntObj(result, (int)gaim_blist_get_handle()); | |
289 break; | |
290 case CMD_BUDDY_INFO: | |
291 if (objc != 3 && objc != 4) { | |
292 Tcl_WrongNumArgs(interp, 2, objv, "( buddy | account username )"); | |
293 return TCL_ERROR; | |
294 } | |
295 if (objc == 3) { | |
296 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) | |
297 return error; | |
298 if (count < 3) { | |
299 Tcl_SetStringObj(result, "buddy too short", -1); | |
300 return TCL_ERROR; | |
301 } | |
302 if (strcmp("buddy", Tcl_GetString(elems[0]))) { | |
303 Tcl_SetStringObj(result, "invalid buddy", -1); | |
304 return TCL_ERROR; | |
305 } | |
306 if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK) | |
307 return TCL_ERROR; | |
308 if (!tcl_validate_account(account, interp)) | |
309 return TCL_ERROR; | |
310 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1])); | |
311 } else { | |
312 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK) | |
313 return error; | |
314 if (!tcl_validate_account(account, interp)) | |
315 return TCL_ERROR; | |
316 serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3])); | |
317 } | |
318 break; | |
319 case CMD_BUDDY_LIST: | |
320 if (objc == 3) { | |
321 if (!strcmp("-all", Tcl_GetString(objv[2]))) { | |
322 all = 1; | |
323 } else { | |
324 Tcl_SetStringObj(result, "", -1); | |
325 Tcl_AppendStringsToObj(result, "unknown option: ", Tcl_GetString(objv[2]), NULL); | |
326 return TCL_ERROR; | |
327 } | |
328 } | |
329 list = Tcl_NewListObj(0, NULL); | |
330 blist = gaim_get_blist(); | |
331 for (gnode = blist->root; gnode != NULL; gnode = gnode->next) { | |
332 tclgroup = Tcl_NewListObj(0, NULL); | |
333 Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1)); | |
334 Tcl_ListObjAppendElement(interp, tclgroup, | |
6700 | 335 Tcl_NewStringObj(((GaimGroup *)gnode)->name, -1)); |
6694 | 336 tclgrouplist = Tcl_NewListObj(0, NULL); |
337 for (node = gnode->child; node != NULL; node = node->next) { | |
338 switch (node->type) { | |
6746 | 339 case GAIM_BLIST_CONTACT_NODE: |
340 tclcontact = Tcl_NewListObj(0, NULL); | |
341 Tcl_IncrRefCount(tclcontact); | |
342 Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1)); | |
343 tclcontactlist = Tcl_NewListObj(0, NULL); | |
344 Tcl_IncrRefCount(tclcontactlist); | |
345 count = 0; | |
346 for (bnode = node->child; bnode != NULL; bnode = bnode ->next) { | |
347 if (bnode->type != GAIM_BLIST_BUDDY_NODE) | |
348 continue; | |
349 bud = (GaimBuddy *)bnode; | |
350 if (!all && !gaim_account_is_connected(bud->account)) | |
351 continue; | |
352 count++; | |
353 tclbud = Tcl_NewListObj(0, NULL); | |
354 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); | |
355 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1)); | |
356 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account)); | |
357 Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); | |
358 } | |
359 if (count) { | |
360 Tcl_ListObjAppendElement(interp, tclcontact, tclcontactlist); | |
361 Tcl_ListObjAppendElement(interp, tclgrouplist, tclcontact); | |
362 } | |
363 Tcl_DecrRefCount(tclcontact); | |
364 Tcl_DecrRefCount(tclcontactlist); | |
6694 | 365 break; |
366 case GAIM_BLIST_CHAT_NODE: | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
367 cnode = (GaimChat *)node; |
6694 | 368 if (!all && !gaim_account_is_connected(cnode->account)) |
369 continue; | |
370 tclbud = Tcl_NewListObj(0, NULL); | |
371 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); | |
372 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1)); | |
373 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account)); | |
6746 | 374 Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); |
6694 | 375 break; |
376 default: | |
6746 | 377 gaim_debug(GAIM_DEBUG_WARNING, "tcl", "Unexpected buddy type %d", node->type); |
6694 | 378 continue; |
379 } | |
380 } | |
381 Tcl_ListObjAppendElement(interp, tclgroup, tclgrouplist); | |
382 Tcl_ListObjAppendElement(interp, list, tclgroup); | |
383 } | |
384 Tcl_SetObjResult(interp, list); | |
385 break; | |
386 } | |
387 | |
388 return TCL_OK; | |
389 } | |
390 | |
391 int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
392 { | |
393 Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; | |
10339 | 394 const char *cmds[] = { "account", "displayname", "handle", "list", NULL }; |
7713 | 395 enum { CMD_CONN_ACCOUNT, CMD_CONN_DISPLAYNAME, CMD_CONN_HANDLE, CMD_CONN_LIST } cmd; |
6694 | 396 int error; |
397 GList *cur; | |
398 GaimConnection *gc; | |
399 | |
400 if (objc < 2) { | |
401 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
402 return TCL_ERROR; | |
403 } | |
404 | |
405 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
406 return error; | |
407 | |
408 switch (cmd) { | |
409 case CMD_CONN_ACCOUNT: | |
410 if (objc != 3) { | |
6864 | 411 Tcl_WrongNumArgs(interp, 2, objv, "gc"); |
6694 | 412 return TCL_ERROR; |
413 } | |
414 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); | |
415 if (error || !tcl_validate_gc(gc)) { | |
416 Tcl_SetStringObj(result, "invalid gc", -1); | |
417 return TCL_ERROR; | |
418 } | |
419 Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc)); | |
420 break; | |
7713 | 421 case CMD_CONN_DISPLAYNAME: |
422 if (objc != 3) { | |
423 Tcl_WrongNumArgs(interp, 2, objv, "gc"); | |
424 return TCL_ERROR; | |
425 } | |
426 error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); | |
427 if (error || !tcl_validate_gc(gc)) { | |
428 Tcl_SetStringObj(result, "invalid gc", -1); | |
429 return TCL_ERROR; | |
430 } | |
431 Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1); | |
432 break; | |
6694 | 433 case CMD_CONN_HANDLE: |
434 if (objc != 2) { | |
435 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
436 return TCL_ERROR; | |
437 } | |
438 Tcl_SetIntObj(result, (int)gaim_connections_get_handle()); | |
439 break; | |
440 case CMD_CONN_LIST: | |
441 if (objc != 2) { | |
442 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
443 return TCL_ERROR; | |
444 } | |
445 list = Tcl_NewListObj(0, NULL); | |
446 for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { | |
447 elem = Tcl_NewIntObj((int)cur->data); | |
448 Tcl_ListObjAppendElement(interp, list, elem); | |
449 } | |
450 Tcl_SetObjResult(interp, list); | |
451 break; | |
452 } | |
453 | |
454 return TCL_OK; | |
455 } | |
456 | |
457 int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
458 { | |
459 Tcl_Obj *list, *elem, *result = Tcl_GetObjResult(interp); | |
10339 | 460 const char *cmds[] = { "find", "handle", "list", "new", "write", NULL }; |
6694 | 461 enum { CMD_CONV_FIND, CMD_CONV_HANDLE, CMD_CONV_LIST, CMD_CONV_NEW, CMD_CONV_WRITE } cmd; |
10339 | 462 const char *styles[] = { "send", "recv", "system", NULL }; |
6694 | 463 enum { CMD_CONV_WRITE_SEND, CMD_CONV_WRITE_RECV, CMD_CONV_WRITE_SYSTEM } style; |
10339 | 464 const char *findopts[] = { "-account", NULL }; |
6694 | 465 enum { CMD_CONV_FIND_ACCOUNT } findopt; |
10339 | 466 const char *newopts[] = { "-chat", "-im" }; |
6694 | 467 enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt; |
468 GaimConversation *convo; | |
469 GaimAccount *account; | |
470 GaimConversationType type; | |
471 GList *cur; | |
472 char *opt, *from, *what; | |
7156 | 473 int error, argsused, flags = 0; |
6694 | 474 |
475 if (objc < 2) { | |
476 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
477 return TCL_ERROR; | |
478 } | |
479 | |
480 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
481 return error; | |
482 | |
483 switch (cmd) { | |
484 case CMD_CONV_FIND: | |
485 if (objc < 3) { | |
486 Tcl_WrongNumArgs(interp, 2, objv, "?options? name"); | |
487 return TCL_ERROR; | |
488 } | |
489 argsused = 2; | |
490 account = NULL; | |
491 while (argsused < objc) { | |
492 opt = Tcl_GetString(objv[argsused]); | |
493 if (*opt == '-') { | |
494 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], findopts, | |
495 "option", 0, (int *)&findopt)) != TCL_OK) | |
496 return error; | |
497 argsused++; | |
498 switch (findopt) { | |
499 case CMD_CONV_FIND_ACCOUNT: | |
500 if (argsused == objc - 1) { | |
501 Tcl_SetStringObj(result, "-account requires an argument", -1); | |
502 return TCL_ERROR; | |
503 } | |
504 if ((error = Tcl_GetIntFromObj(interp, objv[argsused], | |
505 (int *)&account)) != TCL_OK) | |
506 return error; | |
507 if (!tcl_validate_account(account, interp)) | |
508 return TCL_ERROR; | |
509 argsused++; | |
510 break; | |
511 } | |
512 } else { | |
513 break; | |
514 } | |
515 } | |
516 if (objc - argsused != 1) { | |
517 Tcl_WrongNumArgs(interp, 2, objv, "?options? name"); | |
518 return error; | |
519 } | |
520 if (account != NULL) { | |
10246 | 521 convo = gaim_find_conversation_with_account(GAIM_CONV_ANY, Tcl_GetString(objv[argsused]), account); |
6694 | 522 } else { |
10246 | 523 convo = gaim_find_conversation(GAIM_CONV_ANY, Tcl_GetString(objv[argsused])); |
6694 | 524 } |
525 Tcl_SetIntObj(result, (int)convo); | |
526 break; | |
527 case CMD_CONV_HANDLE: | |
528 if (objc != 2) { | |
529 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
530 return TCL_ERROR; | |
531 } | |
532 Tcl_SetIntObj(result, (int)gaim_conversations_get_handle()); | |
533 break; | |
534 case CMD_CONV_LIST: | |
535 list = Tcl_NewListObj(0, NULL); | |
536 for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { | |
537 elem = Tcl_NewIntObj((int)cur->data); | |
538 Tcl_ListObjAppendElement(interp, list, elem); | |
539 } | |
540 Tcl_SetObjResult(interp, list); | |
541 break; | |
542 case CMD_CONV_NEW: | |
543 if (objc < 4) { | |
544 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); | |
545 return TCL_ERROR; | |
546 } | |
547 argsused = 2; | |
548 type = GAIM_CONV_IM; | |
549 while (argsused < objc) { | |
550 opt = Tcl_GetString(objv[argsused]); | |
551 if (*opt == '-') { | |
552 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], newopts, | |
553 "option", 0, (int *)&newopt)) != TCL_OK) | |
554 return error; | |
555 argsused++; | |
556 switch (newopt) { | |
557 case CMD_CONV_NEW_CHAT: | |
558 type = GAIM_CONV_CHAT; | |
559 break; | |
560 case CMD_CONV_NEW_IM: | |
561 type = GAIM_CONV_IM; | |
562 break; | |
563 } | |
564 } else { | |
565 break; | |
566 } | |
567 } | |
568 if (objc - argsused != 2) { | |
569 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); | |
570 return TCL_ERROR; | |
571 } | |
572 if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK) | |
573 return error; | |
574 if (!tcl_validate_account(account, interp)) | |
575 return TCL_ERROR; | |
576 convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); | |
577 Tcl_SetIntObj(result, (int)convo); | |
578 break; | |
579 case CMD_CONV_WRITE: | |
580 if (objc != 6) { | |
581 Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); | |
582 return TCL_ERROR; | |
583 } | |
584 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK) | |
585 return error; | |
586 if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) | |
587 return error; | |
588 if (!tcl_validate_conversation(convo, interp)) | |
589 return TCL_ERROR; | |
590 from = Tcl_GetString(objv[4]); | |
591 what = Tcl_GetString(objv[5]); | |
592 | |
593 switch (style) { | |
594 case CMD_CONV_WRITE_SEND: | |
595 flags = GAIM_MESSAGE_SEND; | |
596 break; | |
597 case CMD_CONV_WRITE_RECV: | |
598 flags = GAIM_MESSAGE_RECV; | |
599 break; | |
600 case CMD_CONV_WRITE_SYSTEM: | |
601 flags = GAIM_MESSAGE_SYSTEM; | |
602 break; | |
603 } | |
604 if (gaim_conversation_get_type(convo) == GAIM_CONV_CHAT) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
605 gaim_conv_chat_write(GAIM_CONV_CHAT(convo), from, what, flags, time(NULL)); |
6694 | 606 else |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7100
diff
changeset
|
607 gaim_conv_im_write(GAIM_CONV_IM(convo), from, what, flags, time(NULL)); |
6694 | 608 break; |
609 } | |
610 | |
611 return TCL_OK; | |
612 } | |
613 | |
614 int tcl_cmd_core(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
615 { | |
616 Tcl_Obj *result = Tcl_GetObjResult(interp); | |
10339 | 617 const char *cmds[] = { "handle", "quit", NULL }; |
6694 | 618 enum { CMD_CORE_HANDLE, CMD_CORE_QUIT } cmd; |
619 int error; | |
620 | |
621 if (objc < 2) { | |
622 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
623 return TCL_ERROR; | |
624 } | |
625 | |
626 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
627 return error; | |
628 | |
629 switch (cmd) { | |
630 case CMD_CORE_HANDLE: | |
631 if (objc != 2) { | |
632 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
633 return TCL_ERROR; | |
634 } | |
635 Tcl_SetIntObj(result, (int)gaim_get_core()); | |
636 break; | |
637 case CMD_CORE_QUIT: | |
638 if (objc != 2) { | |
639 Tcl_WrongNumArgs(interp, 2, objv, ""); | |
640 return TCL_ERROR; | |
641 } | |
642 gaim_core_quit(); | |
643 break; | |
644 } | |
645 | |
646 return TCL_OK; | |
647 } | |
648 | |
649 int tcl_cmd_debug(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
650 { | |
651 char *category, *message; | |
652 int lev; | |
10339 | 653 const char *levels[] = { "-misc", "-info", "-warning", "-error", NULL }; |
6694 | 654 GaimDebugLevel levelind[] = { GAIM_DEBUG_MISC, GAIM_DEBUG_INFO, GAIM_DEBUG_WARNING, GAIM_DEBUG_ERROR }; |
655 int error; | |
656 | |
657 if (objc != 4) { | |
658 Tcl_WrongNumArgs(interp, 1, objv, "level category message"); | |
659 return TCL_ERROR; | |
660 } | |
661 | |
662 error = Tcl_GetIndexFromObj(interp, objv[1], levels, "debug level", 0, &lev); | |
663 if (error != TCL_OK) | |
664 return error; | |
665 | |
666 category = Tcl_GetString(objv[2]); | |
667 message = Tcl_GetString(objv[3]); | |
668 | |
669 gaim_debug(levelind[lev], category, "%s\n", message); | |
670 | |
671 return TCL_OK; | |
672 } | |
673 | |
674 int tcl_cmd_notify(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
675 { | |
676 int error, type; | |
10339 | 677 const char *opts[] = { "-error", "-warning", "-info", NULL }; |
6694 | 678 GaimNotifyMsgType optind[] = { GAIM_NOTIFY_MSG_ERROR, GAIM_NOTIFY_MSG_WARNING, GAIM_NOTIFY_MSG_INFO }; |
679 char *title, *msg1, *msg2; | |
680 | |
681 if (objc < 4 || objc > 5) { | |
682 Tcl_WrongNumArgs(interp, 1, objv, "?type? title primary secondary"); | |
683 return TCL_ERROR; | |
684 } | |
685 | |
686 if (objc == 4) { | |
687 title = Tcl_GetString(objv[1]); | |
688 msg1 = Tcl_GetString(objv[2]); | |
689 msg2 = Tcl_GetString(objv[3]); | |
690 } else { | |
691 error = Tcl_GetIndexFromObj(interp, objv[1], opts, "message type", 0, &type); | |
692 if (error != TCL_OK) | |
693 return error; | |
694 title = Tcl_GetString(objv[2]); | |
695 msg1 = Tcl_GetString(objv[3]); | |
696 msg2 = Tcl_GetString(objv[4]); | |
697 } | |
698 | |
699 gaim_notify_message(_tcl_plugin, optind[type], title, msg1, msg2, NULL, NULL); | |
700 | |
701 return TCL_OK; | |
702 } | |
703 | |
704 int tcl_cmd_prefs(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
705 { | |
706 Tcl_Obj *result, *list, *elem, **elems; | |
10339 | 707 const char *cmds[] = { "get", "set", "type", NULL }; |
6694 | 708 enum { CMD_PREFS_GET, CMD_PREFS_SET, CMD_PREFS_TYPE } cmd; |
709 /* char *types[] = { "none", "boolean", "int", "string", "stringlist", NULL }; */ | |
710 /* enum { TCL_PREFS_NONE, TCL_PREFS_BOOL, TCL_PREFS_INT, TCL_PREFS_STRING, TCL_PREFS_STRINGLIST } type; */ | |
711 GaimPrefType preftype; | |
712 GList *cur; | |
713 int error, intval, nelem, i; | |
714 | |
715 if (objc < 2) { | |
716 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
717 return TCL_ERROR; | |
718 } | |
719 | |
720 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
721 return error; | |
722 | |
723 result = Tcl_GetObjResult(interp); | |
724 switch (cmd) { | |
725 case CMD_PREFS_GET: | |
726 if (objc != 3) { | |
727 Tcl_WrongNumArgs(interp, 1, objv, "path"); | |
728 return TCL_ERROR; | |
729 } | |
730 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
731 switch (preftype) { | |
732 case GAIM_PREF_NONE: | |
733 Tcl_SetStringObj(result, "pref type none", -1); | |
734 return TCL_ERROR; | |
735 break; | |
736 case GAIM_PREF_BOOLEAN: | |
737 Tcl_SetBooleanObj(result, gaim_prefs_get_bool(Tcl_GetString(objv[2]))); | |
738 break; | |
739 case GAIM_PREF_INT: | |
740 Tcl_SetIntObj(result, gaim_prefs_get_int(Tcl_GetString(objv[2]))); | |
741 break; | |
742 case GAIM_PREF_STRING: | |
743 Tcl_SetStringObj(result, (char *)gaim_prefs_get_string(Tcl_GetString(objv[2])), -1); | |
744 break; | |
745 case GAIM_PREF_STRING_LIST: | |
746 cur = gaim_prefs_get_string_list(Tcl_GetString(objv[2])); | |
747 list = Tcl_NewListObj(0, NULL); | |
748 while (cur != NULL) { | |
749 elem = Tcl_NewStringObj((char *)cur->data, -1); | |
750 Tcl_ListObjAppendElement(interp, list, elem); | |
751 cur = g_list_next(cur); | |
752 } | |
753 Tcl_SetObjResult(interp, list); | |
754 break; | |
755 default: | |
756 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
757 Tcl_SetStringObj(result, "unknown pref type", -1); | |
758 return TCL_ERROR; | |
759 } | |
760 break; | |
761 case CMD_PREFS_SET: | |
762 if (objc != 4) { | |
763 Tcl_WrongNumArgs(interp, 1, objv, "path value"); | |
764 return TCL_ERROR; | |
765 } | |
766 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
767 switch (preftype) { | |
768 case GAIM_PREF_NONE: | |
769 Tcl_SetStringObj(result, "bad path or pref type none", -1); | |
770 return TCL_ERROR; | |
771 break; | |
772 case GAIM_PREF_BOOLEAN: | |
773 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &intval)) != TCL_OK) | |
774 return error; | |
775 gaim_prefs_set_bool(Tcl_GetString(objv[2]), intval); | |
776 break; | |
777 case GAIM_PREF_INT: | |
778 if ((error = Tcl_GetIntFromObj(interp, objv[3], &intval)) != TCL_OK) | |
779 return error; | |
780 gaim_prefs_set_int(Tcl_GetString(objv[2]), intval); | |
781 break; | |
782 case GAIM_PREF_STRING: | |
783 gaim_prefs_set_string(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); | |
784 break; | |
785 case GAIM_PREF_STRING_LIST: | |
786 if ((error = Tcl_ListObjGetElements(interp, objv[3], &nelem, &elems)) != TCL_OK) | |
787 return error; | |
788 cur = NULL; | |
789 for (i = 0; i < nelem; i++) { | |
790 cur = g_list_append(cur, (gpointer)Tcl_GetString(elems[i])); | |
791 } | |
792 gaim_prefs_set_string_list(Tcl_GetString(objv[2]), cur); | |
793 g_list_free(cur); | |
794 break; | |
795 default: | |
796 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
797 return TCL_ERROR; | |
798 } | |
799 break; | |
800 case CMD_PREFS_TYPE: | |
801 if (objc != 3) { | |
802 Tcl_WrongNumArgs(interp, 1, objv, "path"); | |
803 return TCL_ERROR; | |
804 } | |
805 preftype = gaim_prefs_get_type(Tcl_GetString(objv[2])); | |
806 switch (preftype) { | |
807 case GAIM_PREF_NONE: | |
808 Tcl_SetStringObj(result, "none", -1); | |
809 break; | |
810 case GAIM_PREF_BOOLEAN: | |
811 Tcl_SetStringObj(result, "boolean", -1); | |
812 break; | |
813 case GAIM_PREF_INT: | |
814 Tcl_SetStringObj(result, "int", -1); | |
815 break; | |
816 case GAIM_PREF_STRING: | |
817 Tcl_SetStringObj(result, "string", -1); | |
818 break; | |
819 case GAIM_PREF_STRING_LIST: | |
820 Tcl_SetStringObj(result, "stringlist", -1); | |
821 break; | |
822 default: | |
823 gaim_debug(GAIM_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); | |
824 Tcl_SetStringObj(result, "unknown", -1); | |
825 } | |
826 break; | |
827 } | |
828 | |
829 return TCL_OK; | |
830 } | |
831 | |
832 int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
833 { | |
834 GaimConnection *gc; | |
835 char *who, *text; | |
836 int error; | |
837 Tcl_Obj *result; | |
838 | |
839 if (objc != 4) { | |
840 Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); | |
841 return TCL_ERROR; | |
842 } | |
843 | |
844 if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK) | |
845 return error; | |
846 if (!tcl_validate_gc(gc)) { | |
847 result = Tcl_GetObjResult(interp); | |
848 Tcl_SetStringObj(result, "invalid gc", -1); | |
849 return TCL_ERROR; | |
850 } | |
851 | |
852 who = Tcl_GetString(objv[2]); | |
853 text = Tcl_GetString(objv[3]); | |
854 | |
6982 | 855 serv_send_im(gc, who, text, 0); |
6694 | 856 |
857 return TCL_OK; | |
858 } | |
859 | |
860 int tcl_cmd_signal(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
861 { | |
10339 | 862 const char *cmds[] = { "connect", "disconnect", NULL }; |
6694 | 863 enum { CMD_SIGNAL_CONNECT, CMD_SIGNAL_DISCONNECT } cmd; |
864 struct tcl_signal_handler *handler; | |
865 Tcl_Obj **elems, *result = Tcl_GetObjResult(interp); | |
866 void *instance; | |
867 int error, nelems, i; | |
868 | |
869 if (objc < 2) { | |
870 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); | |
871 return TCL_ERROR; | |
872 } | |
873 | |
874 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) | |
875 return error; | |
876 | |
877 switch (cmd) { | |
878 case CMD_SIGNAL_CONNECT: | |
879 if (objc != 6) { | |
880 Tcl_WrongNumArgs(interp, 2, objv, "instance signal args proc"); | |
881 return TCL_ERROR; | |
882 } | |
883 if ((error = Tcl_ListObjGetElements(interp, objv[4], &nelems, &elems)) != TCL_OK) | |
884 return error; | |
885 handler = g_new0(struct tcl_signal_handler, 1); | |
886 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&handler->instance)) != TCL_OK) { | |
887 g_free(handler); | |
888 return error; | |
889 } | |
890 handler->signal = g_strdup(Tcl_GetString(objv[3])); | |
891 if (nelems) { | |
892 handler->argnames = g_new0(char *, nelems); | |
893 for (i = 0; i < nelems; i++) { | |
894 handler->argnames[i] = g_strdup(Tcl_GetString(elems[i])); | |
895 } | |
896 } | |
897 handler->nnames = nelems; | |
898 handler->proc = Tcl_NewStringObj("namespace eval ::gaim::_callback { ", -1); | |
899 Tcl_AppendStringsToObj(handler->proc, Tcl_GetString(objv[5]), " }", NULL); | |
900 Tcl_IncrRefCount(handler->proc); | |
901 handler->interp = interp; | |
902 if (!tcl_signal_connect(handler)) { | |
903 tcl_signal_handler_free(handler); | |
904 Tcl_SetIntObj(result, 1); | |
905 } else { | |
906 Tcl_SetIntObj(result, 0); | |
907 } | |
908 break; | |
909 case CMD_SIGNAL_DISCONNECT: | |
910 if (objc != 4) { | |
911 Tcl_WrongNumArgs(interp, 2, objv, "signal"); | |
912 return TCL_ERROR; | |
913 } | |
914 if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK) | |
915 return error; | |
916 tcl_signal_disconnect(instance, Tcl_GetString(objv[3]), interp); | |
917 break; | |
918 } | |
919 | |
920 return TCL_OK; | |
921 } | |
922 | |
923 static gboolean unload_self(gpointer data) | |
924 { | |
925 GaimPlugin *plugin = data; | |
926 gaim_plugin_unload(plugin); | |
927 return FALSE; | |
928 } | |
929 | |
930 int tcl_cmd_unload(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) | |
931 { | |
932 GaimPlugin *plugin; | |
933 if (objc != 1) { | |
934 Tcl_WrongNumArgs(interp, 1, objv, ""); | |
935 return TCL_ERROR; | |
936 } | |
937 | |
938 if ((plugin = tcl_interp_get_plugin(interp)) == NULL) { | |
939 /* This isn't exactly OK, but heh. What do you do? */ | |
940 return TCL_OK; | |
941 } | |
942 /* We can't unload immediately, but we can unload at the first | |
943 * known safe opportunity. */ | |
944 g_idle_add(unload_self, (gpointer)plugin); | |
945 | |
946 return TCL_OK; | |
947 } |