| 1 /** |
|
| 2 * @file tcl_cmds.c Commands for the Purple Tcl plugin bindings |
|
| 3 * |
|
| 4 * purple |
|
| 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
|
| 21 */ |
|
| 22 |
|
| 23 #include <tcl.h> |
|
| 24 |
|
| 25 #include "internal.h" |
|
| 26 #include "conversation.h" |
|
| 27 #include "connection.h" |
|
| 28 #include "eventloop.h" |
|
| 29 #include "account.h" |
|
| 30 #include "server.h" |
|
| 31 #include "notify.h" |
|
| 32 #include "buddylist.h" |
|
| 33 #include "savedstatuses.h" |
|
| 34 #include "debug.h" |
|
| 35 #include "prefs.h" |
|
| 36 #include "presence.h" |
|
| 37 #include "core.h" |
|
| 38 |
|
| 39 #include "tcl_purple.h" |
|
| 40 |
|
| 41 static PurpleAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); |
|
| 42 static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); |
|
| 43 static PurpleConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp); |
|
| 44 |
|
| 45 static PurpleAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) |
|
| 46 { |
|
| 47 PurpleAccount *account; |
|
| 48 GList *cur; |
|
| 49 |
|
| 50 account = purple_tcl_ref_get(interp, obj, PurpleTclRefAccount); |
|
| 51 |
|
| 52 if (account == NULL) |
|
| 53 return NULL; |
|
| 54 |
|
| 55 for (cur = purple_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 56 if (account == cur->data) |
|
| 57 return account; |
|
| 58 } |
|
| 59 if (interp != NULL) |
|
| 60 Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid account", -1)); |
|
| 61 return NULL; |
|
| 62 } |
|
| 63 |
|
| 64 static PurpleConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp) |
|
| 65 { |
|
| 66 PurpleConversation *convo; |
|
| 67 GList *cur; |
|
| 68 |
|
| 69 convo = purple_tcl_ref_get(interp, obj, PurpleTclRefConversation); |
|
| 70 |
|
| 71 if (convo == NULL) |
|
| 72 return NULL; |
|
| 73 |
|
| 74 for (cur = purple_conversations_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 75 if (convo == cur->data) |
|
| 76 return convo; |
|
| 77 } |
|
| 78 if (interp != NULL) |
|
| 79 Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid conversation", -1)); |
|
| 80 return NULL; |
|
| 81 } |
|
| 82 |
|
| 83 static PurpleConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp) |
|
| 84 { |
|
| 85 PurpleConnection *gc; |
|
| 86 GList *cur; |
|
| 87 |
|
| 88 gc = purple_tcl_ref_get(interp, obj, PurpleTclRefConnection); |
|
| 89 |
|
| 90 if (gc == NULL) |
|
| 91 return NULL; |
|
| 92 |
|
| 93 for (cur = purple_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 94 if (gc == cur->data) |
|
| 95 return gc; |
|
| 96 } |
|
| 97 return NULL; |
|
| 98 } |
|
| 99 |
|
| 100 int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 101 { |
|
| 102 Tcl_Obj *result, *list, *elem; |
|
| 103 const char *cmds[] = { "alias", "connect", "connection", "disconnect", |
|
| 104 "enabled", "find", "handle", "isconnected", |
|
| 105 "list", "presence", "protocol", "status", |
|
| 106 "status_type", "status_types", "username", |
|
| 107 NULL }; |
|
| 108 enum { CMD_ACCOUNT_ALIAS, |
|
| 109 CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, |
|
| 110 CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, |
|
| 111 CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, |
|
| 112 CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS, |
|
| 113 CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES, |
|
| 114 CMD_ACCOUNT_USERNAME } cmd; |
|
| 115 const char *listopts[] = { "-all", "-online", NULL }; |
|
| 116 enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; |
|
| 117 const char *alias; |
|
| 118 GList *cur; |
|
| 119 PurpleAccount *account; |
|
| 120 PurpleStatus *status; |
|
| 121 PurpleStatusType *status_type; |
|
| 122 GValue *value; |
|
| 123 char *attr_id; |
|
| 124 int error; |
|
| 125 int b, i; |
|
| 126 |
|
| 127 if (objc < 2) { |
|
| 128 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 129 return TCL_ERROR; |
|
| 130 } |
|
| 131 |
|
| 132 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 133 return error; |
|
| 134 |
|
| 135 switch (cmd) { |
|
| 136 case CMD_ACCOUNT_ALIAS: |
|
| 137 if (objc != 3) { |
|
| 138 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 139 return TCL_ERROR; |
|
| 140 } |
|
| 141 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 142 return TCL_ERROR; |
|
| 143 alias = purple_account_get_private_alias(account); |
|
| 144 Tcl_SetObjResult(interp, Tcl_NewStringObj(alias ? (char *)alias : "", -1)); |
|
| 145 break; |
|
| 146 case CMD_ACCOUNT_CONNECT: |
|
| 147 if (objc != 3) { |
|
| 148 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 149 return TCL_ERROR; |
|
| 150 } |
|
| 151 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 152 return TCL_ERROR; |
|
| 153 if (!purple_account_is_connected(account)) |
|
| 154 purple_account_connect(account); |
|
| 155 Tcl_SetObjResult(interp, |
|
| 156 purple_tcl_ref_new(PurpleTclRefConnection, |
|
| 157 purple_account_get_connection(account))); |
|
| 158 break; |
|
| 159 case CMD_ACCOUNT_CONNECTION: |
|
| 160 if (objc != 3) { |
|
| 161 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 162 return TCL_ERROR; |
|
| 163 } |
|
| 164 |
|
| 165 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 166 return TCL_ERROR; |
|
| 167 Tcl_SetObjResult(interp, |
|
| 168 purple_tcl_ref_new(PurpleTclRefConnection, |
|
| 169 purple_account_get_connection(account))); |
|
| 170 break; |
|
| 171 case CMD_ACCOUNT_DISCONNECT: |
|
| 172 if (objc != 3) { |
|
| 173 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 174 return TCL_ERROR; |
|
| 175 } |
|
| 176 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 177 return TCL_ERROR; |
|
| 178 purple_account_disconnect(account); |
|
| 179 break; |
|
| 180 case CMD_ACCOUNT_ENABLED: |
|
| 181 if (objc != 3 && objc != 4) { |
|
| 182 Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?"); |
|
| 183 return TCL_ERROR; |
|
| 184 } |
|
| 185 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 186 return TCL_ERROR; |
|
| 187 if (objc == 3) { |
|
| 188 Tcl_SetObjResult(interp, |
|
| 189 Tcl_NewBooleanObj( |
|
| 190 purple_account_get_enabled(account, |
|
| 191 purple_core_get_ui()))); |
|
| 192 } else { |
|
| 193 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK) |
|
| 194 return TCL_ERROR; |
|
| 195 purple_account_set_enabled(account, purple_core_get_ui(), b); |
|
| 196 } |
|
| 197 break; |
|
| 198 case CMD_ACCOUNT_FIND: |
|
| 199 if (objc != 4) { |
|
| 200 Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); |
|
| 201 return TCL_ERROR; |
|
| 202 } |
|
| 203 account = purple_accounts_find(Tcl_GetString(objv[2]), |
|
| 204 Tcl_GetString(objv[3])); |
|
| 205 Tcl_SetObjResult(interp, |
|
| 206 purple_tcl_ref_new(PurpleTclRefAccount, account)); |
|
| 207 break; |
|
| 208 case CMD_ACCOUNT_HANDLE: |
|
| 209 if (objc != 2) { |
|
| 210 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 211 return TCL_ERROR; |
|
| 212 } |
|
| 213 Tcl_SetObjResult(interp, |
|
| 214 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 215 purple_accounts_get_handle())); |
|
| 216 break; |
|
| 217 case CMD_ACCOUNT_ISCONNECTED: |
|
| 218 if (objc != 3) { |
|
| 219 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 220 return TCL_ERROR; |
|
| 221 } |
|
| 222 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 223 return TCL_ERROR; |
|
| 224 Tcl_SetObjResult(interp, |
|
| 225 Tcl_NewBooleanObj( |
|
| 226 purple_account_is_connected(account))); |
|
| 227 break; |
|
| 228 case CMD_ACCOUNT_LIST: |
|
| 229 listopt = CMD_ACCOUNTLIST_ALL; |
|
| 230 if (objc > 3) { |
|
| 231 Tcl_WrongNumArgs(interp, 2, objv, "?option?"); |
|
| 232 return TCL_ERROR; |
|
| 233 } |
|
| 234 if (objc == 3) { |
|
| 235 if ((error = Tcl_GetIndexFromObj(interp, objv[2], listopts, "option", 0, (int *)&listopt)) != TCL_OK) |
|
| 236 return error; |
|
| 237 } |
|
| 238 list = Tcl_NewListObj(0, NULL); |
|
| 239 for (cur = purple_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 240 account = cur->data; |
|
| 241 if (listopt == CMD_ACCOUNTLIST_ONLINE && !purple_account_is_connected(account)) |
|
| 242 continue; |
|
| 243 elem = purple_tcl_ref_new(PurpleTclRefAccount, account); |
|
| 244 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 245 } |
|
| 246 Tcl_SetObjResult(interp, list); |
|
| 247 break; |
|
| 248 case CMD_ACCOUNT_PRESENCE: |
|
| 249 if (objc != 3) { |
|
| 250 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 251 return TCL_ERROR; |
|
| 252 } |
|
| 253 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 254 return TCL_ERROR; |
|
| 255 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefPresence, |
|
| 256 purple_account_get_presence(account))); |
|
| 257 break; |
|
| 258 case CMD_ACCOUNT_PROTOCOL: |
|
| 259 if (objc != 3) { |
|
| 260 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 261 return TCL_ERROR; |
|
| 262 } |
|
| 263 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 264 return TCL_ERROR; |
|
| 265 Tcl_SetObjResult(interp, Tcl_NewStringObj((char *)purple_account_get_protocol_id(account), -1)); |
|
| 266 break; |
|
| 267 case CMD_ACCOUNT_STATUS: |
|
| 268 if (objc < 3) { |
|
| 269 Tcl_WrongNumArgs(interp, 2, objv, "account ?status_id name value ...?"); |
|
| 270 return TCL_ERROR; |
|
| 271 } |
|
| 272 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 273 return TCL_ERROR; |
|
| 274 if (objc == 3) { |
|
| 275 Tcl_SetObjResult(interp, |
|
| 276 purple_tcl_ref_new(PurpleTclRefStatus, |
|
| 277 purple_account_get_active_status(account))); |
|
| 278 } else { |
|
| 279 GList *l = NULL; |
|
| 280 if (objc % 2) { |
|
| 281 Tcl_SetObjResult(interp, Tcl_NewStringObj("name without value setting status", -1)); |
|
| 282 return TCL_ERROR; |
|
| 283 } |
|
| 284 status = purple_account_get_status(account, Tcl_GetString(objv[3])); |
|
| 285 if (status == NULL) { |
|
| 286 Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid status for account", -1)); |
|
| 287 return TCL_ERROR; |
|
| 288 } |
|
| 289 for (i = 4; i < objc; i += 2) { |
|
| 290 attr_id = Tcl_GetString(objv[i]); |
|
| 291 value = purple_status_get_attr_value(status, attr_id); |
|
| 292 if (value == NULL) { |
|
| 293 Tcl_SetObjResult(interp, Tcl_NewStringObj("invalid attribute for account", -1)); |
|
| 294 return TCL_ERROR; |
|
| 295 } |
|
| 296 switch (G_VALUE_TYPE(value)) { |
|
| 297 case G_TYPE_BOOLEAN: |
|
| 298 error = Tcl_GetBooleanFromObj(interp, objv[i + 1], &b); |
|
| 299 if (error != TCL_OK) |
|
| 300 return error; |
|
| 301 l = g_list_append(l, attr_id); |
|
| 302 l = g_list_append(l, GINT_TO_POINTER(b)); |
|
| 303 break; |
|
| 304 case G_TYPE_INT: |
|
| 305 error = Tcl_GetIntFromObj(interp, objv[i + 1], &b); |
|
| 306 if (error != TCL_OK) |
|
| 307 return error; |
|
| 308 l = g_list_append(l, attr_id); |
|
| 309 l = g_list_append(l, GINT_TO_POINTER(b)); |
|
| 310 break; |
|
| 311 case G_TYPE_STRING: |
|
| 312 l = g_list_append(l, attr_id); |
|
| 313 l = g_list_append(l, Tcl_GetString(objv[i + 1])); |
|
| 314 break; |
|
| 315 default: |
|
| 316 Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown GValue type", -1)); |
|
| 317 return TCL_ERROR; |
|
| 318 } |
|
| 319 } |
|
| 320 purple_account_set_status_list(account, Tcl_GetString(objv[3]), TRUE, l); |
|
| 321 g_list_free(l); |
|
| 322 } |
|
| 323 break; |
|
| 324 case CMD_ACCOUNT_STATUS_TYPE: |
|
| 325 if (objc != 4 && objc != 5) { |
|
| 326 Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?"); |
|
| 327 return TCL_ERROR; |
|
| 328 } |
|
| 329 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 330 return TCL_ERROR; |
|
| 331 if (objc == 4) { |
|
| 332 status_type = purple_account_get_status_type(account, |
|
| 333 Tcl_GetString(objv[3])); |
|
| 334 } else { |
|
| 335 PurpleStatusPrimitive primitive; |
|
| 336 if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { |
|
| 337 result = Tcl_NewStringObj("bad option \"", -1); |
|
| 338 Tcl_AppendObjToObj(result, objv[3]); |
|
| 339 Tcl_AppendToObj(result, "\": should be -primitive", -1); |
|
| 340 Tcl_SetObjResult(interp,result); |
|
| 341 return TCL_ERROR; |
|
| 342 } |
|
| 343 primitive = purple_primitive_get_type_from_id(Tcl_GetString(objv[4])); |
|
| 344 status_type = purple_account_get_status_type_with_primitive(account, |
|
| 345 primitive); |
|
| 346 } |
|
| 347 if (status_type == NULL) { |
|
| 348 Tcl_SetObjResult(interp, Tcl_NewStringObj("status type not found", -1)); |
|
| 349 return TCL_ERROR; |
|
| 350 } |
|
| 351 Tcl_SetObjResult(interp, |
|
| 352 purple_tcl_ref_new(PurpleTclRefStatusType, |
|
| 353 status_type)); |
|
| 354 break; |
|
| 355 case CMD_ACCOUNT_STATUS_TYPES: |
|
| 356 if (objc != 3) { |
|
| 357 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 358 return TCL_ERROR; |
|
| 359 } |
|
| 360 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 361 return TCL_ERROR; |
|
| 362 list = Tcl_NewListObj(0, NULL); |
|
| 363 for (cur = purple_account_get_status_types(account); cur != NULL; |
|
| 364 cur = g_list_next(cur)) { |
|
| 365 Tcl_ListObjAppendElement(interp, list, |
|
| 366 purple_tcl_ref_new(PurpleTclRefStatusType, |
|
| 367 cur->data)); |
|
| 368 } |
|
| 369 Tcl_SetObjResult(interp, list); |
|
| 370 break; |
|
| 371 case CMD_ACCOUNT_USERNAME: |
|
| 372 if (objc != 3) { |
|
| 373 Tcl_WrongNumArgs(interp, 2, objv, "account"); |
|
| 374 return TCL_ERROR; |
|
| 375 } |
|
| 376 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 377 return TCL_ERROR; |
|
| 378 Tcl_SetObjResult(interp, |
|
| 379 Tcl_NewStringObj((char *)purple_account_get_username(account), -1)); |
|
| 380 break; |
|
| 381 } |
|
| 382 |
|
| 383 return TCL_OK; |
|
| 384 } |
|
| 385 |
|
| 386 static PurpleBlistNode *tcl_list_to_buddy(Tcl_Interp *interp, int count, Tcl_Obj **elems) |
|
| 387 { |
|
| 388 PurpleBlistNode *node = NULL; |
|
| 389 PurpleAccount *account; |
|
| 390 char *name; |
|
| 391 char *type; |
|
| 392 |
|
| 393 if (count < 3) { |
|
| 394 Tcl_SetObjResult(interp, |
|
| 395 Tcl_NewStringObj("list too short", -1)); |
|
| 396 return NULL; |
|
| 397 } |
|
| 398 |
|
| 399 type = Tcl_GetString(elems[0]); |
|
| 400 name = Tcl_GetString(elems[1]); |
|
| 401 if ((account = tcl_validate_account(elems[2], interp)) == NULL) |
|
| 402 return NULL; |
|
| 403 |
|
| 404 if (!strcmp(type, "buddy")) { |
|
| 405 node = PURPLE_BLIST_NODE(purple_blist_find_buddy(account, name)); |
|
| 406 } else if (!strcmp(type, "group")) { |
|
| 407 node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, name)); |
|
| 408 } |
|
| 409 |
|
| 410 return node; |
|
| 411 } |
|
| 412 |
|
| 413 int tcl_cmd_buddy(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 414 { |
|
| 415 Tcl_Obj *list, *tclgroup, *tclgrouplist, *tclcontact, *tclcontactlist, *tclbud, **elems, *result; |
|
| 416 const char *cmds[] = { "alias", "handle", "info", "list", NULL }; |
|
| 417 enum { CMD_BUDDY_ALIAS, CMD_BUDDY_HANDLE, CMD_BUDDY_INFO, CMD_BUDDY_LIST } cmd; |
|
| 418 PurpleBlistNode *node, *gnode, *bnode; |
|
| 419 PurpleAccount *account; |
|
| 420 PurpleBuddy *bud; |
|
| 421 PurpleChat *cnode; |
|
| 422 int error, all = 0, count; |
|
| 423 |
|
| 424 if (objc < 2) { |
|
| 425 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 426 return TCL_ERROR; |
|
| 427 } |
|
| 428 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 429 return error; |
|
| 430 |
|
| 431 switch (cmd) { |
|
| 432 case CMD_BUDDY_ALIAS: |
|
| 433 if (objc != 3) { |
|
| 434 Tcl_WrongNumArgs(interp, 2, objv, "buddy"); |
|
| 435 return TCL_ERROR; |
|
| 436 } |
|
| 437 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) |
|
| 438 return error; |
|
| 439 if ((node = tcl_list_to_buddy(interp, count, elems)) == NULL) |
|
| 440 return TCL_ERROR; |
|
| 441 if (PURPLE_IS_CHAT(node)) |
|
| 442 Tcl_SetObjResult(interp, |
|
| 443 Tcl_NewStringObj(purple_chat_get_name(PURPLE_CHAT(node)), -1)); |
|
| 444 else if (PURPLE_IS_BUDDY(node)) |
|
| 445 Tcl_SetObjResult(interp, |
|
| 446 Tcl_NewStringObj((char *)purple_buddy_get_alias(PURPLE_BUDDY(node)), -1)); |
|
| 447 return TCL_OK; |
|
| 448 break; |
|
| 449 case CMD_BUDDY_HANDLE: |
|
| 450 if (objc != 2) { |
|
| 451 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 452 return TCL_ERROR; |
|
| 453 } |
|
| 454 Tcl_SetObjResult(interp, |
|
| 455 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 456 purple_blist_get_handle())); |
|
| 457 break; |
|
| 458 case CMD_BUDDY_INFO: |
|
| 459 if (objc != 3 && objc != 4) { |
|
| 460 Tcl_WrongNumArgs(interp, 2, objv, "( buddy | account username )"); |
|
| 461 return TCL_ERROR; |
|
| 462 } |
|
| 463 if (objc == 3) { |
|
| 464 if ((error = Tcl_ListObjGetElements(interp, objv[2], &count, &elems)) != TCL_OK) |
|
| 465 return error; |
|
| 466 if (count < 3) { |
|
| 467 Tcl_SetObjResult(interp, |
|
| 468 Tcl_NewStringObj("buddy too short", -1)); |
|
| 469 return TCL_ERROR; |
|
| 470 } |
|
| 471 if (strcmp("buddy", Tcl_GetString(elems[0]))) { |
|
| 472 Tcl_SetObjResult(interp, |
|
| 473 Tcl_NewStringObj("invalid buddy", -1)); |
|
| 474 return TCL_ERROR; |
|
| 475 } |
|
| 476 if ((account = tcl_validate_account(elems[2], interp)) == NULL) |
|
| 477 return TCL_ERROR; |
|
| 478 purple_serv_get_info(purple_account_get_connection(account), Tcl_GetString(elems[1])); |
|
| 479 } else { |
|
| 480 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 481 return TCL_ERROR; |
|
| 482 purple_serv_get_info(purple_account_get_connection(account), Tcl_GetString(objv[3])); |
|
| 483 } |
|
| 484 break; |
|
| 485 case CMD_BUDDY_LIST: |
|
| 486 if (objc == 3) { |
|
| 487 if (!strcmp("-all", Tcl_GetString(objv[2]))) { |
|
| 488 all = 1; |
|
| 489 } else { |
|
| 490 result = Tcl_NewStringObj("",-1); |
|
| 491 Tcl_AppendStringsToObj(result, "unknown option: ", Tcl_GetString(objv[2]), NULL); |
|
| 492 Tcl_SetObjResult(interp,result); |
|
| 493 return TCL_ERROR; |
|
| 494 } |
|
| 495 } |
|
| 496 list = Tcl_NewListObj(0, NULL); |
|
| 497 for (gnode = purple_blist_get_root(); gnode != NULL; gnode = purple_blist_node_get_sibling_next(gnode)) { |
|
| 498 tclgroup = Tcl_NewListObj(0, NULL); |
|
| 499 Tcl_ListObjAppendElement(interp, tclgroup, Tcl_NewStringObj("group", -1)); |
|
| 500 Tcl_ListObjAppendElement(interp, tclgroup, |
|
| 501 Tcl_NewStringObj(purple_group_get_name(PURPLE_GROUP(gnode)), -1)); |
|
| 502 tclgrouplist = Tcl_NewListObj(0, NULL); |
|
| 503 for (node = purple_blist_node_get_first_child(gnode); node != NULL; node = purple_blist_node_get_sibling_next(node)) { |
|
| 504 PurpleAccount *account; |
|
| 505 |
|
| 506 if (PURPLE_IS_CONTACT(node)) { |
|
| 507 tclcontact = Tcl_NewListObj(0, NULL); |
|
| 508 Tcl_IncrRefCount(tclcontact); |
|
| 509 Tcl_ListObjAppendElement(interp, tclcontact, Tcl_NewStringObj("contact", -1)); |
|
| 510 tclcontactlist = Tcl_NewListObj(0, NULL); |
|
| 511 Tcl_IncrRefCount(tclcontactlist); |
|
| 512 count = 0; |
|
| 513 for (bnode = purple_blist_node_get_first_child(node); bnode != NULL; bnode = purple_blist_node_get_sibling_next(bnode)) { |
|
| 514 if (!PURPLE_IS_BUDDY(bnode)) |
|
| 515 continue; |
|
| 516 bud = PURPLE_BUDDY(bnode); |
|
| 517 account = purple_buddy_get_account(bud); |
|
| 518 if (!all && !purple_account_is_connected(account)) |
|
| 519 continue; |
|
| 520 count++; |
|
| 521 tclbud = Tcl_NewListObj(0, NULL); |
|
| 522 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); |
|
| 523 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(purple_buddy_get_name(bud), -1)); |
|
| 524 Tcl_ListObjAppendElement(interp, tclbud, purple_tcl_ref_new(PurpleTclRefAccount, account)); |
|
| 525 Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); |
|
| 526 } |
|
| 527 if (count) { |
|
| 528 Tcl_ListObjAppendElement(interp, tclcontact, tclcontactlist); |
|
| 529 Tcl_ListObjAppendElement(interp, tclgrouplist, tclcontact); |
|
| 530 } |
|
| 531 Tcl_DecrRefCount(tclcontact); |
|
| 532 Tcl_DecrRefCount(tclcontactlist); |
|
| 533 } else if (PURPLE_IS_CHAT(node)) { |
|
| 534 cnode = PURPLE_CHAT(node); |
|
| 535 account = purple_chat_get_account(cnode); |
|
| 536 if (!all && !purple_account_is_connected(account)) |
|
| 537 continue; |
|
| 538 tclbud = Tcl_NewListObj(0, NULL); |
|
| 539 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); |
|
| 540 Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(purple_chat_get_name(cnode), -1)); |
|
| 541 Tcl_ListObjAppendElement(interp, tclbud, purple_tcl_ref_new(PurpleTclRefAccount, account)); |
|
| 542 Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); |
|
| 543 } else { |
|
| 544 purple_debug(PURPLE_DEBUG_WARNING, "tcl", "Unexpected buddy type %s", G_OBJECT_TYPE_NAME(node)); |
|
| 545 continue; |
|
| 546 } |
|
| 547 } |
|
| 548 Tcl_ListObjAppendElement(interp, tclgroup, tclgrouplist); |
|
| 549 Tcl_ListObjAppendElement(interp, list, tclgroup); |
|
| 550 } |
|
| 551 Tcl_SetObjResult(interp, list); |
|
| 552 break; |
|
| 553 } |
|
| 554 |
|
| 555 return TCL_OK; |
|
| 556 } |
|
| 557 |
|
| 558 int tcl_cmd_cmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 559 { |
|
| 560 const char *cmds[] = { "do", "help", "list", "register", "unregister", NULL }; |
|
| 561 enum { CMD_CMD_DO, CMD_CMD_HELP, CMD_CMD_LIST, CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd; |
|
| 562 struct tcl_cmd_handler *handler; |
|
| 563 Tcl_Obj *list, *elem; |
|
| 564 PurpleConversation *convo; |
|
| 565 PurpleCmdId id; |
|
| 566 PurpleCmdStatus status; |
|
| 567 int error; |
|
| 568 GList *l, *cur; |
|
| 569 gchar *escaped, *errstr = NULL; |
|
| 570 |
|
| 571 if (objc < 2) { |
|
| 572 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 573 return TCL_ERROR; |
|
| 574 } |
|
| 575 |
|
| 576 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 577 return error; |
|
| 578 |
|
| 579 switch (cmd) { |
|
| 580 case CMD_CMD_DO: |
|
| 581 if (objc != 4) { |
|
| 582 Tcl_WrongNumArgs(interp, 2, objv, "conversation command"); |
|
| 583 return TCL_ERROR; |
|
| 584 } |
|
| 585 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 586 return TCL_ERROR; |
|
| 587 escaped = g_markup_escape_text(Tcl_GetString(objv[3]), -1); |
|
| 588 status = purple_cmd_do_command(convo, Tcl_GetString(objv[3]), |
|
| 589 escaped, &errstr); |
|
| 590 g_free(escaped); |
|
| 591 Tcl_SetObjResult(interp, |
|
| 592 Tcl_NewStringObj(errstr ? (char *)errstr : "", -1)); |
|
| 593 g_free(errstr); |
|
| 594 if (status != PURPLE_CMD_STATUS_OK) { |
|
| 595 return TCL_ERROR; |
|
| 596 } |
|
| 597 break; |
|
| 598 case CMD_CMD_HELP: |
|
| 599 if (objc != 4) { |
|
| 600 Tcl_WrongNumArgs(interp, 2, objv, "conversation name"); |
|
| 601 return TCL_ERROR; |
|
| 602 } |
|
| 603 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 604 return TCL_ERROR; |
|
| 605 l = cur = purple_cmd_help(convo, Tcl_GetString(objv[3])); |
|
| 606 list = Tcl_NewListObj(0, NULL); |
|
| 607 while (cur != NULL) { |
|
| 608 elem = Tcl_NewStringObj((char *)cur->data, -1); |
|
| 609 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 610 cur = g_list_next(cur); |
|
| 611 } |
|
| 612 g_list_free(l); |
|
| 613 Tcl_SetObjResult(interp, list); |
|
| 614 break; |
|
| 615 case CMD_CMD_LIST: |
|
| 616 if (objc != 3) { |
|
| 617 Tcl_WrongNumArgs(interp, 2, objv, "conversation"); |
|
| 618 return TCL_ERROR; |
|
| 619 } |
|
| 620 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 621 return TCL_ERROR; |
|
| 622 l = cur = purple_cmd_list(convo); |
|
| 623 list = Tcl_NewListObj(0, NULL); |
|
| 624 while (cur != NULL) { |
|
| 625 elem = Tcl_NewStringObj((char *)cur->data, -1); |
|
| 626 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 627 cur = g_list_next(cur); |
|
| 628 } |
|
| 629 g_list_free(l); |
|
| 630 Tcl_SetObjResult(interp, list); |
|
| 631 break; |
|
| 632 case CMD_CMD_REGISTER: |
|
| 633 if (objc != 9) { |
|
| 634 Tcl_WrongNumArgs(interp, 2, objv, "cmd arglist priority flags protocol_id proc helpstr"); |
|
| 635 return TCL_ERROR; |
|
| 636 } |
|
| 637 handler = g_new0(struct tcl_cmd_handler, 1); |
|
| 638 handler->cmd = objv[2]; |
|
| 639 handler->args = Tcl_GetString(objv[3]); |
|
| 640 handler->nargs = strlen(handler->args); |
|
| 641 if ((error = Tcl_GetIntFromObj(interp, objv[4], |
|
| 642 &handler->priority)) != TCL_OK) { |
|
| 643 g_free(handler); |
|
| 644 return error; |
|
| 645 } |
|
| 646 if ((error = Tcl_GetIntFromObj(interp, objv[5], |
|
| 647 &handler->flags)) != TCL_OK) { |
|
| 648 g_free(handler); |
|
| 649 return error; |
|
| 650 } |
|
| 651 handler->protocol_id = Tcl_GetString(objv[6]); |
|
| 652 handler->proc = objv[7]; |
|
| 653 handler->helpstr = Tcl_GetString(objv[8]); |
|
| 654 handler->interp = interp; |
|
| 655 if ((id = tcl_cmd_register(handler)) == 0) { |
|
| 656 tcl_cmd_handler_free(handler); |
|
| 657 Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); |
|
| 658 } else { |
|
| 659 handler->id = id; |
|
| 660 Tcl_SetObjResult(interp, Tcl_NewIntObj(id)); |
|
| 661 } |
|
| 662 break; |
|
| 663 case CMD_CMD_UNREGISTER: |
|
| 664 if (objc != 3) { |
|
| 665 Tcl_WrongNumArgs(interp, 2, objv, "id"); |
|
| 666 return TCL_ERROR; |
|
| 667 } |
|
| 668 if ((error = Tcl_GetIntFromObj(interp, objv[2], |
|
| 669 (int *)&id)) != TCL_OK) |
|
| 670 return error; |
|
| 671 tcl_cmd_unregister(id, interp); |
|
| 672 break; |
|
| 673 } |
|
| 674 |
|
| 675 return TCL_OK; |
|
| 676 } |
|
| 677 |
|
| 678 int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 679 { |
|
| 680 Tcl_Obj *list, *elem; |
|
| 681 const char *cmds[] = { "account", "displayname", "handle", "list", "state", NULL }; |
|
| 682 enum { CMD_CONN_ACCOUNT, CMD_CONN_DISPLAYNAME, CMD_CONN_HANDLE, |
|
| 683 CMD_CONN_LIST, CMD_CONN_STATE } cmd; |
|
| 684 int error; |
|
| 685 GList *cur; |
|
| 686 PurpleConnection *gc; |
|
| 687 |
|
| 688 if (objc < 2) { |
|
| 689 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 690 return TCL_ERROR; |
|
| 691 } |
|
| 692 |
|
| 693 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 694 return error; |
|
| 695 |
|
| 696 switch (cmd) { |
|
| 697 case CMD_CONN_ACCOUNT: |
|
| 698 if (objc != 3) { |
|
| 699 Tcl_WrongNumArgs(interp, 2, objv, "gc"); |
|
| 700 return TCL_ERROR; |
|
| 701 } |
|
| 702 if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) |
|
| 703 return TCL_ERROR; |
|
| 704 Tcl_SetObjResult(interp, |
|
| 705 purple_tcl_ref_new(PurpleTclRefAccount, |
|
| 706 purple_connection_get_account(gc))); |
|
| 707 break; |
|
| 708 case CMD_CONN_DISPLAYNAME: |
|
| 709 if (objc != 3) { |
|
| 710 Tcl_WrongNumArgs(interp, 2, objv, "gc"); |
|
| 711 return TCL_ERROR; |
|
| 712 } |
|
| 713 if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) |
|
| 714 return TCL_ERROR; |
|
| 715 Tcl_SetObjResult(interp, |
|
| 716 Tcl_NewStringObj(purple_connection_get_display_name(gc), -1)); |
|
| 717 break; |
|
| 718 case CMD_CONN_HANDLE: |
|
| 719 if (objc != 2) { |
|
| 720 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 721 return TCL_ERROR; |
|
| 722 } |
|
| 723 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 724 purple_connections_get_handle())); |
|
| 725 break; |
|
| 726 case CMD_CONN_LIST: |
|
| 727 if (objc != 2) { |
|
| 728 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 729 return TCL_ERROR; |
|
| 730 } |
|
| 731 list = Tcl_NewListObj(0, NULL); |
|
| 732 for (cur = purple_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 733 elem = purple_tcl_ref_new(PurpleTclRefConnection, cur->data); |
|
| 734 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 735 } |
|
| 736 Tcl_SetObjResult(interp, list); |
|
| 737 break; |
|
| 738 case CMD_CONN_STATE: |
|
| 739 if (objc != 3) { |
|
| 740 Tcl_WrongNumArgs(interp, 2, objv, "gc"); |
|
| 741 return TCL_ERROR; |
|
| 742 } |
|
| 743 if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) |
|
| 744 return TCL_ERROR; |
|
| 745 switch (purple_connection_get_state(gc)) { |
|
| 746 case PURPLE_CONNECTION_DISCONNECTED: |
|
| 747 Tcl_SetObjResult(interp, Tcl_NewStringObj("disconnected", -1)); |
|
| 748 break; |
|
| 749 case PURPLE_CONNECTION_CONNECTED: |
|
| 750 Tcl_SetObjResult(interp, Tcl_NewStringObj("connected", -1)); |
|
| 751 break; |
|
| 752 case PURPLE_CONNECTION_CONNECTING: |
|
| 753 Tcl_SetObjResult(interp, Tcl_NewStringObj("connecting", -1)); |
|
| 754 break; |
|
| 755 } |
|
| 756 break; |
|
| 757 } |
|
| 758 |
|
| 759 return TCL_OK; |
|
| 760 } |
|
| 761 |
|
| 762 int tcl_cmd_conversation(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 763 { |
|
| 764 Tcl_Obj *list, *elem; |
|
| 765 const char *cmds[] = { "find", "handle", "list", "new", "write", "name", "title", "send", NULL }; |
|
| 766 enum { CMD_CONV_FIND, CMD_CONV_HANDLE, CMD_CONV_LIST, CMD_CONV_NEW, CMD_CONV_WRITE , CMD_CONV_NAME, CMD_CONV_TITLE, CMD_CONV_SEND } cmd; |
|
| 767 const char *styles[] = { "send", "recv", "system", NULL }; |
|
| 768 enum { CMD_CONV_WRITE_SEND, CMD_CONV_WRITE_RECV, CMD_CONV_WRITE_SYSTEM } style; |
|
| 769 const char *newopts[] = { "-chat", "-im" }; |
|
| 770 enum { CMD_CONV_NEW_CHAT, CMD_CONV_NEW_IM } newopt; |
|
| 771 PurpleConversation *convo; |
|
| 772 PurpleAccount *account; |
|
| 773 PurpleMessage *pmsg; |
|
| 774 gboolean is_chat = FALSE; |
|
| 775 GList *cur; |
|
| 776 char *opt, *from, *what; |
|
| 777 int error, argsused; |
|
| 778 |
|
| 779 if (objc < 2) { |
|
| 780 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 781 return TCL_ERROR; |
|
| 782 } |
|
| 783 |
|
| 784 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 785 return error; |
|
| 786 |
|
| 787 switch (cmd) { |
|
| 788 case CMD_CONV_FIND: |
|
| 789 if (objc != 4) { |
|
| 790 Tcl_WrongNumArgs(interp, 2, objv, "account name"); |
|
| 791 return TCL_ERROR; |
|
| 792 } |
|
| 793 account = NULL; |
|
| 794 if ((account = tcl_validate_account(objv[2], interp)) == NULL) |
|
| 795 return TCL_ERROR; |
|
| 796 convo = purple_conversations_find_with_account(Tcl_GetString(objv[3]), |
|
| 797 account); |
|
| 798 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo)); |
|
| 799 break; |
|
| 800 case CMD_CONV_HANDLE: |
|
| 801 if (objc != 2) { |
|
| 802 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 803 return TCL_ERROR; |
|
| 804 } |
|
| 805 Tcl_SetObjResult(interp, |
|
| 806 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 807 purple_conversations_get_handle())); |
|
| 808 break; |
|
| 809 case CMD_CONV_LIST: |
|
| 810 list = Tcl_NewListObj(0, NULL); |
|
| 811 for (cur = purple_conversations_get_all(); cur != NULL; cur = g_list_next(cur)) { |
|
| 812 elem = purple_tcl_ref_new(PurpleTclRefConversation, cur->data); |
|
| 813 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 814 } |
|
| 815 Tcl_SetObjResult(interp, list); |
|
| 816 break; |
|
| 817 case CMD_CONV_NEW: |
|
| 818 if (objc < 4) { |
|
| 819 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); |
|
| 820 return TCL_ERROR; |
|
| 821 } |
|
| 822 argsused = 2; |
|
| 823 is_chat = FALSE; |
|
| 824 while (argsused < objc) { |
|
| 825 opt = Tcl_GetString(objv[argsused]); |
|
| 826 if (*opt == '-') { |
|
| 827 if ((error = Tcl_GetIndexFromObj(interp, objv[argsused], newopts, |
|
| 828 "option", 0, (int *)&newopt)) != TCL_OK) |
|
| 829 return error; |
|
| 830 argsused++; |
|
| 831 switch (newopt) { |
|
| 832 case CMD_CONV_NEW_CHAT: |
|
| 833 is_chat = TRUE; |
|
| 834 break; |
|
| 835 case CMD_CONV_NEW_IM: |
|
| 836 is_chat = FALSE; |
|
| 837 break; |
|
| 838 } |
|
| 839 } else { |
|
| 840 break; |
|
| 841 } |
|
| 842 } |
|
| 843 if (objc - argsused != 2) { |
|
| 844 Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); |
|
| 845 return TCL_ERROR; |
|
| 846 } |
|
| 847 if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) |
|
| 848 return TCL_ERROR; |
|
| 849 if (is_chat) |
|
| 850 convo = PURPLE_CONVERSATION(purple_chat_conversation_new(account, Tcl_GetString(objv[argsused]))); |
|
| 851 else |
|
| 852 convo = PURPLE_CONVERSATION(purple_im_conversation_new(account, Tcl_GetString(objv[argsused]))); |
|
| 853 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefConversation, convo)); |
|
| 854 break; |
|
| 855 case CMD_CONV_WRITE: |
|
| 856 if (objc != 6) { |
|
| 857 Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); |
|
| 858 return TCL_ERROR; |
|
| 859 } |
|
| 860 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 861 return TCL_ERROR; |
|
| 862 if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) |
|
| 863 return error; |
|
| 864 from = Tcl_GetString(objv[4]); |
|
| 865 what = Tcl_GetString(objv[5]); |
|
| 866 |
|
| 867 switch (style) { |
|
| 868 case CMD_CONV_WRITE_SEND: |
|
| 869 pmsg = purple_message_new_outgoing(from, what, 0); |
|
| 870 break; |
|
| 871 case CMD_CONV_WRITE_RECV: |
|
| 872 pmsg = purple_message_new_incoming(from, what, 0, 0); |
|
| 873 break; |
|
| 874 case CMD_CONV_WRITE_SYSTEM: |
|
| 875 default: |
|
| 876 pmsg = purple_message_new_system(what, 0); |
|
| 877 break; |
|
| 878 } |
|
| 879 purple_conversation_write_message(convo, pmsg); |
|
| 880 break; |
|
| 881 case CMD_CONV_NAME: |
|
| 882 if (objc != 3) { |
|
| 883 Tcl_WrongNumArgs(interp, 2, objv, "conversation"); |
|
| 884 return TCL_ERROR; |
|
| 885 } |
|
| 886 |
|
| 887 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 888 return TCL_ERROR; |
|
| 889 Tcl_SetObjResult(interp, |
|
| 890 Tcl_NewStringObj((char *)purple_conversation_get_name(convo), -1)); |
|
| 891 break; |
|
| 892 case CMD_CONV_TITLE: |
|
| 893 if (objc != 3) { |
|
| 894 Tcl_WrongNumArgs(interp, 2, objv, "conversation"); |
|
| 895 return TCL_ERROR; |
|
| 896 } |
|
| 897 |
|
| 898 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 899 return TCL_ERROR; |
|
| 900 Tcl_SetObjResult(interp, |
|
| 901 Tcl_NewStringObj((char *)purple_conversation_get_title(convo), -1)); |
|
| 902 break; |
|
| 903 case CMD_CONV_SEND: |
|
| 904 if (objc != 4) { |
|
| 905 Tcl_WrongNumArgs(interp, 2, objv, "conversation message"); |
|
| 906 return TCL_ERROR; |
|
| 907 } |
|
| 908 if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) |
|
| 909 return TCL_ERROR; |
|
| 910 what = Tcl_GetString(objv[3]); |
|
| 911 purple_conversation_send(convo, what); |
|
| 912 break; |
|
| 913 } |
|
| 914 |
|
| 915 return TCL_OK; |
|
| 916 } |
|
| 917 |
|
| 918 int tcl_cmd_core(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 919 { |
|
| 920 const char *cmds[] = { "handle", "quit", NULL }; |
|
| 921 enum { CMD_CORE_HANDLE, CMD_CORE_QUIT } cmd; |
|
| 922 int error; |
|
| 923 |
|
| 924 if (objc < 2) { |
|
| 925 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 926 return TCL_ERROR; |
|
| 927 } |
|
| 928 |
|
| 929 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 930 return error; |
|
| 931 |
|
| 932 switch (cmd) { |
|
| 933 case CMD_CORE_HANDLE: |
|
| 934 if (objc != 2) { |
|
| 935 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 936 return TCL_ERROR; |
|
| 937 } |
|
| 938 Tcl_SetObjResult(interp, |
|
| 939 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 940 purple_get_core())); |
|
| 941 break; |
|
| 942 case CMD_CORE_QUIT: |
|
| 943 if (objc != 2) { |
|
| 944 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 945 return TCL_ERROR; |
|
| 946 } |
|
| 947 purple_core_quit(); |
|
| 948 break; |
|
| 949 } |
|
| 950 |
|
| 951 return TCL_OK; |
|
| 952 } |
|
| 953 |
|
| 954 int tcl_cmd_debug(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 955 { |
|
| 956 char *category, *message; |
|
| 957 int lev; |
|
| 958 const char *levels[] = { "-misc", "-info", "-warning", "-error", NULL }; |
|
| 959 PurpleDebugLevel levelind[] = { PURPLE_DEBUG_MISC, PURPLE_DEBUG_INFO, PURPLE_DEBUG_WARNING, PURPLE_DEBUG_ERROR }; |
|
| 960 int error; |
|
| 961 |
|
| 962 if (objc != 4) { |
|
| 963 Tcl_WrongNumArgs(interp, 1, objv, "level category message"); |
|
| 964 return TCL_ERROR; |
|
| 965 } |
|
| 966 |
|
| 967 error = Tcl_GetIndexFromObj(interp, objv[1], levels, "debug level", 0, &lev); |
|
| 968 if (error != TCL_OK) |
|
| 969 return error; |
|
| 970 |
|
| 971 category = Tcl_GetString(objv[2]); |
|
| 972 message = Tcl_GetString(objv[3]); |
|
| 973 |
|
| 974 purple_debug(levelind[lev], category, "%s\n", message); |
|
| 975 |
|
| 976 return TCL_OK; |
|
| 977 } |
|
| 978 |
|
| 979 int tcl_cmd_notify(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 980 { |
|
| 981 int error, type; |
|
| 982 const char *opts[] = { "-error", "-warning", "-info", NULL }; |
|
| 983 PurpleNotifyMsgType optind[] = { PURPLE_NOTIFY_MSG_ERROR, PURPLE_NOTIFY_MSG_WARNING, PURPLE_NOTIFY_MSG_INFO }; |
|
| 984 char *title, *msg1, *msg2; |
|
| 985 |
|
| 986 if (objc < 4 || objc > 5) { |
|
| 987 Tcl_WrongNumArgs(interp, 1, objv, "?type? title primary secondary"); |
|
| 988 return TCL_ERROR; |
|
| 989 } |
|
| 990 |
|
| 991 if (objc == 4) { |
|
| 992 type = 1; /* Default to warning */ |
|
| 993 title = Tcl_GetString(objv[1]); |
|
| 994 msg1 = Tcl_GetString(objv[2]); |
|
| 995 msg2 = Tcl_GetString(objv[3]); |
|
| 996 } else { |
|
| 997 error = Tcl_GetIndexFromObj(interp, objv[1], opts, "message type", 0, &type); |
|
| 998 if (error != TCL_OK) |
|
| 999 return error; |
|
| 1000 title = Tcl_GetString(objv[2]); |
|
| 1001 msg1 = Tcl_GetString(objv[3]); |
|
| 1002 msg2 = Tcl_GetString(objv[4]); |
|
| 1003 } |
|
| 1004 |
|
| 1005 purple_notify_message(_tcl_plugin, optind[type], title, msg1, msg2, NULL, NULL, NULL); |
|
| 1006 |
|
| 1007 return TCL_OK; |
|
| 1008 } |
|
| 1009 |
|
| 1010 int tcl_cmd_plugins(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1011 { |
|
| 1012 const char *cmds[] = { "handle", NULL }; |
|
| 1013 enum { CMD_PLUGINS_HANDLE } cmd; |
|
| 1014 int error; |
|
| 1015 |
|
| 1016 if (objc < 2) { |
|
| 1017 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1018 return TCL_ERROR; |
|
| 1019 } |
|
| 1020 |
|
| 1021 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1022 return error; |
|
| 1023 |
|
| 1024 switch (cmd) { |
|
| 1025 case CMD_PLUGINS_HANDLE: |
|
| 1026 if (objc != 2) { |
|
| 1027 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 1028 return TCL_ERROR; |
|
| 1029 } |
|
| 1030 Tcl_SetObjResult(interp, |
|
| 1031 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 1032 purple_plugins_get_handle())); |
|
| 1033 break; |
|
| 1034 } |
|
| 1035 |
|
| 1036 return TCL_OK; |
|
| 1037 } |
|
| 1038 |
|
| 1039 int tcl_cmd_prefs(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1040 { |
|
| 1041 Tcl_Obj *list, *elem, **elems; |
|
| 1042 const char *cmds[] = { "get", "set", "type", NULL }; |
|
| 1043 enum { CMD_PREFS_GET, CMD_PREFS_SET, CMD_PREFS_TYPE } cmd; |
|
| 1044 /* char *types[] = { "none", "boolean", "int", "string", "stringlist", NULL }; */ |
|
| 1045 /* enum { TCL_PREFS_NONE, TCL_PREFS_BOOL, TCL_PREFS_INT, TCL_PREFS_STRING, TCL_PREFS_STRINGLIST } type; */ |
|
| 1046 PurplePrefType preftype; |
|
| 1047 GList *cur; |
|
| 1048 int error, intval, nelem, i; |
|
| 1049 |
|
| 1050 if (objc < 2) { |
|
| 1051 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1052 return TCL_ERROR; |
|
| 1053 } |
|
| 1054 |
|
| 1055 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1056 return error; |
|
| 1057 |
|
| 1058 switch (cmd) { |
|
| 1059 case CMD_PREFS_GET: |
|
| 1060 if (objc != 3) { |
|
| 1061 Tcl_WrongNumArgs(interp, 1, objv, "path"); |
|
| 1062 return TCL_ERROR; |
|
| 1063 } |
|
| 1064 preftype = purple_prefs_get_pref_type(Tcl_GetString(objv[2])); |
|
| 1065 switch (preftype) { |
|
| 1066 case PURPLE_PREF_NONE: |
|
| 1067 Tcl_SetObjResult(interp, |
|
| 1068 Tcl_NewStringObj("pref type none", -1)); |
|
| 1069 return TCL_ERROR; |
|
| 1070 break; |
|
| 1071 case PURPLE_PREF_BOOLEAN: |
|
| 1072 Tcl_SetObjResult(interp, |
|
| 1073 Tcl_NewBooleanObj( |
|
| 1074 purple_prefs_get_bool(Tcl_GetString(objv[2])))); |
|
| 1075 break; |
|
| 1076 case PURPLE_PREF_INT: |
|
| 1077 Tcl_SetObjResult(interp, Tcl_NewIntObj(purple_prefs_get_int(Tcl_GetString(objv[2])))); |
|
| 1078 break; |
|
| 1079 case PURPLE_PREF_STRING: |
|
| 1080 Tcl_SetObjResult(interp, |
|
| 1081 Tcl_NewStringObj((char *)purple_prefs_get_string(Tcl_GetString(objv[2])), -1)); |
|
| 1082 break; |
|
| 1083 case PURPLE_PREF_STRING_LIST: |
|
| 1084 cur = purple_prefs_get_string_list(Tcl_GetString(objv[2])); |
|
| 1085 list = Tcl_NewListObj(0, NULL); |
|
| 1086 while (cur != NULL) { |
|
| 1087 elem = Tcl_NewStringObj((char *)cur->data, -1); |
|
| 1088 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 1089 cur = g_list_next(cur); |
|
| 1090 } |
|
| 1091 Tcl_SetObjResult(interp, list); |
|
| 1092 break; |
|
| 1093 default: |
|
| 1094 purple_debug(PURPLE_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); |
|
| 1095 Tcl_SetObjResult(interp, |
|
| 1096 Tcl_NewStringObj("unknown pref type", -1)); |
|
| 1097 return TCL_ERROR; |
|
| 1098 } |
|
| 1099 break; |
|
| 1100 case CMD_PREFS_SET: |
|
| 1101 if (objc != 4) { |
|
| 1102 Tcl_WrongNumArgs(interp, 1, objv, "path value"); |
|
| 1103 return TCL_ERROR; |
|
| 1104 } |
|
| 1105 preftype = purple_prefs_get_pref_type(Tcl_GetString(objv[2])); |
|
| 1106 switch (preftype) { |
|
| 1107 case PURPLE_PREF_NONE: |
|
| 1108 Tcl_SetObjResult(interp, |
|
| 1109 Tcl_NewStringObj("bad path or pref type none", -1)); |
|
| 1110 return TCL_ERROR; |
|
| 1111 break; |
|
| 1112 case PURPLE_PREF_BOOLEAN: |
|
| 1113 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &intval)) != TCL_OK) |
|
| 1114 return error; |
|
| 1115 purple_prefs_set_bool(Tcl_GetString(objv[2]), intval); |
|
| 1116 break; |
|
| 1117 case PURPLE_PREF_INT: |
|
| 1118 if ((error = Tcl_GetIntFromObj(interp, objv[3], &intval)) != TCL_OK) |
|
| 1119 return error; |
|
| 1120 purple_prefs_set_int(Tcl_GetString(objv[2]), intval); |
|
| 1121 break; |
|
| 1122 case PURPLE_PREF_STRING: |
|
| 1123 purple_prefs_set_string(Tcl_GetString(objv[2]), Tcl_GetString(objv[3])); |
|
| 1124 break; |
|
| 1125 case PURPLE_PREF_STRING_LIST: |
|
| 1126 if ((error = Tcl_ListObjGetElements(interp, objv[3], &nelem, &elems)) != TCL_OK) |
|
| 1127 return error; |
|
| 1128 cur = NULL; |
|
| 1129 for (i = 0; i < nelem; i++) { |
|
| 1130 cur = g_list_append(cur, (gpointer)Tcl_GetString(elems[i])); |
|
| 1131 } |
|
| 1132 purple_prefs_set_string_list(Tcl_GetString(objv[2]), cur); |
|
| 1133 g_list_free(cur); |
|
| 1134 break; |
|
| 1135 default: |
|
| 1136 purple_debug(PURPLE_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); |
|
| 1137 return TCL_ERROR; |
|
| 1138 } |
|
| 1139 break; |
|
| 1140 case CMD_PREFS_TYPE: |
|
| 1141 if (objc != 3) { |
|
| 1142 Tcl_WrongNumArgs(interp, 1, objv, "path"); |
|
| 1143 return TCL_ERROR; |
|
| 1144 } |
|
| 1145 preftype = purple_prefs_get_pref_type(Tcl_GetString(objv[2])); |
|
| 1146 switch (preftype) { |
|
| 1147 case PURPLE_PREF_NONE: |
|
| 1148 Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1)); |
|
| 1149 break; |
|
| 1150 case PURPLE_PREF_BOOLEAN: |
|
| 1151 Tcl_SetObjResult(interp, Tcl_NewStringObj("boolean", -1)); |
|
| 1152 break; |
|
| 1153 case PURPLE_PREF_INT: |
|
| 1154 Tcl_SetObjResult(interp, Tcl_NewStringObj("int", -1)); |
|
| 1155 break; |
|
| 1156 case PURPLE_PREF_STRING: |
|
| 1157 Tcl_SetObjResult(interp, Tcl_NewStringObj("string", -1)); |
|
| 1158 break; |
|
| 1159 case PURPLE_PREF_STRING_LIST: |
|
| 1160 Tcl_SetObjResult(interp, Tcl_NewStringObj("stringlist", -1)); |
|
| 1161 break; |
|
| 1162 default: |
|
| 1163 purple_debug(PURPLE_DEBUG_ERROR, "tcl", "tcl does not know about pref type %d\n", preftype); |
|
| 1164 Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown", -1)); |
|
| 1165 } |
|
| 1166 break; |
|
| 1167 } |
|
| 1168 |
|
| 1169 return TCL_OK; |
|
| 1170 } |
|
| 1171 |
|
| 1172 int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1173 { |
|
| 1174 const char *cmds[] = { "account", "active_status", "available", |
|
| 1175 "idle", "type", "login", "online", "status", |
|
| 1176 "statuses", NULL }; |
|
| 1177 enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS, |
|
| 1178 CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_IDLE, CMD_PRESENCE_TYPE, |
|
| 1179 CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE, |
|
| 1180 CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd; |
|
| 1181 Tcl_Obj *result; |
|
| 1182 Tcl_Obj *list, *elem; |
|
| 1183 PurplePresence *presence; |
|
| 1184 GList *cur; |
|
| 1185 int error, idle, idle_time, login_time; |
|
| 1186 |
|
| 1187 if (objc < 2) { |
|
| 1188 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1189 return TCL_ERROR; |
|
| 1190 } |
|
| 1191 |
|
| 1192 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1193 return error; |
|
| 1194 |
|
| 1195 switch (cmd) { |
|
| 1196 case CMD_PRESENCE_ACCOUNT: |
|
| 1197 if (objc != 3) { |
|
| 1198 Tcl_WrongNumArgs(interp, 2, objv, "presence"); |
|
| 1199 return TCL_ERROR; |
|
| 1200 } |
|
| 1201 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1202 return TCL_ERROR; |
|
| 1203 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefAccount, |
|
| 1204 purple_account_presence_get_account(PURPLE_ACCOUNT_PRESENCE(presence)))); |
|
| 1205 break; |
|
| 1206 case CMD_PRESENCE_ACTIVE_STATUS: |
|
| 1207 if (objc != 3 && objc != 4 && objc != 5) { |
|
| 1208 Tcl_WrongNumArgs(interp, 2, objv, "presence [?status_id? | ?-primitive primitive?]"); |
|
| 1209 return TCL_ERROR; |
|
| 1210 } |
|
| 1211 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1212 return TCL_ERROR; |
|
| 1213 if (objc == 3) { |
|
| 1214 Tcl_SetObjResult(interp, |
|
| 1215 purple_tcl_ref_new(PurpleTclRefStatus, |
|
| 1216 purple_presence_get_active_status(presence))); |
|
| 1217 } else if (objc == 4) { |
|
| 1218 Tcl_SetObjResult(interp, |
|
| 1219 Tcl_NewBooleanObj( |
|
| 1220 purple_presence_is_status_active(presence, |
|
| 1221 Tcl_GetString(objv[3])))); |
|
| 1222 } else { |
|
| 1223 PurpleStatusPrimitive primitive; |
|
| 1224 if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { |
|
| 1225 result = Tcl_NewStringObj("bad option \"", -1); |
|
| 1226 Tcl_AppendObjToObj(result, objv[3]); |
|
| 1227 Tcl_AppendToObj(result, |
|
| 1228 "\": should be -primitive", -1); |
|
| 1229 Tcl_SetObjResult(interp,result); |
|
| 1230 return TCL_ERROR; |
|
| 1231 } |
|
| 1232 primitive = purple_primitive_get_type_from_id(Tcl_GetString(objv[4])); |
|
| 1233 if (primitive == PURPLE_STATUS_UNSET) { |
|
| 1234 result = Tcl_NewStringObj("invalid primitive ", -1); |
|
| 1235 Tcl_AppendObjToObj(result, objv[4]); |
|
| 1236 Tcl_SetObjResult(interp,result); |
|
| 1237 return TCL_ERROR; |
|
| 1238 } |
|
| 1239 Tcl_SetObjResult(interp, |
|
| 1240 Tcl_NewBooleanObj( |
|
| 1241 purple_presence_is_status_primitive_active(presence, primitive))); |
|
| 1242 break; |
|
| 1243 } |
|
| 1244 break; |
|
| 1245 case CMD_PRESENCE_AVAILABLE: |
|
| 1246 if (objc != 3) { |
|
| 1247 Tcl_WrongNumArgs(interp, 2, objv, "presence"); |
|
| 1248 return TCL_ERROR; |
|
| 1249 } |
|
| 1250 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1251 return TCL_ERROR; |
|
| 1252 Tcl_SetObjResult(interp, |
|
| 1253 Tcl_NewBooleanObj(purple_presence_is_available(presence))); |
|
| 1254 break; |
|
| 1255 case CMD_PRESENCE_TYPE: |
|
| 1256 if (objc != 3) { |
|
| 1257 Tcl_WrongNumArgs(interp, 2, objv, "presence"); |
|
| 1258 return TCL_ERROR; |
|
| 1259 } |
|
| 1260 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1261 return TCL_ERROR; |
|
| 1262 if (PURPLE_IS_ACCOUNT_PRESENCE(presence)) |
|
| 1263 Tcl_SetObjResult(interp, Tcl_NewStringObj("account", -1)); |
|
| 1264 else if (PURPLE_IS_BUDDY_PRESENCE(presence)) |
|
| 1265 Tcl_SetObjResult(interp, Tcl_NewStringObj("buddy", -1)); |
|
| 1266 break; |
|
| 1267 case CMD_PRESENCE_IDLE: |
|
| 1268 if (objc < 3 || objc > 5) { |
|
| 1269 Tcl_WrongNumArgs(interp, 2, objv, "presence ?idle? ?time?"); |
|
| 1270 return TCL_ERROR; |
|
| 1271 } |
|
| 1272 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1273 return TCL_ERROR; |
|
| 1274 if (objc == 3) { |
|
| 1275 if (purple_presence_is_idle(presence)) { |
|
| 1276 idle_time = purple_presence_get_idle_time (presence); |
|
| 1277 Tcl_SetObjResult(interp, Tcl_NewIntObj(idle_time)); |
|
| 1278 } else { |
|
| 1279 result = Tcl_NewListObj(0, NULL); |
|
| 1280 Tcl_SetObjResult(interp, result); |
|
| 1281 } |
|
| 1282 break; |
|
| 1283 } |
|
| 1284 if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &idle)) != TCL_OK) |
|
| 1285 return TCL_ERROR; |
|
| 1286 if (objc == 4) { |
|
| 1287 purple_presence_set_idle(presence, idle, time(NULL)); |
|
| 1288 } else if (objc == 5) { |
|
| 1289 if ((error = Tcl_GetIntFromObj(interp, |
|
| 1290 objv[4], |
|
| 1291 &idle_time)) != TCL_OK) |
|
| 1292 return TCL_ERROR; |
|
| 1293 purple_presence_set_idle(presence, idle, idle_time); |
|
| 1294 } |
|
| 1295 break; |
|
| 1296 case CMD_PRESENCE_LOGIN: |
|
| 1297 if (objc != 3 && objc != 4) { |
|
| 1298 Tcl_WrongNumArgs(interp, 2, objv, "presence ?time?"); |
|
| 1299 return TCL_ERROR; |
|
| 1300 } |
|
| 1301 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1302 return TCL_ERROR; |
|
| 1303 if (objc == 3) { |
|
| 1304 Tcl_SetObjResult(interp, Tcl_NewIntObj(purple_presence_get_login_time(presence))); |
|
| 1305 } else { |
|
| 1306 if ((error == Tcl_GetIntFromObj(interp, |
|
| 1307 objv[3], |
|
| 1308 &login_time)) != TCL_OK) |
|
| 1309 return TCL_ERROR; |
|
| 1310 purple_presence_set_login_time(presence, login_time); |
|
| 1311 } |
|
| 1312 break; |
|
| 1313 case CMD_PRESENCE_ONLINE: |
|
| 1314 if (objc != 3) { |
|
| 1315 Tcl_WrongNumArgs(interp, 2, objv, "presence"); |
|
| 1316 return TCL_ERROR; |
|
| 1317 } |
|
| 1318 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1319 return TCL_ERROR; |
|
| 1320 Tcl_SetObjResult(interp, |
|
| 1321 Tcl_NewBooleanObj( |
|
| 1322 purple_presence_is_online(presence))); |
|
| 1323 break; |
|
| 1324 case CMD_PRESENCE_STATUS: |
|
| 1325 if (objc != 4) { |
|
| 1326 Tcl_WrongNumArgs(interp, 2, objv, "presence status_id"); |
|
| 1327 return TCL_ERROR; |
|
| 1328 } |
|
| 1329 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1330 return TCL_ERROR; |
|
| 1331 Tcl_SetObjResult(interp, |
|
| 1332 purple_tcl_ref_new(PurpleTclRefStatus, |
|
| 1333 purple_presence_get_status(presence, |
|
| 1334 Tcl_GetString(objv[3])))); |
|
| 1335 break; |
|
| 1336 case CMD_PRESENCE_STATUSES: |
|
| 1337 if (objc != 3) { |
|
| 1338 Tcl_WrongNumArgs(interp, 2, objv, "presence"); |
|
| 1339 return TCL_ERROR; |
|
| 1340 } |
|
| 1341 if ((presence = purple_tcl_ref_get(interp, objv[2], PurpleTclRefPresence)) == NULL) |
|
| 1342 return TCL_ERROR; |
|
| 1343 list = Tcl_NewListObj(0, NULL); |
|
| 1344 for (cur = purple_presence_get_statuses(presence); cur != NULL; |
|
| 1345 cur = g_list_next(cur)) { |
|
| 1346 elem = purple_tcl_ref_new(PurpleTclRefStatus, cur->data); |
|
| 1347 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 1348 } |
|
| 1349 Tcl_SetObjResult(interp, list); |
|
| 1350 break; |
|
| 1351 } |
|
| 1352 |
|
| 1353 return TCL_OK; |
|
| 1354 } |
|
| 1355 |
|
| 1356 int tcl_cmd_savedstatus(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1357 { |
|
| 1358 Tcl_Obj *result; |
|
| 1359 const char *cmds[] = { "current", "handle", NULL }; |
|
| 1360 enum { CMD_SAVEDSTATUS_CURRENT, CMD_SAVEDSTATUS_HANDLE } cmd; |
|
| 1361 int error; |
|
| 1362 PurpleSavedStatus *saved_status; |
|
| 1363 |
|
| 1364 if (objc < 2) { |
|
| 1365 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1366 return TCL_ERROR; |
|
| 1367 } |
|
| 1368 |
|
| 1369 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1370 return error; |
|
| 1371 |
|
| 1372 switch (cmd) { |
|
| 1373 case CMD_SAVEDSTATUS_CURRENT: |
|
| 1374 if (objc != 2) { |
|
| 1375 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 1376 return TCL_ERROR; |
|
| 1377 } |
|
| 1378 if ((saved_status = purple_savedstatus_get_current()) == NULL) |
|
| 1379 return TCL_ERROR; |
|
| 1380 result = Tcl_NewListObj(0, NULL); |
|
| 1381 Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(purple_savedstatus_get_title(saved_status), -1)); |
|
| 1382 Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(purple_savedstatus_get_primitive_type(saved_status))); |
|
| 1383 Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(purple_savedstatus_get_message(saved_status), -1)); |
|
| 1384 Tcl_SetObjResult(interp,result); |
|
| 1385 break; |
|
| 1386 case CMD_SAVEDSTATUS_HANDLE: |
|
| 1387 if (objc != 2) { |
|
| 1388 Tcl_WrongNumArgs(interp, 2, objv, ""); |
|
| 1389 return TCL_ERROR; |
|
| 1390 } |
|
| 1391 Tcl_SetObjResult(interp, |
|
| 1392 purple_tcl_ref_new(PurpleTclRefHandle, |
|
| 1393 purple_savedstatuses_get_handle())); |
|
| 1394 break; |
|
| 1395 } |
|
| 1396 |
|
| 1397 return TCL_OK; |
|
| 1398 } |
|
| 1399 |
|
| 1400 int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1401 { |
|
| 1402 PurpleConnection *gc; |
|
| 1403 char *who, *text; |
|
| 1404 |
|
| 1405 if (objc != 4) { |
|
| 1406 Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); |
|
| 1407 return TCL_ERROR; |
|
| 1408 } |
|
| 1409 |
|
| 1410 if ((gc = tcl_validate_gc(objv[1], interp)) == NULL) |
|
| 1411 return TCL_ERROR; |
|
| 1412 |
|
| 1413 who = Tcl_GetString(objv[2]); |
|
| 1414 text = Tcl_GetString(objv[3]); |
|
| 1415 |
|
| 1416 purple_serv_send_im(gc, purple_message_new_outgoing(who, text, 0)); |
|
| 1417 |
|
| 1418 return TCL_OK; |
|
| 1419 } |
|
| 1420 |
|
| 1421 int tcl_cmd_signal(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1422 { |
|
| 1423 const char *cmds[] = { "connect", "disconnect", NULL }; |
|
| 1424 enum { CMD_SIGNAL_CONNECT, CMD_SIGNAL_DISCONNECT } cmd; |
|
| 1425 struct tcl_signal_handler *handler; |
|
| 1426 void *instance; |
|
| 1427 int error; |
|
| 1428 |
|
| 1429 if (objc < 2) { |
|
| 1430 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1431 return TCL_ERROR; |
|
| 1432 } |
|
| 1433 |
|
| 1434 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1435 return error; |
|
| 1436 |
|
| 1437 switch (cmd) { |
|
| 1438 case CMD_SIGNAL_CONNECT: |
|
| 1439 if (objc != 6) { |
|
| 1440 Tcl_WrongNumArgs(interp, 2, objv, "instance signal args proc"); |
|
| 1441 return TCL_ERROR; |
|
| 1442 } |
|
| 1443 handler = g_new0(struct tcl_signal_handler, 1); |
|
| 1444 if ((handler->instance = purple_tcl_ref_get(interp, objv[2],PurpleTclRefHandle)) == NULL) { |
|
| 1445 g_free(handler); |
|
| 1446 return error; |
|
| 1447 } |
|
| 1448 handler->signal = objv[3]; |
|
| 1449 Tcl_IncrRefCount(handler->signal); |
|
| 1450 handler->args = objv[4]; |
|
| 1451 handler->proc = objv[5]; |
|
| 1452 handler->interp = interp; |
|
| 1453 if (!tcl_signal_connect(handler)) { |
|
| 1454 tcl_signal_handler_free(handler); |
|
| 1455 Tcl_SetObjResult(interp, Tcl_NewIntObj(1)); |
|
| 1456 } else { |
|
| 1457 Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); |
|
| 1458 } |
|
| 1459 break; |
|
| 1460 case CMD_SIGNAL_DISCONNECT: |
|
| 1461 if (objc != 4) { |
|
| 1462 Tcl_WrongNumArgs(interp, 2, objv, "instance signal"); |
|
| 1463 return TCL_ERROR; |
|
| 1464 } |
|
| 1465 if ((instance = purple_tcl_ref_get(interp, objv[2],PurpleTclRefHandle)) == NULL) |
|
| 1466 return error; |
|
| 1467 tcl_signal_disconnect(instance, Tcl_GetString(objv[3]), interp); |
|
| 1468 break; |
|
| 1469 } |
|
| 1470 |
|
| 1471 return TCL_OK; |
|
| 1472 } |
|
| 1473 |
|
| 1474 int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1475 { |
|
| 1476 const char *cmds[] = { "attr", "type", NULL }; |
|
| 1477 enum { CMD_STATUS_ATTRIBUTE, CMD_STATUS_TYPE } cmd; |
|
| 1478 PurpleStatus *status; |
|
| 1479 PurpleStatusType *status_type; |
|
| 1480 int error; |
|
| 1481 # if (0) |
|
| 1482 /* #if !(defined PURPLE_DISABLE_DEPRECATED) */ |
|
| 1483 PurpleValue *value; |
|
| 1484 const char *attr; |
|
| 1485 int v; |
|
| 1486 #endif |
|
| 1487 |
|
| 1488 if (objc < 2) { |
|
| 1489 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1490 return TCL_ERROR; |
|
| 1491 } |
|
| 1492 |
|
| 1493 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1494 return error; |
|
| 1495 |
|
| 1496 switch (cmd) { |
|
| 1497 case CMD_STATUS_ATTRIBUTE: |
|
| 1498 # if (0) |
|
| 1499 /* #if !(defined PURPLE_DISABLE_DEPRECATED) */ |
|
| 1500 if (objc != 4 && objc != 5) { |
|
| 1501 Tcl_WrongNumArgs(interp, 2, objv, "status attr_id ?value?"); |
|
| 1502 return TCL_ERROR; |
|
| 1503 } |
|
| 1504 if ((status = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatus)) == NULL) |
|
| 1505 return TCL_ERROR; |
|
| 1506 attr = Tcl_GetString(objv[3]); |
|
| 1507 value = purple_status_get_attr_value(status, attr); |
|
| 1508 if (value == NULL) { |
|
| 1509 Tcl_SetObjResult(interp, |
|
| 1510 Tcl_NewStringObj("no such attribute", -1)); |
|
| 1511 return TCL_ERROR; |
|
| 1512 } |
|
| 1513 switch (purple_value_get_type(value)) { |
|
| 1514 case PURPLE_TYPE_BOOLEAN: |
|
| 1515 if (objc == 4) { |
|
| 1516 Tcl_SetObjResult(interp, |
|
| 1517 Tcl_NewBooleanObj(purple_value_get_boolean(value))); |
|
| 1518 } else { |
|
| 1519 if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK) |
|
| 1520 return error; |
|
| 1521 purple_status_set_attr_boolean(status, attr, v); |
|
| 1522 } |
|
| 1523 break; |
|
| 1524 case PURPLE_TYPE_INT: |
|
| 1525 if (objc == 4) { |
|
| 1526 Tcl_SetObjResult(interp, Tcl_NewIntObj(purple_value_get_int(value))); |
|
| 1527 } else { |
|
| 1528 if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK) |
|
| 1529 return error; |
|
| 1530 purple_status_set_attr_int(status, attr, v ); |
|
| 1531 } |
|
| 1532 break; |
|
| 1533 case PURPLE_TYPE_STRING: |
|
| 1534 if (objc == 4) |
|
| 1535 Tcl_SetObjResult(interp, |
|
| 1536 Tcl_NewStringObj(purple_value_get_string(value), -1)); |
|
| 1537 else |
|
| 1538 purple_status_set_attr_string(status, attr, Tcl_GetString(objv[4])); |
|
| 1539 break; |
|
| 1540 default: |
|
| 1541 Tcl_SetObjResult(interp, |
|
| 1542 Tcl_NewStringObj("attribute has unknown type", -1)); |
|
| 1543 return TCL_ERROR; |
|
| 1544 } |
|
| 1545 #endif |
|
| 1546 break; |
|
| 1547 case CMD_STATUS_TYPE: |
|
| 1548 if (objc != 3) { |
|
| 1549 Tcl_WrongNumArgs(interp, 2, objv, "status"); |
|
| 1550 return TCL_ERROR; |
|
| 1551 } |
|
| 1552 if ((status = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatus)) == NULL) |
|
| 1553 return TCL_ERROR; |
|
| 1554 status_type = purple_status_get_status_type(status); |
|
| 1555 Tcl_SetObjResult(interp, purple_tcl_ref_new(PurpleTclRefStatusType, |
|
| 1556 status_type)); |
|
| 1557 break; |
|
| 1558 } |
|
| 1559 |
|
| 1560 return TCL_OK; |
|
| 1561 } |
|
| 1562 |
|
| 1563 int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1564 { |
|
| 1565 const char *cmds[] = { "id", "name", NULL }; |
|
| 1566 enum { CMD_STATUS_ATTRIBUTE_ID, CMD_STATUS_ATTRIBUTE_NAME } cmd; |
|
| 1567 PurpleStatusAttribute *attr; |
|
| 1568 int error; |
|
| 1569 |
|
| 1570 if (objc < 2) { |
|
| 1571 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1572 return TCL_ERROR; |
|
| 1573 } |
|
| 1574 |
|
| 1575 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1576 return error; |
|
| 1577 |
|
| 1578 switch (cmd) { |
|
| 1579 case CMD_STATUS_ATTRIBUTE_ID: |
|
| 1580 if (objc != 3) { |
|
| 1581 Tcl_WrongNumArgs(interp, 2, objv, "attr"); |
|
| 1582 return TCL_ERROR; |
|
| 1583 } |
|
| 1584 if ((attr = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusAttr)) == NULL) |
|
| 1585 return TCL_ERROR; |
|
| 1586 Tcl_SetObjResult(interp, |
|
| 1587 Tcl_NewStringObj(purple_status_attribute_get_id(attr), -1)); |
|
| 1588 break; |
|
| 1589 case CMD_STATUS_ATTRIBUTE_NAME: |
|
| 1590 if (objc != 3) { |
|
| 1591 Tcl_WrongNumArgs(interp, 2, objv, "attr"); |
|
| 1592 return TCL_ERROR; |
|
| 1593 } |
|
| 1594 if ((attr = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusAttr)) == NULL) |
|
| 1595 return TCL_ERROR; |
|
| 1596 Tcl_SetObjResult(interp, |
|
| 1597 Tcl_NewStringObj(purple_status_attribute_get_name(attr), -1)); |
|
| 1598 break; |
|
| 1599 } |
|
| 1600 |
|
| 1601 return TCL_OK; |
|
| 1602 } |
|
| 1603 |
|
| 1604 int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1605 { |
|
| 1606 const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", |
|
| 1607 "independent", "name", |
|
| 1608 "primitive", "saveable", "user_settable", |
|
| 1609 NULL }; |
|
| 1610 enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, |
|
| 1611 CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, |
|
| 1612 CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, |
|
| 1613 CMD_STATUS_TYPE_NAME, |
|
| 1614 CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, |
|
| 1615 CMD_STATUS_TYPE_USER_SETTABLE } cmd; |
|
| 1616 PurpleStatusType *status_type; |
|
| 1617 Tcl_Obj *list, *elem; |
|
| 1618 GList *cur; |
|
| 1619 int error; |
|
| 1620 |
|
| 1621 if (objc < 2) { |
|
| 1622 Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); |
|
| 1623 return TCL_ERROR; |
|
| 1624 } |
|
| 1625 |
|
| 1626 if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) |
|
| 1627 return error; |
|
| 1628 |
|
| 1629 switch (cmd) { |
|
| 1630 case CMD_STATUS_TYPE_AVAILABLE: |
|
| 1631 if (objc != 3) { |
|
| 1632 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1633 return TCL_ERROR; |
|
| 1634 } |
|
| 1635 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1636 return TCL_ERROR; |
|
| 1637 Tcl_SetObjResult(interp, |
|
| 1638 Tcl_NewBooleanObj(purple_status_type_is_available(status_type))); |
|
| 1639 break; |
|
| 1640 case CMD_STATUS_TYPE_ATTR: |
|
| 1641 if (objc != 4) { |
|
| 1642 Tcl_WrongNumArgs(interp, 2, objv, "statustype attr"); |
|
| 1643 return TCL_ERROR; |
|
| 1644 } |
|
| 1645 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1646 return TCL_ERROR; |
|
| 1647 Tcl_SetObjResult(interp, |
|
| 1648 purple_tcl_ref_new(PurpleTclRefStatusAttr, |
|
| 1649 purple_status_type_get_attr(status_type, |
|
| 1650 Tcl_GetStringFromObj(objv[3], NULL)))); |
|
| 1651 break; |
|
| 1652 case CMD_STATUS_TYPE_ATTRS: |
|
| 1653 if (objc != 3) { |
|
| 1654 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1655 return TCL_ERROR; |
|
| 1656 } |
|
| 1657 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1658 return TCL_ERROR; |
|
| 1659 list = Tcl_NewListObj(0, NULL); |
|
| 1660 for (cur = purple_status_type_get_attrs(status_type); |
|
| 1661 cur != NULL; cur = g_list_next(cur)) { |
|
| 1662 elem = purple_tcl_ref_new(PurpleTclRefStatusAttr, cur->data); |
|
| 1663 Tcl_ListObjAppendElement(interp, list, elem); |
|
| 1664 } |
|
| 1665 Tcl_SetObjResult(interp, list); |
|
| 1666 break; |
|
| 1667 case CMD_STATUS_TYPE_EXCLUSIVE: |
|
| 1668 if (objc != 3) { |
|
| 1669 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1670 return TCL_ERROR; |
|
| 1671 } |
|
| 1672 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1673 return TCL_ERROR; |
|
| 1674 Tcl_SetObjResult(interp, |
|
| 1675 Tcl_NewBooleanObj(purple_status_type_is_exclusive(status_type))); |
|
| 1676 break; |
|
| 1677 case CMD_STATUS_TYPE_ID: |
|
| 1678 if (objc != 3) { |
|
| 1679 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1680 return TCL_ERROR; |
|
| 1681 } |
|
| 1682 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1683 return TCL_ERROR; |
|
| 1684 Tcl_SetObjResult(interp, |
|
| 1685 Tcl_NewStringObj(purple_status_type_get_id(status_type), -1)); |
|
| 1686 break; |
|
| 1687 case CMD_STATUS_TYPE_INDEPENDENT: |
|
| 1688 if (objc != 3) { |
|
| 1689 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1690 return TCL_ERROR; |
|
| 1691 } |
|
| 1692 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1693 return TCL_ERROR; |
|
| 1694 Tcl_SetObjResult(interp, |
|
| 1695 Tcl_NewBooleanObj(purple_status_type_is_independent(status_type))); |
|
| 1696 break; |
|
| 1697 case CMD_STATUS_TYPE_NAME: |
|
| 1698 if (objc != 3) { |
|
| 1699 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1700 return TCL_ERROR; |
|
| 1701 } |
|
| 1702 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1703 return TCL_ERROR; |
|
| 1704 Tcl_SetObjResult(interp, |
|
| 1705 Tcl_NewStringObj(purple_status_type_get_name(status_type), -1)); |
|
| 1706 break; |
|
| 1707 case CMD_STATUS_TYPE_PRIMITIVE: |
|
| 1708 if (objc != 3) { |
|
| 1709 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1710 return TCL_ERROR; |
|
| 1711 } |
|
| 1712 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1713 return TCL_ERROR; |
|
| 1714 Tcl_SetObjResult(interp, |
|
| 1715 Tcl_NewStringObj(purple_primitive_get_id_from_type |
|
| 1716 (purple_status_type_get_primitive(status_type)), -1)); |
|
| 1717 break; |
|
| 1718 case CMD_STATUS_TYPE_SAVEABLE: |
|
| 1719 if (objc != 3) { |
|
| 1720 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1721 return TCL_ERROR; |
|
| 1722 } |
|
| 1723 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1724 return TCL_ERROR; |
|
| 1725 Tcl_SetObjResult(interp, |
|
| 1726 Tcl_NewBooleanObj( |
|
| 1727 purple_status_type_is_saveable(status_type))); |
|
| 1728 break; |
|
| 1729 case CMD_STATUS_TYPE_USER_SETTABLE: |
|
| 1730 if (objc != 3) { |
|
| 1731 Tcl_WrongNumArgs(interp, 2, objv, "statustype"); |
|
| 1732 return TCL_ERROR; |
|
| 1733 } |
|
| 1734 if ((status_type = purple_tcl_ref_get(interp, objv[2], PurpleTclRefStatusType)) == NULL) |
|
| 1735 return TCL_ERROR; |
|
| 1736 Tcl_SetObjResult(interp, |
|
| 1737 Tcl_NewBooleanObj( |
|
| 1738 purple_status_type_is_user_settable(status_type))); |
|
| 1739 break; |
|
| 1740 } |
|
| 1741 |
|
| 1742 return TCL_OK; |
|
| 1743 } |
|
| 1744 |
|
| 1745 static gboolean unload_self(gpointer data) |
|
| 1746 { |
|
| 1747 PurplePlugin *plugin = data; |
|
| 1748 purple_plugin_unload(plugin); |
|
| 1749 return FALSE; |
|
| 1750 } |
|
| 1751 |
|
| 1752 int tcl_cmd_unload(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) |
|
| 1753 { |
|
| 1754 PurplePlugin *plugin; |
|
| 1755 if (objc != 1) { |
|
| 1756 Tcl_WrongNumArgs(interp, 1, objv, ""); |
|
| 1757 return TCL_ERROR; |
|
| 1758 } |
|
| 1759 |
|
| 1760 if ((plugin = tcl_interp_get_plugin(interp)) == NULL) { |
|
| 1761 /* This isn't exactly OK, but heh. What do you do? */ |
|
| 1762 return TCL_OK; |
|
| 1763 } |
|
| 1764 /* We can't unload immediately, but we can unload at the first |
|
| 1765 * known safe opportunity. */ |
|
| 1766 purple_timeout_add(0, unload_self, (gpointer)plugin); |
|
| 1767 |
|
| 1768 return TCL_OK; |
|
| 1769 } |
|