From: <ebl...@us...> - 2006-06-10 18:01:18
|
Revision: 16240 Author: eblanton Date: 2006-06-10 11:01:11 -0700 (Sat, 10 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16240&view=rev Log Message: ----------- This is not a completed update, but it has useful bits and bug fixes and the completed update will take some more time. This adds support for some of the status API to Tcl, as well as improving the handling of several of the pointer types (by introducing a gaim reference object type and appropriate string roundtrip functions) and introducing some "type safety". Modified Paths: -------------- trunk/plugins/tcl/Makefile.am trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_cmds.c trunk/plugins/tcl/tcl_gaim.h trunk/plugins/tcl/tcl_signals.c Modified: trunk/plugins/tcl/Makefile.am =================================================================== --- trunk/plugins/tcl/Makefile.am 2006-06-10 17:45:31 UTC (rev 16239) +++ trunk/plugins/tcl/Makefile.am 2006-06-10 18:01:11 UTC (rev 16240) @@ -4,7 +4,8 @@ plugin_LTLIBRARIES = tcl.la -tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h +tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \ + tcl_ref.c EXTRA_DIST = signal-test.tcl Makefile.mingw Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-10 17:45:31 UTC (rev 16239) +++ trunk/plugins/tcl/tcl.c 2006-06-10 18:01:11 UTC (rev 16240) @@ -50,6 +50,12 @@ Tcl_Interp *interp; }; +GaimStringref *GaimTclRefAccount; +GaimStringref *GaimTclRefConversation; +GaimStringref *GaimTclRefStatus; +GaimStringref *GaimTclRefStatusAttr; +GaimStringref *GaimTclRefStatusType; + static GHashTable *tcl_plugins = NULL; GaimPlugin *_tcl_plugin; @@ -125,6 +131,9 @@ Tcl_CreateObjCommand(interp, "::gaim::prefs", tcl_cmd_prefs, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status_type, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_type, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_type", tcl_cmd_status_type, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::unload", tcl_cmd_unload, (ClientData)NULL, NULL); return 0; @@ -329,6 +338,14 @@ return FALSE; tcl_glib_init(); tcl_signal_init(); + gaim_tcl_ref_init(); + + GaimTclRefAccount = gaim_stringref_new("Account"); + GaimTclRefConversation = gaim_stringref_new("Conversation"); + GaimTclRefStatus = gaim_stringref_new("Status"); + GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); + GaimTclRefStatusType = gaim_stringref_new("StatusType"); + tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal); #ifdef HAVE_TK @@ -343,6 +360,12 @@ g_hash_table_destroy(tcl_plugins); tcl_plugins = NULL; + gaim_stringref_unref(GaimTclRefAccount); + gaim_stringref_unref(GaimTclRefConversation); + gaim_stringref_unref(GaimTclRefStatus); + gaim_stringref_unref(GaimTclRefStatusAttr); + gaim_stringref_unref(GaimTclRefStatusType); + return TRUE; } Modified: trunk/plugins/tcl/tcl_cmds.c =================================================================== --- trunk/plugins/tcl/tcl_cmds.c 2006-06-10 17:45:31 UTC (rev 16239) +++ trunk/plugins/tcl/tcl_cmds.c 2006-06-10 18:01:11 UTC (rev 16240) @@ -35,33 +35,46 @@ #include "tcl_gaim.h" -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp); -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp); +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); static gboolean tcl_validate_gc(GaimConnection *gc); -static gboolean tcl_validate_account(GaimAccount *account, Tcl_Interp *interp) +static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimAccount *account; GList *cur; + + account = gaim_tcl_ref_get(interp, obj, GaimTclRefAccount); + + if (account == NULL) + return NULL; + for (cur = gaim_accounts_get_all(); cur != NULL; cur = g_list_next(cur)) { if (account == cur->data) - return TRUE; + return account; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } -static gboolean tcl_validate_conversation(GaimConversation *convo, Tcl_Interp *interp) +static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConversation *convo; GList *cur; + convo = gaim_tcl_ref_get(interp, obj, GaimTclRefConversation); + + if (convo == NULL) + return NULL; + for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { if (convo == cur->data) - return TRUE; + return convo; } if (interp != NULL) Tcl_SetStringObj(Tcl_GetObjResult(interp), "invalid account", -1); - return FALSE; + return NULL; } static gboolean tcl_validate_gc(GaimConnection *gc) @@ -77,19 +90,24 @@ int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; - const char *cmds[] = { "alias", "connect", "connection", "disconnect", "find", - "handle", "isconnected", "list", - "protocol", "username", NULL }; - enum { CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, - CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, - CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, - CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_USERNAME } cmd; + const char *cmds[] = { "active_status", "alias", "connect", + "connection", "disconnect", "enabled", "find", + "handle", "isconnected", "list", "protocol", + "status_type", "status_types", "username", NULL }; + enum { CMD_ACCOUNT_ACTIVE_STATUS, CMD_ACCOUNT_ALIAS, + CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, + CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, + CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, + CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS_TYPE, + CMD_ACCOUNT_STATUS_TYPES, CMD_ACCOUNT_USERNAME } cmd; const char *listopts[] = { "-all", "-online", NULL }; enum { CMD_ACCOUNTLIST_ALL, CMD_ACCOUNTLIST_ONLINE } listopt; const char *alias; - GList *cur; + const GList *cur; GaimAccount *account; + GaimStatusType *status_type; int error; + int b; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); @@ -100,13 +118,23 @@ return error; switch (cmd) { + case CMD_ACCOUNT_ACTIVE_STATUS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_account_get_active_status(account))); + break; case CMD_ACCOUNT_ALIAS: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; alias = gaim_account_get_alias(account); Tcl_SetStringObj(result, alias ? (char *)alias : "", -1); @@ -116,8 +144,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; if (!gaim_account_is_connected(account)) gaim_account_connect(account); @@ -128,8 +155,8 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); break; @@ -138,11 +165,27 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; gaim_account_disconnect(account); break; + case CMD_ACCOUNT_ENABLED: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?enabled?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetBooleanObj(result, + gaim_account_get_enabled(account, + gaim_core_get_ui())); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &b)) != TCL_OK) + return TCL_ERROR; + gaim_account_set_enabled(account, gaim_core_get_ui(), b); + } + break; case CMD_ACCOUNT_FIND: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); @@ -163,8 +206,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetBooleanObj(result, gaim_account_is_connected(account)); break; @@ -183,7 +225,7 @@ account = cur->data; if (listopt == CMD_ACCOUNTLIST_ONLINE && !gaim_account_is_connected(account)) continue; - elem = Tcl_NewIntObj((int)account); + elem = gaim_tcl_ref_new(GaimTclRefAccount, account); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -193,18 +235,63 @@ Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_protocol_id(account), -1); break; + case CMD_ACCOUNT_STATUS_TYPE: + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "account ?statustype? ?-primitive primitive?"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + if (objc == 4) { + status_type = gaim_account_get_status_type(account, + Tcl_GetString(objv[3])); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + status_type = gaim_account_get_status_type_with_primitive(account, + primitive); + } + if (status_type == NULL) { + Tcl_SetStringObj(result, "status type not found", -1); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + case CMD_ACCOUNT_STATUS_TYPES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_account_get_status_types(account); cur != NULL; + cur = g_list_next(cur)) { + Tcl_ListObjAppendElement(interp, list, + gaim_tcl_ref_new(GaimTclRefStatusType, + cur->data)); + } + Tcl_SetObjResult(interp, list); + break; case CMD_ACCOUNT_USERNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account); - if (error || !tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; Tcl_SetStringObj(result, (char *)gaim_account_get_username(account), -1); break; @@ -227,10 +314,8 @@ type = Tcl_GetString(elems[0]); name = Tcl_GetString(elems[1]); - if (Tcl_GetIntFromObj(interp, elems[2], (int *)&account) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return NULL; - if (!tcl_validate_account(account, interp)) - return NULL; if (!strcmp(type, "buddy")) { node = (GaimBlistNode *)gaim_find_buddy(account, name); @@ -301,15 +386,11 @@ Tcl_SetStringObj(result, "invalid buddy", -1); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, elems[2], (int *)&account)) != TCL_OK) + if ((account = tcl_validate_account(elems[2], interp)) == NULL) return TCL_ERROR; - if (!tcl_validate_account(account, interp)) - return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(elems[1])); } else { - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; serv_get_info(gaim_account_get_connection(account), Tcl_GetString(objv[3])); } @@ -351,7 +432,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("buddy", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(bud->name, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)bud->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, bud->account)); Tcl_ListObjAppendElement(interp, tclcontactlist, tclbud); } if (count) { @@ -368,7 +449,7 @@ tclbud = Tcl_NewListObj(0, NULL); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj("chat", -1)); Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewStringObj(cnode->alias, -1)); - Tcl_ListObjAppendElement(interp, tclbud, Tcl_NewIntObj((int)cnode->account)); + Tcl_ListObjAppendElement(interp, tclbud, gaim_tcl_ref_new(GaimTclRefAccount, cnode->account)); Tcl_ListObjAppendElement(interp, tclgrouplist, tclbud); break; default: @@ -483,10 +564,7 @@ return TCL_ERROR; } account = NULL; - if ((error = Tcl_GetIntFromObj(interp, objv[2], - (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, Tcl_GetString(objv[3]), @@ -538,9 +616,7 @@ Tcl_WrongNumArgs(interp, 2, objv, "?options? account name"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[argsused++], (int *)&account)) != TCL_OK) - return error; - if (!tcl_validate_account(account, interp)) + if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) return TCL_ERROR; convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); Tcl_SetIntObj(result, (int)convo); @@ -550,12 +626,10 @@ Tcl_WrongNumArgs(interp, 2, objv, "conversation style from what"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&convo)) != TCL_OK) - return error; + if ((convo = tcl_validate_conversation(objv[2], interp)) == NULL) + return TCL_ERROR; if ((error = Tcl_GetIndexFromObj(interp, objv[3], styles, "style", 0, (int *)&style)) != TCL_OK) return error; - if (!tcl_validate_conversation(convo, interp)) - return TCL_ERROR; from = Tcl_GetString(objv[4]); what = Tcl_GetString(objv[5]); @@ -856,6 +930,7 @@ return error; } handler->signal = objv[3]; + Tcl_IncrRefCount(handler->signal); handler->args = objv[4]; handler->proc = objv[5]; handler->interp = interp; @@ -868,7 +943,7 @@ break; case CMD_SIGNAL_DISCONNECT: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "signal"); + Tcl_WrongNumArgs(interp, 2, objv, "instance signal"); return TCL_ERROR; } if ((error = Tcl_GetIntFromObj(interp, objv[2], (int *)&instance)) != TCL_OK) @@ -880,6 +955,248 @@ return TCL_OK; } +int tcl_cmd_status(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "type" }; + enum { CMD_STATUS_ATTR, CMD_STATUS_TYPE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatus *status; + GaimStatusType *status_type; + GaimValue *value; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "status attr_id"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + value = gaim_status_get_attr_value(status, Tcl_GetString(objv[3])); + if (value == NULL) { + Tcl_SetStringObj(result, "no such attribute", -1); + return TCL_ERROR; + } + switch (gaim_value_get_type(value)) { + case GAIM_TYPE_BOOLEAN: + Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); + break; + case GAIM_TYPE_INT: + Tcl_SetIntObj(result, gaim_value_get_int(value)); + break; + case GAIM_TYPE_STRING: + Tcl_SetStringObj(result, gaim_value_get_string(value), -1); + break; + default: + Tcl_SetStringObj(result, "attribute has unknown type", -1); + return TCL_ERROR; + } + break; + case CMD_STATUS_TYPE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "status"); + return TCL_ERROR; + } + if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) + return TCL_ERROR; + status_type = gaim_status_get_type(status); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefStatusType, + status_type)); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_attr(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "id", "name", NULL }; + enum { CMD_STATUS_ATTR_ID, CMD_STATUS_ATTR_NAME } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusAttr *attr; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_ATTR_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_id(attr), -1); + break; + case CMD_STATUS_ATTR_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "attr"); + return TCL_ERROR; + } + if ((attr = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusAttr)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_attr_get_name(attr), -1); + break; + } + + return TCL_OK; +} + +int tcl_cmd_status_type(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "attr", "attrs", "available", "exclusive", "id", + "independent", "name", "primary_attr", + "primitive", "saveable", "user_settable", + NULL }; + enum { CMD_STATUS_TYPE_ATTR, CMD_STATUS_TYPE_ATTRS, + CMD_STATUS_TYPE_AVAILABLE, CMD_STATUS_TYPE_EXCLUSIVE, + CMD_STATUS_TYPE_ID, CMD_STATUS_TYPE_INDEPENDENT, + CMD_STATUS_TYPE_NAME, CMD_STATUS_TYPE_PRIMARY_ATTR, + CMD_STATUS_TYPE_PRIMITIVE, CMD_STATUS_TYPE_SAVEABLE, + CMD_STATUS_TYPE_USER_SETTABLE } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimStatusType *status_type; + Tcl_Obj *list, *elem; + const GList *cur; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_STATUS_TYPE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_available(status_type)); + break; + case CMD_STATUS_TYPE_ATTR: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype attr"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatusAttr, + gaim_status_type_get_attr(status_type, + Tcl_GetStringFromObj(objv[3], NULL)))); + break; + case CMD_STATUS_TYPE_ATTRS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_status_type_get_attrs(status_type); + cur != NULL; cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatusAttr, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + case CMD_STATUS_TYPE_EXCLUSIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_exclusive(status_type)); + break; + case CMD_STATUS_TYPE_ID: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_id(status_type), -1); + break; + case CMD_STATUS_TYPE_INDEPENDENT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_independent(status_type)); + break; + case CMD_STATUS_TYPE_NAME: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_name(status_type), -1); + break; + case CMD_STATUS_TYPE_PRIMITIVE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_primitive_get_id_from_type(gaim_status_type_get_primitive(status_type)), -1); + break; + case CMD_STATUS_TYPE_PRIMARY_ATTR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_status_type_get_primary_attr(status_type), -1); + break; + case CMD_STATUS_TYPE_SAVEABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_saveable(status_type)); + break; + case CMD_STATUS_TYPE_USER_SETTABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "statustype"); + return TCL_ERROR; + } + if ((status_type = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatusType)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_status_type_is_user_settable(status_type)); + break; + } + + return TCL_OK; +} + static gboolean unload_self(gpointer data) { GaimPlugin *plugin = data; Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-10 17:45:31 UTC (rev 16239) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-10 18:01:11 UTC (rev 16240) @@ -28,6 +28,7 @@ #include "internal.h" #include "plugin.h" #include "value.h" +#include "stringref.h" struct tcl_signal_handler { Tcl_Obj *signal; @@ -46,6 +47,13 @@ extern GaimPlugin *_tcl_plugin; +/* Capitalized this way because these are "types" */ +extern GaimStringref *GaimTclRefAccount; +extern GaimStringref *GaimTclRefConversation; +extern GaimStringref *GaimTclRefStatus; +extern GaimStringref *GaimTclRefStatusAttr; +extern GaimStringref *GaimTclRefStatusType; + GaimPlugin *tcl_interp_get_plugin(Tcl_Interp *interp); void tcl_signal_init(void); @@ -54,6 +62,10 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); +void gaim_tcl_ref_init(); +void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); +Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); + Tcl_ObjCmdProc tcl_cmd_account; Tcl_ObjCmdProc tcl_cmd_signal_connect; Tcl_ObjCmdProc tcl_cmd_buddy; @@ -65,6 +77,9 @@ Tcl_ObjCmdProc tcl_cmd_prefs; Tcl_ObjCmdProc tcl_cmd_send_im; Tcl_ObjCmdProc tcl_cmd_signal; +Tcl_ObjCmdProc tcl_cmd_status; +Tcl_ObjCmdProc tcl_cmd_status_attr; +Tcl_ObjCmdProc tcl_cmd_status_type; Tcl_ObjCmdProc tcl_cmd_unload; #endif /* _GAIM_TCL_GAIM_H_ */ Modified: trunk/plugins/tcl/tcl_signals.c =================================================================== --- trunk/plugins/tcl/tcl_signals.c 2006-06-10 17:45:31 UTC (rev 16239) +++ trunk/plugins/tcl/tcl_signals.c 2006-06-10 18:01:11 UTC (rev 16240) @@ -48,7 +48,8 @@ return; Tcl_DecrRefCount(handler->signal); - Tcl_DecrRefCount(handler->namespace); + if (handler->namespace) + Tcl_DecrRefCount(handler->namespace); g_free(handler); } @@ -86,7 +87,6 @@ (void *)handler)) return FALSE; - Tcl_IncrRefCount(handler->signal); handler->namespace = new_cb_namespace (); Tcl_IncrRefCount(handler->namespace); proc = g_string_new(""); @@ -256,8 +256,12 @@ case GAIM_SUBTYPE_UNKNOWN: gaim_debug(GAIM_DEBUG_ERROR, "tcl", "subtype unknown\n"); case GAIM_SUBTYPE_ACCOUNT: + case GAIM_SUBTYPE_CONVERSATION: + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(GaimTclRefAccount, va_arg(args, void *)); + break; case GAIM_SUBTYPE_CONNECTION: - case GAIM_SUBTYPE_CONVERSATION: case GAIM_SUBTYPE_PLUGIN: case GAIM_SUBTYPE_XFER: /* pointers again */ @@ -281,24 +285,40 @@ node = va_arg(args, GaimBlistNode *); switch (node->type) { case GAIM_BLIST_GROUP_NODE: - g_string_printf(val, "group {%s}", ((GaimGroup *)node)->name); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("group", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimGroup *)node)->name, -1)); break; case GAIM_BLIST_CONTACT_NODE: /* g_string_printf(val, "contact {%s}", Contact Name? ); */ + arg = Tcl_NewStringObj("contact", -1); break; case GAIM_BLIST_BUDDY_NODE: - g_string_printf(val, "buddy {%s} %lu", ((GaimBuddy *)node)->name, - (unsigned long)((GaimBuddy *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("buddy", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimBuddy *)node)->name, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimBuddy *)node)->account)); break; case GAIM_BLIST_CHAT_NODE: - g_string_printf(val, "chat {%s} %lu", ((GaimChat *)node)->alias, - (unsigned long)((GaimChat *)node)->account); + arg = Tcl_NewListObj(0, NULL); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj("chat", -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + Tcl_NewStringObj(((GaimChat *)node)->alias, -1)); + Tcl_ListObjAppendElement(handler->interp, arg, + gaim_tcl_ref_new(GaimTclRefAccount, + ((GaimChat *)node)->account)); break; case GAIM_BLIST_OTHER_NODE: - g_string_printf(val, "other"); + arg = Tcl_NewStringObj("other", -1); break; } - arg = Tcl_NewStringObj(val->str, -1); break; } } @@ -329,8 +349,10 @@ for (i = 0; i < handler->nargs; i++) { g_string_printf(name, "%s::arg%d", Tcl_GetString(handler->namespace), i); - if (gaim_value_is_outgoing(handler->argtypes[i])) + if (gaim_value_is_outgoing(handler->argtypes[i]) + && gaim_value_get_type(handler->argtypes[i]) != GAIM_TYPE_SUBTYPE) Tcl_UnlinkVar(handler->interp, name->str); + /* We basically only have to deal with strings on the * way out */ switch (gaim_value_get_type(handler->argtypes[i])) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-06-10 19:17:05
|
Revision: 16247 Author: eblanton Date: 2006-06-10 12:16:58 -0700 (Sat, 10 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16247&view=rev Log Message: ----------- This cleans up a few missed account and conversation cases, and moves GaimConnections to the typed pointer references. Modified Paths: -------------- trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_cmds.c trunk/plugins/tcl/tcl_gaim.h trunk/plugins/tcl/tcl_signals.c Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-10 19:04:04 UTC (rev 16246) +++ trunk/plugins/tcl/tcl.c 2006-06-10 19:16:58 UTC (rev 16247) @@ -51,6 +51,7 @@ }; GaimStringref *GaimTclRefAccount; +GaimStringref *GaimTclRefConnection; GaimStringref *GaimTclRefConversation; GaimStringref *GaimTclRefStatus; GaimStringref *GaimTclRefStatusAttr; @@ -341,6 +342,7 @@ gaim_tcl_ref_init(); GaimTclRefAccount = gaim_stringref_new("Account"); + GaimTclRefConnection = gaim_stringref_new("Connection"); GaimTclRefConversation = gaim_stringref_new("Conversation"); GaimTclRefStatus = gaim_stringref_new("Status"); GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); @@ -361,6 +363,7 @@ tcl_plugins = NULL; gaim_stringref_unref(GaimTclRefAccount); + gaim_stringref_unref(GaimTclRefConnection); gaim_stringref_unref(GaimTclRefConversation); gaim_stringref_unref(GaimTclRefStatus); gaim_stringref_unref(GaimTclRefStatusAttr); Modified: trunk/plugins/tcl/tcl_cmds.c =================================================================== --- trunk/plugins/tcl/tcl_cmds.c 2006-06-10 19:04:04 UTC (rev 16246) +++ trunk/plugins/tcl/tcl_cmds.c 2006-06-10 19:16:58 UTC (rev 16247) @@ -37,7 +37,7 @@ static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp); static GaimConversation *tcl_validate_conversation(Tcl_Obj *obj, Tcl_Interp *interp); -static gboolean tcl_validate_gc(GaimConnection *gc); +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp); static GaimAccount *tcl_validate_account(Tcl_Obj *obj, Tcl_Interp *interp) { @@ -77,14 +77,21 @@ return NULL; } -static gboolean tcl_validate_gc(GaimConnection *gc) +static GaimConnection *tcl_validate_gc(Tcl_Obj *obj, Tcl_Interp *interp) { + GaimConnection *gc; GList *cur; + + gc = gaim_tcl_ref_get(interp, obj, GaimTclRefConnection); + + if (gc == NULL) + return NULL; + for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { if (gc == cur->data) - return TRUE; + return gc; } - return FALSE; + return NULL; } int tcl_cmd_account(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) @@ -148,7 +155,9 @@ return TCL_ERROR; if (!gaim_account_is_connected(account)) gaim_account_connect(account); - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_CONNECTION: if (objc != 3) { @@ -158,7 +167,9 @@ if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; - Tcl_SetIntObj(result, (int)gaim_account_get_connection(account)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefConnection, + gaim_account_get_connection(account))); break; case CMD_ACCOUNT_DISCONNECT: if (objc != 3) { @@ -191,8 +202,10 @@ Tcl_WrongNumArgs(interp, 2, objv, "username protocol"); return TCL_ERROR; } - Tcl_SetIntObj(result, (int)gaim_accounts_find(Tcl_GetString(objv[2]), - Tcl_GetString(objv[3]))); + account = gaim_accounts_find(Tcl_GetString(objv[2]), + Tcl_GetString(objv[3])); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, account)); break; case CMD_ACCOUNT_HANDLE: if (objc != 2) { @@ -490,23 +503,19 @@ Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } - Tcl_SetIntObj(result, (int)gaim_connection_get_account(gc)); + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefAccount, + gaim_connection_get_account(gc))); break; case CMD_CONN_DISPLAYNAME: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "gc"); return TCL_ERROR; } - error = Tcl_GetIntFromObj(interp, objv[2], (int *)&gc); - if (error || !tcl_validate_gc(gc)) { - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[2], interp)) == NULL) return TCL_ERROR; - } Tcl_SetStringObj(result, (char *)gaim_connection_get_display_name(gc), -1); break; case CMD_CONN_HANDLE: @@ -523,7 +532,7 @@ } list = Tcl_NewListObj(0, NULL); for (cur = gaim_connections_get_all(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConnection, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -569,7 +578,7 @@ convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_ANY, Tcl_GetString(objv[3]), account); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_HANDLE: if (objc != 2) { @@ -581,7 +590,7 @@ case CMD_CONV_LIST: list = Tcl_NewListObj(0, NULL); for (cur = gaim_get_conversations(); cur != NULL; cur = g_list_next(cur)) { - elem = Tcl_NewIntObj((int)cur->data); + elem = gaim_tcl_ref_new(GaimTclRefConversation, cur->data); Tcl_ListObjAppendElement(interp, list, elem); } Tcl_SetObjResult(interp, list); @@ -619,7 +628,7 @@ if ((account = tcl_validate_account(objv[argsused++], interp)) == NULL) return TCL_ERROR; convo = gaim_conversation_new(type, account, Tcl_GetString(objv[argsused])); - Tcl_SetIntObj(result, (int)convo); + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, convo)); break; case CMD_CONV_WRITE: if (objc != 6) { @@ -877,21 +886,14 @@ { GaimConnection *gc; char *who, *text; - int error; - Tcl_Obj *result; if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, "gc who text"); return TCL_ERROR; } - if ((error = Tcl_GetIntFromObj(interp, objv[1], (int *)&gc)) != TCL_OK) - return error; - if (!tcl_validate_gc(gc)) { - result = Tcl_GetObjResult(interp); - Tcl_SetStringObj(result, "invalid gc", -1); + if ((gc = tcl_validate_gc(objv[1], interp)) == NULL) return TCL_ERROR; - } who = Tcl_GetString(objv[2]); text = Tcl_GetString(objv[3]); Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-10 19:04:04 UTC (rev 16246) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-10 19:16:58 UTC (rev 16247) @@ -49,6 +49,7 @@ /* Capitalized this way because these are "types" */ extern GaimStringref *GaimTclRefAccount; +extern GaimStringref *GaimTclRefConnection; extern GaimStringref *GaimTclRefConversation; extern GaimStringref *GaimTclRefStatus; extern GaimStringref *GaimTclRefStatusAttr; Modified: trunk/plugins/tcl/tcl_signals.c =================================================================== --- trunk/plugins/tcl/tcl_signals.c 2006-06-10 19:04:04 UTC (rev 16246) +++ trunk/plugins/tcl/tcl_signals.c 2006-06-10 19:16:58 UTC (rev 16247) @@ -134,6 +134,22 @@ tcl_callbacks = g_list_remove_all(tcl_callbacks, NULL); } +static GaimStringref *ref_type(GaimSubType type) +{ + switch (type) { + case GAIM_SUBTYPE_ACCOUNT: + return GaimTclRefAccount; + case GAIM_SUBTYPE_CONNECTION: + return GaimTclRefConnection; + case GAIM_SUBTYPE_CONVERSATION: + return GaimTclRefConversation; + case GAIM_SUBTYPE_STATUS: + return GaimTclRefStatus; + default: + return NULL; + } +} + static void *tcl_signal_callback(va_list args, struct tcl_signal_handler *handler) { GString *name, *val; @@ -256,12 +272,13 @@ case GAIM_SUBTYPE_UNKNOWN: gaim_debug(GAIM_DEBUG_ERROR, "tcl", "subtype unknown\n"); case GAIM_SUBTYPE_ACCOUNT: + case GAIM_SUBTYPE_CONNECTION: case GAIM_SUBTYPE_CONVERSATION: + case GAIM_SUBTYPE_STATUS: if (gaim_value_is_outgoing(handler->argtypes[i])) gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n"); - arg = gaim_tcl_ref_new(GaimTclRefAccount, va_arg(args, void *)); + arg = gaim_tcl_ref_new(ref_type(gaim_value_get_subtype(handler->argtypes[i])), va_arg(args, void *)); break; - case GAIM_SUBTYPE_CONNECTION: case GAIM_SUBTYPE_PLUGIN: case GAIM_SUBTYPE_XFER: /* pointers again */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-06-10 19:51:38
|
Revision: 16249 Author: eblanton Date: 2006-06-10 12:51:32 -0700 (Sat, 10 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16249&view=rev Log Message: ----------- This has no functional effect, but it should eliminate some compiler crying. Modified Paths: -------------- trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_gaim.h trunk/plugins/tcl/tcl_signals.c Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-10 19:27:21 UTC (rev 16248) +++ trunk/plugins/tcl/tcl.c 2006-06-10 19:51:32 UTC (rev 16249) @@ -53,6 +53,7 @@ GaimStringref *GaimTclRefAccount; GaimStringref *GaimTclRefConnection; GaimStringref *GaimTclRefConversation; +GaimStringref *GaimTclRefPointer; GaimStringref *GaimTclRefStatus; GaimStringref *GaimTclRefStatusAttr; GaimStringref *GaimTclRefStatusType; @@ -344,6 +345,7 @@ GaimTclRefAccount = gaim_stringref_new("Account"); GaimTclRefConnection = gaim_stringref_new("Connection"); GaimTclRefConversation = gaim_stringref_new("Conversation"); + GaimTclRefPointer = gaim_stringref_new("Pointer"); GaimTclRefStatus = gaim_stringref_new("Status"); GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); GaimTclRefStatusType = gaim_stringref_new("StatusType"); @@ -365,6 +367,7 @@ gaim_stringref_unref(GaimTclRefAccount); gaim_stringref_unref(GaimTclRefConnection); gaim_stringref_unref(GaimTclRefConversation); + gaim_stringref_unref(GaimTclRefPointer); gaim_stringref_unref(GaimTclRefStatus); gaim_stringref_unref(GaimTclRefStatusAttr); gaim_stringref_unref(GaimTclRefStatusType); Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-10 19:27:21 UTC (rev 16248) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-10 19:51:32 UTC (rev 16249) @@ -51,6 +51,7 @@ extern GaimStringref *GaimTclRefAccount; extern GaimStringref *GaimTclRefConnection; extern GaimStringref *GaimTclRefConversation; +extern GaimStringref *GaimTclRefPointer; extern GaimStringref *GaimTclRefStatus; extern GaimStringref *GaimTclRefStatusAttr; extern GaimStringref *GaimTclRefStatusType; Modified: trunk/plugins/tcl/tcl_signals.c =================================================================== --- trunk/plugins/tcl/tcl_signals.c 2006-06-10 19:27:21 UTC (rev 16248) +++ trunk/plugins/tcl/tcl_signals.c 2006-06-10 19:51:32 UTC (rev 16249) @@ -186,14 +186,9 @@ case GAIM_TYPE_OBJECT: case GAIM_TYPE_BOXED: /* These are all "pointer" types to us */ - if (gaim_value_is_outgoing(handler->argtypes[i])) { - vals[i] = va_arg(args, void **); - Tcl_LinkVar(handler->interp, name->str, - vals[i], TCL_LINK_INT); - arg = Tcl_NewStringObj(name->str, -1); - } else { - arg = Tcl_NewIntObj((int)va_arg(args, void *)); - } + if (gaim_value_is_outgoing(handler->argtypes[i])) + gaim_debug_error("tcl", "pointer types do not currently support outgoing arguments\n"); + arg = gaim_tcl_ref_new(GaimTclRefPointer, va_arg(args, void *)); break; case GAIM_TYPE_BOOLEAN: if (gaim_value_is_outgoing(handler->argtypes[i])) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-06-11 06:05:18
|
Revision: 16254 Author: eblanton Date: 2006-06-10 23:05:09 -0700 (Sat, 10 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16254&view=rev Log Message: ----------- Work proceeds apace on the Tcl status API, this time with GaimPresence Modified Paths: -------------- trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_cmds.c trunk/plugins/tcl/tcl_gaim.h Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-11 00:42:41 UTC (rev 16253) +++ trunk/plugins/tcl/tcl.c 2006-06-11 06:05:09 UTC (rev 16254) @@ -54,6 +54,7 @@ GaimStringref *GaimTclRefConnection; GaimStringref *GaimTclRefConversation; GaimStringref *GaimTclRefPointer; +GaimStringref *GaimTclRefPresence; GaimStringref *GaimTclRefStatus; GaimStringref *GaimTclRefStatusAttr; GaimStringref *GaimTclRefStatusType; @@ -131,6 +132,7 @@ Tcl_CreateObjCommand(interp, "::gaim::debug", tcl_cmd_debug, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::notify", tcl_cmd_notify, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::prefs", tcl_cmd_prefs, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::presence", tcl_cmd_presence, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status_type, (ClientData)NULL, NULL); @@ -346,6 +348,7 @@ GaimTclRefConnection = gaim_stringref_new("Connection"); GaimTclRefConversation = gaim_stringref_new("Conversation"); GaimTclRefPointer = gaim_stringref_new("Pointer"); + GaimTclRefPresence = gaim_stringref_new("Presence"); GaimTclRefStatus = gaim_stringref_new("Status"); GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); GaimTclRefStatusType = gaim_stringref_new("StatusType"); @@ -368,6 +371,7 @@ gaim_stringref_unref(GaimTclRefConnection); gaim_stringref_unref(GaimTclRefConversation); gaim_stringref_unref(GaimTclRefPointer); + gaim_stringref_unref(GaimTclRefPresence); gaim_stringref_unref(GaimTclRefStatus); gaim_stringref_unref(GaimTclRefStatusAttr); gaim_stringref_unref(GaimTclRefStatusType); Modified: trunk/plugins/tcl/tcl_cmds.c =================================================================== --- trunk/plugins/tcl/tcl_cmds.c 2006-06-11 00:42:41 UTC (rev 16253) +++ trunk/plugins/tcl/tcl_cmds.c 2006-06-11 06:05:09 UTC (rev 16254) @@ -99,12 +99,14 @@ Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; const char *cmds[] = { "active_status", "alias", "connect", "connection", "disconnect", "enabled", "find", - "handle", "isconnected", "list", "protocol", - "status_type", "status_types", "username", NULL }; + "handle", "isconnected", "list", "presence", + "protocol", "status_type", "status_types", + "username", NULL }; enum { CMD_ACCOUNT_ACTIVE_STATUS, CMD_ACCOUNT_ALIAS, CMD_ACCOUNT_CONNECT, CMD_ACCOUNT_CONNECTION, CMD_ACCOUNT_DISCONNECT, CMD_ACCOUNT_ENABLED, CMD_ACCOUNT_FIND, CMD_ACCOUNT_HANDLE, CMD_ACCOUNT_ISCONNECTED, CMD_ACCOUNT_LIST, + CMD_ACCOUNT_PRESENCE, CMD_ACCOUNT_PROTOCOL, CMD_ACCOUNT_STATUS_TYPE, CMD_ACCOUNT_STATUS_TYPES, CMD_ACCOUNT_USERNAME } cmd; const char *listopts[] = { "-all", "-online", NULL }; @@ -243,6 +245,16 @@ } Tcl_SetObjResult(interp, list); break; + case CMD_ACCOUNT_PRESENCE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "account"); + return TCL_ERROR; + } + if ((account = tcl_validate_account(objv[2], interp)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(result, gaim_tcl_ref_new(GaimTclRefPresence, + gaim_account_get_presence(account))); + break; case CMD_ACCOUNT_PROTOCOL: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "account"); @@ -882,6 +894,212 @@ return TCL_OK; } +int tcl_cmd_presence(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "account", "active_status", "available", + "chat_user", "context", "conversation", "idle", + "login", "online", "status", "statuses", NULL }; + enum { CMD_PRESENCE_ACCOUNT, CMD_PRESENCE_ACTIVE_STATUS, + CMD_PRESENCE_AVAILABLE, CMD_PRESENCE_CHAT_USER, + CMD_PRESENCE_CONTEXT, CMD_PRESENCE_CONVERSATION, + CMD_PRESENCE_IDLE, CMD_PRESENCE_LOGIN, CMD_PRESENCE_ONLINE, + CMD_PRESENCE_STATUS, CMD_PRESENCE_STATUSES } cmd; + Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *list, *elem; + GaimPresence *presence; + const GList *cur; + int error, idle, idle_time, login_time; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_PRESENCE_ACCOUNT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefAccount, + gaim_presence_get_account(presence))); + break; + case CMD_PRESENCE_ACTIVE_STATUS: + if (objc != 3 && objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence [?status_id? | ?-primitive primitive?]"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_active_status(presence))); + } else if (objc == 4) { + Tcl_SetBooleanObj(result, + gaim_presence_is_status_active(presence, + Tcl_GetString(objv[3]))); + } else { + GaimStatusPrimitive primitive; + if (strcmp(Tcl_GetString(objv[3]), "-primitive")) { + Tcl_SetStringObj(result, "bad option \"", -1); + Tcl_AppendObjToObj(result, objv[3]); + Tcl_AppendToObj(result, + "\": should be -primitive", -1); + return TCL_ERROR; + } + primitive = gaim_primitive_get_type_from_id(Tcl_GetString(objv[4])); + if (primitive == GAIM_STATUS_UNSET) { + Tcl_SetStringObj(result, "invalid primitive ", -1); + Tcl_AppendObjToObj(result, objv[4]); + return TCL_ERROR; + } + Tcl_SetBooleanObj(result, gaim_presence_is_status_primitive_active(presence, primitive)); + break; + } + break; + case CMD_PRESENCE_AVAILABLE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_available(presence)); + break; + case CMD_PRESENCE_CHAT_USER: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetStringObj(result, gaim_presence_get_chat_user(presence), -1); + break; + case CMD_PRESENCE_CONTEXT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + switch (gaim_presence_get_context(presence)) { + case GAIM_PRESENCE_CONTEXT_UNSET: + Tcl_SetStringObj(result, "unset", -1); + break; + case GAIM_PRESENCE_CONTEXT_ACCOUNT: + Tcl_SetStringObj(result, "account", -1); + break; + case GAIM_PRESENCE_CONTEXT_CONV: + Tcl_SetStringObj(result, "conversation", -1); + break; + case GAIM_PRESENCE_CONTEXT_BUDDY: + Tcl_SetStringObj(result, "buddy", -1); + break; + } + break; + case CMD_PRESENCE_CONVERSATION: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefConversation, + gaim_presence_get_conversation(presence))); + break; + case CMD_PRESENCE_IDLE: + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?idle? ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + if (gaim_presence_is_idle(presence)) { + idle_time = gaim_presence_get_idle_time (presence); + Tcl_SetIntObj(result, idle_time); + } else { + result = Tcl_NewListObj(0, NULL); + Tcl_SetObjResult(interp, result); + } + break; + } + if ((error = Tcl_GetBooleanFromObj(interp, objv[3], &idle)) != TCL_OK) + return TCL_ERROR; + if (objc == 4) { + gaim_presence_set_idle(presence, idle, time(NULL)); + } else if (objc == 5) { + if ((error = Tcl_GetIntFromObj(interp, + objv[4], + &idle_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_idle(presence, idle, idle_time); + } + break; + case CMD_PRESENCE_LOGIN: + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence ?time?"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + if (objc == 3) { + Tcl_SetIntObj(result, gaim_presence_get_login_time(presence)); + } else { + if ((error == Tcl_GetIntFromObj(interp, + objv[3], + &login_time)) != TCL_OK) + return TCL_ERROR; + gaim_presence_set_login_time(presence, login_time); + } + break; + case CMD_PRESENCE_ONLINE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetBooleanObj(result, gaim_presence_is_online(presence)); + break; + case CMD_PRESENCE_STATUS: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "presence status_id"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + Tcl_SetObjResult(interp, + gaim_tcl_ref_new(GaimTclRefStatus, + gaim_presence_get_status(presence, + Tcl_GetString(objv[3])))); + break; + case CMD_PRESENCE_STATUSES: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "presence"); + return TCL_ERROR; + } + if ((presence = gaim_tcl_ref_get(interp, objv[2], GaimTclRefPresence)) == NULL) + return TCL_ERROR; + list = Tcl_NewListObj(0, NULL); + for (cur = gaim_presence_get_statuses(presence); cur != NULL; + cur = g_list_next(cur)) { + elem = gaim_tcl_ref_new(GaimTclRefStatus, cur->data); + Tcl_ListObjAppendElement(interp, list, elem); + } + Tcl_SetObjResult(interp, list); + break; + } + + return TCL_OK; +} + int tcl_cmd_send_im(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { GaimConnection *gc; Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-11 00:42:41 UTC (rev 16253) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-11 06:05:09 UTC (rev 16254) @@ -52,6 +52,7 @@ extern GaimStringref *GaimTclRefConnection; extern GaimStringref *GaimTclRefConversation; extern GaimStringref *GaimTclRefPointer; +extern GaimStringref *GaimTclRefPresence; extern GaimStringref *GaimTclRefStatus; extern GaimStringref *GaimTclRefStatusAttr; extern GaimStringref *GaimTclRefStatusType; @@ -77,6 +78,7 @@ Tcl_ObjCmdProc tcl_cmd_debug; Tcl_ObjCmdProc tcl_cmd_notify; Tcl_ObjCmdProc tcl_cmd_prefs; +Tcl_ObjCmdProc tcl_cmd_presence; Tcl_ObjCmdProc tcl_cmd_send_im; Tcl_ObjCmdProc tcl_cmd_signal; Tcl_ObjCmdProc tcl_cmd_status; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-06-16 03:42:41
|
Revision: 16268 Author: eblanton Date: 2006-06-15 20:42:34 -0700 (Thu, 15 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16268&view=rev Log Message: ----------- Shut up a useless warning, fix a return bug, and allow setting of status attrs Modified Paths: -------------- trunk/plugins/tcl/tcl_cmds.c trunk/plugins/tcl/tcl_gaim.h Modified: trunk/plugins/tcl/tcl_cmds.c =================================================================== --- trunk/plugins/tcl/tcl_cmds.c 2006-06-16 03:24:46 UTC (rev 16267) +++ trunk/plugins/tcl/tcl_cmds.c 2006-06-16 03:42:34 UTC (rev 16268) @@ -252,7 +252,7 @@ } if ((account = tcl_validate_account(objv[2], interp)) == NULL) return TCL_ERROR; - Tcl_SetObjResult(result, gaim_tcl_ref_new(GaimTclRefPresence, + Tcl_SetObjResult(interp, gaim_tcl_ref_new(GaimTclRefPresence, gaim_account_get_presence(account))); break; case CMD_ACCOUNT_PROTOCOL: @@ -1183,7 +1183,8 @@ GaimStatus *status; GaimStatusType *status_type; GaimValue *value; - int error; + const char *attr; + int error, v; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); @@ -1195,26 +1196,42 @@ switch (cmd) { case CMD_STATUS_ATTR: - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "status attr_id"); + if (objc != 4 && objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "status attr_id ?value?"); return TCL_ERROR; } if ((status = gaim_tcl_ref_get(interp, objv[2], GaimTclRefStatus)) == NULL) return TCL_ERROR; - value = gaim_status_get_attr_value(status, Tcl_GetString(objv[3])); + attr = Tcl_GetString(objv[3]); + value = gaim_status_get_attr_value(status, attr); if (value == NULL) { Tcl_SetStringObj(result, "no such attribute", -1); return TCL_ERROR; } switch (gaim_value_get_type(value)) { case GAIM_TYPE_BOOLEAN: - Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); + if (objc == 4) { + Tcl_SetBooleanObj(result, gaim_value_get_boolean(value)); + } else { + if ((error = Tcl_GetBooleanFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_boolean(status, attr, v); + } break; case GAIM_TYPE_INT: - Tcl_SetIntObj(result, gaim_value_get_int(value)); + if (objc == 4) { + Tcl_SetIntObj(result, gaim_value_get_int(value)); + } else { + if ((error = Tcl_GetIntFromObj(interp, objv[4], &v)) != TCL_OK) + return error; + gaim_status_set_attr_int(status, attr, v ); + } break; case GAIM_TYPE_STRING: - Tcl_SetStringObj(result, gaim_value_get_string(value), -1); + if (objc == 4) + Tcl_SetStringObj(result, gaim_value_get_string(value), -1); + else + gaim_status_set_attr_string(status, attr, Tcl_GetString(objv[4])); break; default: Tcl_SetStringObj(result, "attribute has unknown type", -1); Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-16 03:24:46 UTC (rev 16267) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-16 03:42:34 UTC (rev 16268) @@ -65,7 +65,7 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); -void gaim_tcl_ref_init(); +void gaim_tcl_ref_init(void); void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-06-16 03:49:20
|
Revision: 16269 Author: eblanton Date: 2006-06-15 20:49:14 -0700 (Thu, 15 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16269&view=rev Log Message: ----------- Fix some spacing bugs and a stupid copy-and-paste error Modified Paths: -------------- trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_ref.c Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-16 03:42:34 UTC (rev 16268) +++ trunk/plugins/tcl/tcl.c 2006-06-16 03:49:14 UTC (rev 16269) @@ -135,8 +135,8 @@ Tcl_CreateObjCommand(interp, "::gaim::presence", tcl_cmd_presence, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::send_im", tcl_cmd_send_im, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::signal", tcl_cmd_signal, (ClientData)NULL, NULL); - Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status_type, (ClientData)NULL, NULL); - Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_type, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status", tcl_cmd_status, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::status_attr", tcl_cmd_status_attr, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::status_type", tcl_cmd_status_type, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::unload", tcl_cmd_unload, (ClientData)NULL, NULL); Modified: trunk/plugins/tcl/tcl_ref.c =================================================================== --- trunk/plugins/tcl/tcl_ref.c 2006-06-16 03:42:34 UTC (rev 16268) +++ trunk/plugins/tcl/tcl_ref.c 2006-06-16 03:49:14 UTC (rev 16269) @@ -60,7 +60,7 @@ if (interp) { Tcl_Obj *error = Tcl_NewStringObj("Bad Gaim reference type: expected ", -1); Tcl_AppendToObj(error, gaim_stringref_value(type), -1); - Tcl_AppendToObj(error, "but got ", -1); + Tcl_AppendToObj(error, " but got ", -1); Tcl_AppendToObj(error, gaim_stringref_value(OBJ_REF_TYPE(obj)), -1); Tcl_SetObjResult(interp, error); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <de...@us...> - 2006-06-21 04:58:19
|
Revision: 16301 Author: deryni9 Date: 2006-06-20 21:57:27 -0700 (Tue, 20 Jun 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16301&view=rev Log Message: ----------- This is tcl /cmd support. It doesn't currently let tcl plugins return error message (I couldn't ever get that to work). But other than that it works. Ethan please look over this when you get a chance. Modified Paths: -------------- trunk/plugins/tcl/Makefile.am trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_cmds.c trunk/plugins/tcl/tcl_gaim.h trunk/plugins/tcl/tcl_signals.c Added Paths: ----------- trunk/plugins/tcl/tcl_cmd.c Modified: trunk/plugins/tcl/Makefile.am =================================================================== --- trunk/plugins/tcl/Makefile.am 2006-06-21 04:10:47 UTC (rev 16300) +++ trunk/plugins/tcl/Makefile.am 2006-06-21 04:57:27 UTC (rev 16301) @@ -5,7 +5,7 @@ plugin_LTLIBRARIES = tcl.la tcl_la_SOURCES = tcl.c tcl_glib.c tcl_glib.h tcl_cmds.c tcl_signals.c tcl_gaim.h \ - tcl_ref.c + tcl_ref.c tcl_cmd.c EXTRA_DIST = signal-test.tcl Makefile.mingw Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-06-21 04:10:47 UTC (rev 16300) +++ trunk/plugins/tcl/tcl.c 2006-06-21 04:57:27 UTC (rev 16301) @@ -126,6 +126,7 @@ Tcl_CreateObjCommand(interp, "::gaim::account", tcl_cmd_account, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::buddy", tcl_cmd_buddy, (ClientData)NULL, NULL); + Tcl_CreateObjCommand(interp, "::gaim::cmd", tcl_cmd_cmd, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::connection", tcl_cmd_connection, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::conversation", tcl_cmd_conversation, (ClientData)NULL, NULL); Tcl_CreateObjCommand(interp, "::gaim::core", tcl_cmd_core, (ClientData)NULL, NULL); @@ -284,7 +285,9 @@ if (Tcl_EvalFile(interp, plugin->path) != TCL_OK) { result = Tcl_GetObjResult(interp); - gaim_debug(GAIM_DEBUG_ERROR, "tcl", "Error evaluating %s: %s\n", plugin->path, Tcl_GetString(result)); + gaim_debug(GAIM_DEBUG_ERROR, "tcl", + "Error evaluating %s: %s\n", plugin->path, + Tcl_GetString(result)); Tcl_DeleteInterp(interp); return FALSE; } @@ -313,6 +316,7 @@ if (data != NULL) { g_hash_table_remove(tcl_plugins, (gpointer)(data->interp)); gaim_signals_disconnect_by_handle(data->interp); + tcl_cmd_cleanup(data->interp); tcl_signal_cleanup(data->interp); Tcl_Release((ClientData)data->interp); Tcl_DeleteInterp(data->interp); @@ -341,6 +345,7 @@ if(!tcl_loaded) return FALSE; tcl_glib_init(); + tcl_cmd_init(); tcl_signal_init(); gaim_tcl_ref_init(); Added: trunk/plugins/tcl/tcl_cmd.c =================================================================== --- trunk/plugins/tcl/tcl_cmd.c (rev 0) +++ trunk/plugins/tcl/tcl_cmd.c 2006-06-21 04:57:27 UTC (rev 16301) @@ -0,0 +1,189 @@ +/** + * @file tcl_cmd.c Gaim Tcl cmd API + * + * gaim + * + * Copyright (C) 2006 Etan Reisner <de...@gm...> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <tcl.h> + +#include "tcl_gaim.h" + +#include "internal.h" +#include "cmds.h" +#include "debug.h" + +static GList *tcl_cmd_callbacks; + +static GaimCmdRet tcl_cmd_callback(GaimConversation *conv, const gchar *cmd, + gchar **args, gchar **errors, + struct tcl_cmd_handler *handler); +static Tcl_Obj *new_cmd_cb_namespace(void); + +void tcl_cmd_init() +{ + tcl_cmd_callbacks = NULL; +} + +void tcl_cmd_handler_free(struct tcl_cmd_handler *handler) +{ + if (handler == NULL) + return; + + Tcl_DecrRefCount(handler->namespace); + g_free(handler); +} + +void tcl_cmd_cleanup(Tcl_Interp *interp) +{ + GList *cur; + struct tcl_cmd_handler *handler; + + for (cur = tcl_cmd_callbacks; cur != NULL; cur = g_list_next(cur)) { + handler = cur->data; + if (handler->interp == interp) { + gaim_cmd_unregister(handler->id); + tcl_cmd_handler_free(handler); + cur->data = NULL; + } + } + tcl_cmd_callbacks = g_list_remove_all(tcl_cmd_callbacks, NULL); +} + +GaimCmdId tcl_cmd_register(struct tcl_cmd_handler *handler) +{ + int id; + GString *proc; + + if ((id = gaim_cmd_register(Tcl_GetString(handler->cmd), + handler->args, handler->priority, + handler->flags, handler->prpl_id, + GAIM_CMD_FUNC(tcl_cmd_callback), + handler->helpstr, (void *)handler)) == 0) + return 0; + + handler->namespace = new_cmd_cb_namespace (); + Tcl_IncrRefCount(handler->namespace); + proc = g_string_new(""); + g_string_append_printf(proc, "namespace eval %s { proc cb { conv cmd arglist } { %s } }", + Tcl_GetString(handler->namespace), + Tcl_GetString(handler->proc)); + if (Tcl_Eval(handler->interp, proc->str) != TCL_OK) { + Tcl_DecrRefCount(handler->namespace); + g_string_free(proc, TRUE); + return 0; + } + g_string_free(proc, TRUE); + + tcl_cmd_callbacks = g_list_append(tcl_cmd_callbacks, (gpointer)handler); + + return id; +} + +void tcl_cmd_unregister(GaimCmdId id, Tcl_Interp *interp) +{ + GList *cur; + GString *cmd; + gboolean found = FALSE; + struct tcl_cmd_handler *handler; + + for (cur = tcl_cmd_callbacks; cur != NULL; cur = g_list_next(cur)) { + handler = cur->data; + if (handler->interp == interp && handler->id == id) { + gaim_cmd_unregister(id); + cmd = g_string_sized_new(64); + g_string_printf(cmd, "namespace delete %s", + Tcl_GetString(handler->namespace)); + Tcl_EvalEx(interp, cmd->str, -1, TCL_EVAL_GLOBAL); + tcl_cmd_handler_free(handler); + g_string_free(cmd, TRUE); + cur->data = NULL; + found = TRUE; + break; + } + } + + if (found) + tcl_cmd_callbacks = g_list_remove_all(tcl_cmd_callbacks, NULL); +} + +static GaimCmdRet tcl_cmd_callback(GaimConversation *conv, const gchar *cmd, + gchar **args, gchar **errors, + struct tcl_cmd_handler *handler) +{ + int retval, error, i; + Tcl_Obj *command, *arg, *tclargs, *result; + + command = Tcl_NewListObj(0, NULL); + Tcl_IncrRefCount(command); + + /* The callback */ + arg = Tcl_DuplicateObj(handler->namespace); + Tcl_AppendStringsToObj(arg, "::cb", NULL); + Tcl_ListObjAppendElement(handler->interp, command, arg); + + /* The conversation */ + arg = Tcl_NewIntObj((int)conv); + Tcl_ListObjAppendElement(handler->interp, command, arg); + + /* The command */ + arg = Tcl_NewStringObj(cmd, -1); + Tcl_ListObjAppendElement(handler->interp, command, arg); + + /* The args list */ + tclargs = Tcl_NewListObj(0, NULL); + for (i = 0; i < handler->nargs; i++) { + arg = Tcl_NewStringObj(args[i], -1); + + Tcl_ListObjAppendElement(handler->interp, tclargs, arg); + } + Tcl_ListObjAppendElement(handler->interp, command, tclargs); + + if ((error = Tcl_EvalObjEx(handler->interp, command, + TCL_EVAL_GLOBAL)) != TCL_OK) { + gchar *errorstr; + + errorstr = g_strdup_printf("error evaluating callback: %s\n", + Tcl_GetString(Tcl_GetObjResult(handler->interp))); + gaim_debug(GAIM_DEBUG_ERROR, "tcl", errorstr); + *errors = errorstr; + retval = GAIM_CMD_RET_FAILED; + } else { + result = Tcl_GetObjResult(handler->interp); + if ((error = Tcl_GetIntFromObj(handler->interp, result, + &retval)) != TCL_OK) { + gchar *errorstr; + + errorstr = g_strdup_printf("Error retreiving procedure result: %s\n", + Tcl_GetString(Tcl_GetObjResult(handler->interp))); + gaim_debug(GAIM_DEBUG_ERROR, "tcl", errorstr); + *errors = errorstr; + retval = GAIM_CMD_RET_FAILED; + } + } + + return retval; +} + +static Tcl_Obj *new_cmd_cb_namespace() +{ + char name[32]; + static int cbnum; + + g_snprintf(name, sizeof(name), "::gaim::_callback::cb_%d", cbnum++); + return Tcl_NewStringObj(name, -1); +} Property changes on: trunk/plugins/tcl/tcl_cmd.c ___________________________________________________________________ Name: svn:mime-type + text/x-csrc Name: svn:eol-style + native Modified: trunk/plugins/tcl/tcl_cmds.c =================================================================== --- trunk/plugins/tcl/tcl_cmds.c 2006-06-21 04:10:47 UTC (rev 16300) +++ trunk/plugins/tcl/tcl_cmds.c 2006-06-21 04:57:27 UTC (rev 16301) @@ -541,6 +541,70 @@ return TCL_OK; } +int tcl_cmd_cmd(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) +{ + const char *cmds[] = { "register", "unregister", NULL }; + enum { CMD_CMD_REGISTER, CMD_CMD_UNREGISTER } cmd; + struct tcl_cmd_handler *handler; + Tcl_Obj *result = Tcl_GetObjResult(interp); + GaimCmdId id; + int error; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?args?"); + return TCL_ERROR; + } + + if ((error = Tcl_GetIndexFromObj(interp, objv[1], cmds, "subcommand", 0, (int *)&cmd)) != TCL_OK) + return error; + + switch (cmd) { + case CMD_CMD_REGISTER: + if (objc != 9) { + Tcl_WrongNumArgs(interp, 2, objv, "cmd arglist priority flags prpl_id proc helpstr"); + return TCL_ERROR; + } + handler = g_new0(struct tcl_cmd_handler, 1); + handler->cmd = objv[2]; + handler->args = Tcl_GetString(objv[3]); + handler->nargs = strlen(handler->args); + if ((error = Tcl_GetIntFromObj(interp, objv[4], + &handler->priority)) != TCL_OK) { + g_free(handler); + return error; + } + if ((error = Tcl_GetIntFromObj(interp, objv[5], + &handler->flags)) != TCL_OK) { + g_free(handler); + return error; + } + handler->prpl_id = Tcl_GetString(objv[6]); + handler->proc = objv[7]; + handler->helpstr = Tcl_GetString(objv[8]); + handler->interp = interp; + if ((id = tcl_cmd_register(handler)) == 0) { + tcl_cmd_handler_free(handler); + Tcl_SetIntObj(result, 0); + } else { + handler->id = id; + Tcl_SetIntObj(result, id); + } + break; + case CMD_CMD_UNREGISTER: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "id"); + return TCL_ERROR; + } + if ((error = Tcl_GetIntFromObj(interp, objv[2], + (int *)&id)) != TCL_OK) + return error; + tcl_cmd_unregister(id, interp); + break; + } + + return TCL_OK; +} + int tcl_cmd_connection(ClientData unused, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *result = Tcl_GetObjResult(interp), *list, *elem; Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-06-21 04:10:47 UTC (rev 16300) +++ trunk/plugins/tcl/tcl_gaim.h 2006-06-21 04:57:27 UTC (rev 16301) @@ -26,6 +26,7 @@ #include <tcl.h> #include "internal.h" +#include "cmds.h" #include "plugin.h" #include "value.h" #include "stringref.h" @@ -45,6 +46,23 @@ GaimValue **argtypes; }; +struct tcl_cmd_handler { + int id; + Tcl_Obj *cmd; + Tcl_Interp *interp; + + Tcl_Obj *namespace; + /* These are temporary during setup */ + const char *args; + int priority; + int flags; + const char *prpl_id; + Tcl_Obj *proc; + const char *helpstr; + + int nargs; +}; + extern GaimPlugin *_tcl_plugin; /* Capitalized this way because these are "types" */ @@ -65,6 +83,12 @@ gboolean tcl_signal_connect(struct tcl_signal_handler *handler); void tcl_signal_disconnect(void *instance, const char *signal, Tcl_Interp *interp); +void tcl_cmd_init(void); +void tcl_cmd_handler_free(struct tcl_cmd_handler *handler); +void tcl_cmd_cleanup(Tcl_Interp *interp); +GaimCmdId tcl_cmd_register(struct tcl_cmd_handler *handler); +void tcl_cmd_unregister(GaimCmdId id, Tcl_Interp *interp); + void gaim_tcl_ref_init(void); void *gaim_tcl_ref_get(Tcl_Interp *interp, Tcl_Obj *obj, GaimStringref *type); Tcl_Obj *gaim_tcl_ref_new(GaimStringref *type, void *value); @@ -72,6 +96,7 @@ Tcl_ObjCmdProc tcl_cmd_account; Tcl_ObjCmdProc tcl_cmd_signal_connect; Tcl_ObjCmdProc tcl_cmd_buddy; +Tcl_ObjCmdProc tcl_cmd_cmd; Tcl_ObjCmdProc tcl_cmd_connection; Tcl_ObjCmdProc tcl_cmd_conversation; Tcl_ObjCmdProc tcl_cmd_core; Modified: trunk/plugins/tcl/tcl_signals.c =================================================================== --- trunk/plugins/tcl/tcl_signals.c 2006-06-21 04:10:47 UTC (rev 16300) +++ trunk/plugins/tcl/tcl_signals.c 2006-06-21 04:57:27 UTC (rev 16301) @@ -387,7 +387,6 @@ g_string_free(val, TRUE); g_free(vals); g_free(strs); - return retval; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ebl...@us...> - 2006-07-11 16:22:33
|
Revision: 16486 Author: eblanton Date: 2006-07-11 09:22:28 -0700 (Tue, 11 Jul 2006) ViewCVS: http://svn.sourceforge.net/gaim/?rev=16486&view=rev Log Message: ----------- Fix some more 64-bit warnings. The "handle" warnings remain, because they're real problems on 64-bit systems and they still need fixin'. I'm not sure how to best fix them just yet. Modified Paths: -------------- trunk/plugins/tcl/tcl.c trunk/plugins/tcl/tcl_gaim.h trunk/plugins/tcl/tcl_signals.c Modified: trunk/plugins/tcl/tcl.c =================================================================== --- trunk/plugins/tcl/tcl.c 2006-07-11 16:11:30 UTC (rev 16485) +++ trunk/plugins/tcl/tcl.c 2006-07-11 16:22:28 UTC (rev 16486) @@ -54,10 +54,12 @@ GaimStringref *GaimTclRefConnection; GaimStringref *GaimTclRefConversation; GaimStringref *GaimTclRefPointer; +GaimStringref *GaimTclRefPlugin; GaimStringref *GaimTclRefPresence; GaimStringref *GaimTclRefStatus; GaimStringref *GaimTclRefStatusAttr; GaimStringref *GaimTclRefStatusType; +GaimStringref *GaimTclRefXfer; static GHashTable *tcl_plugins = NULL; @@ -186,7 +188,7 @@ buf = g_malloc(len + 1); cur = buf; - while (fgets(cur, (int) buf - (buf - cur), fp)) { + while (fgets(cur, GPOINTER_TO_INT(buf) - (buf - cur), fp)) { cur += strlen(cur); if (feof(fp)) break; @@ -353,10 +355,12 @@ GaimTclRefConnection = gaim_stringref_new("Connection"); GaimTclRefConversation = gaim_stringref_new("Conversation"); GaimTclRefPointer = gaim_stringref_new("Pointer"); + GaimTclRefPlugin = gaim_stringref_new("Plugin"); GaimTclRefPresence = gaim_stringref_new("Presence"); GaimTclRefStatus = gaim_stringref_new("Status"); GaimTclRefStatusAttr = gaim_stringref_new("StatusAttr"); GaimTclRefStatusType = gaim_stringref_new("StatusType"); + GaimTclRefXfer = gaim_stringref_new("Xfer"); tcl_plugins = g_hash_table_new(g_direct_hash, g_direct_equal); Modified: trunk/plugins/tcl/tcl_gaim.h =================================================================== --- trunk/plugins/tcl/tcl_gaim.h 2006-07-11 16:11:30 UTC (rev 16485) +++ trunk/plugins/tcl/tcl_gaim.h 2006-07-11 16:22:28 UTC (rev 16486) @@ -70,10 +70,12 @@ extern GaimStringref *GaimTclRefConnection; extern GaimStringref *GaimTclRefConversation; extern GaimStringref *GaimTclRefPointer; +extern GaimStringref *GaimTclRefPlugin; extern GaimStringref *GaimTclRefPresence; extern GaimStringref *GaimTclRefStatus; extern GaimStringref *GaimTclRefStatusAttr; extern GaimStringref *GaimTclRefStatusType; +extern GaimStringref *GaimTclRefXfer; GaimPlugin *tcl_interp_get_plugin(Tcl_Interp *interp); Modified: trunk/plugins/tcl/tcl_signals.c =================================================================== --- trunk/plugins/tcl/tcl_signals.c 2006-07-11 16:11:30 UTC (rev 16485) +++ trunk/plugins/tcl/tcl_signals.c 2006-07-11 16:22:28 UTC (rev 16486) @@ -143,8 +143,12 @@ return GaimTclRefConnection; case GAIM_SUBTYPE_CONVERSATION: return GaimTclRefConversation; + case GAIM_SUBTYPE_PLUGIN: + return GaimTclRefPlugin; case GAIM_SUBTYPE_STATUS: return GaimTclRefStatus; + case GAIM_SUBTYPE_XFER: + return GaimTclRefXfer; default: return NULL; } @@ -270,22 +274,12 @@ case GAIM_SUBTYPE_CONNECTION: case GAIM_SUBTYPE_CONVERSATION: case GAIM_SUBTYPE_STATUS: + case GAIM_SUBTYPE_PLUGIN: + case GAIM_SUBTYPE_XFER: if (gaim_value_is_outgoing(handler->argtypes[i])) gaim_debug_error("tcl", "pointer subtypes do not currently support outgoing arguments\n"); arg = gaim_tcl_ref_new(ref_type(gaim_value_get_subtype(handler->argtypes[i])), va_arg(args, void *)); break; - case GAIM_SUBTYPE_PLUGIN: - case GAIM_SUBTYPE_XFER: - /* pointers again */ - if (gaim_value_is_outgoing(handler->argtypes[i])) { - vals[i] = va_arg(args, void **); - Tcl_LinkVar(handler->interp, name->str, - vals[i], TCL_LINK_INT); - arg = Tcl_NewStringObj(name->str, -1); - } else { - arg = Tcl_NewIntObj((int)va_arg(args, void *)); - } - break; case GAIM_SUBTYPE_BLIST: case GAIM_SUBTYPE_BLIST_BUDDY: case GAIM_SUBTYPE_BLIST_GROUP: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |