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