diff -P -c -r gaim-1.1.0/src/protocols/Makefile.am gaim-1.1.0n/src/protocols/Makefile.am *** gaim-1.1.0/src/protocols/Makefile.am Sun May 2 19:57:10 2004 --- gaim-1.1.0n/src/protocols/Makefile.am Tue Dec 7 14:12:36 2004 *************** *** 1,3 **** ! DIST_SUBDIRS = gg irc jabber msn napster novell oscar rendezvous silc toc trepia yahoo zephyr SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS) --- 1,3 ---- ! DIST_SUBDIRS = gg irc jabber msn napster novell oscar rendezvous silc toc trepia yahoo zephyr tsn SUBDIRS = $(DYNAMIC_PRPLS) $(STATIC_PRPLS) diff -P -c -r gaim-1.1.0/src/protocols/tsn/Makefile.am gaim-1.1.0n/src/protocols/tsn/Makefile.am *** gaim-1.1.0/src/protocols/tsn/Makefile.am Thu Jan 1 01:00:00 1970 --- gaim-1.1.0n/src/protocols/tsn/Makefile.am Mon Dec 13 11:36:55 2004 *************** *** 0 **** --- 1,30 ---- + EXTRA_DIST = \ + Makefile.mingw + + pkgdir = $(libdir)/gaim + + TSNSOURCES = tsn.c + + libtsn_la_LDFLAGS = -module -avoid-version + + if STATIC_TSN + + st = -DGAIM_STATIC_PRPL + noinst_LIBRARIES = libtsn.a + libtsn_a_SOURCES = $(TSNSOURCES) + libtsn_a_CFLAGS = $(AM_CFLAGS) + + else + + st = + pkg_LTLIBRARIES = libtsn.la + libtsn_la_SOURCES = $(TSNSOURCES) + + endif + + AM_CFLAGS = $(st) + + AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + $(GLIB_CFLAGS) \ + $(DEBUG_CFLAGS) diff -P -c -r gaim-1.1.0/src/protocols/tsn/Makefile.mingw gaim-1.1.0n/src/protocols/tsn/Makefile.mingw *** gaim-1.1.0/src/protocols/tsn/Makefile.mingw Thu Jan 1 01:00:00 1970 --- gaim-1.1.0n/src/protocols/tsn/Makefile.mingw Mon Dec 13 11:36:55 2004 *************** *** 0 **** --- 1,133 ---- + # + # Makefile.mingw + # + # Description: Makefile for win32 (mingw) version of libtsn + # + + # + # PATHS + # + + INCLUDE_DIR := . + GTK_TOP := ../../../../win32-dev/gtk_2_0 + GAIM_TOP := ../../.. + NAPSTER_ROOT := . + GAIM_INSTALL_DIR := $(GAIM_TOP)/win32-install-dir + + ## + ## VARIABLE DEFINITIONS + ## + + TARGET = libnapster + + # Compiler Options + + CFLAGS = + + DEFINES = + + # Static or Plugin... + ifeq ($(TYPE),STATIC) + DEFINES += -DSTATIC + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR) + else + ifeq ($(TYPE),PLUGIN) + DLL_INSTALL_DIR = $(GAIM_INSTALL_DIR)/plugins + endif + endif + + + ## + ## INCLUDE MAKEFILES + ## + + include $(GAIM_TOP)/src/win32/global.mak + + ## + ## INCLUDE PATHS + ## + + INCLUDE_PATHS += -I$(NAPSTER_ROOT) \ + -I$(GTK_TOP)/include \ + -I$(GTK_TOP)/include/gtk-2.0 \ + -I$(GTK_TOP)/include/glib-2.0 \ + -I$(GTK_TOP)/include/pango-1.0 \ + -I$(GTK_TOP)/include/atk-1.0 \ + -I$(GTK_TOP)/lib/glib-2.0/include \ + -I$(GTK_TOP)/lib/gtk-2.0/include \ + -I$(GAIM_TOP)/src \ + -I$(GAIM_TOP)/src/win32 \ + -I$(GAIM_TOP) + + + LIB_PATHS = -L$(GTK_TOP)/lib \ + -L$(GAIM_TOP)/src + + + ## + ## SOURCES, OBJECTS + ## + + C_SRC = napster.c + + + OBJECTS = $(C_SRC:%.c=%.o) + + + ## + ## LIBRARIES + ## + + LIBS = -lgtk-win32-2.0 \ + -lglib-2.0 \ + -lgdk-win32-2.0 \ + -lgmodule-2.0 \ + -lgobject-2.0 \ + -lws2_32 \ + -lintl \ + -lgaim + + + ## + ## RULES + ## + + # How to make a C file + + %.o: %.c + $(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $< + + ## + ## TARGET DEFINITIONS + ## + + .PHONY: all clean + + all: $(TARGET).dll + + install: + cp $(NAPSTER_ROOT)/$(TARGET).dll $(DLL_INSTALL_DIR) + + + ## + ## BUILD Dependencies + ## + + $(GAIM_TOP)/src/gaim.lib: + $(MAKE) -C $(GAIM_TOP)/src -f Makefile.mingw gaim.lib + + ## + ## BUILD DLL + ## + + $(TARGET).dll: $(OBJECTS) $(GAIM_TOP)/src/gaim.lib + $(CC) -shared $(OBJECTS) $(LIB_PATHS) $(LIBS) $(DLL_LD_FLAGS) -Wl,--out-implib,$(TARGET).lib -o $(TARGET).dll + + ## + ## CLEAN RULES + ## + + clean: + rm -rf *.o + rm -rf $(TARGET).dll + rm -rf $(TARGET).lib diff -P -c -r gaim-1.1.0/src/protocols/tsn/tsn.c gaim-1.1.0n/src/protocols/tsn/tsn.c *** gaim-1.1.0/src/protocols/tsn/tsn.c Thu Jan 1 01:00:00 1970 --- gaim-1.1.0n/src/protocols/tsn/tsn.c Tue Feb 15 14:40:54 2005 *************** *** 0 **** --- 1,906 ---- + #include "internal.h" + + #include "account.h" + #include "accountopt.h" + #include "blist.h" + #include "conversation.h" + #include "debug.h" + #include "notify.h" + #include "prpl.h" + #include "proxy.h" + #include "util.h" + #include "request.h" + #include "version.h" + #include "roomlist.h" + + #define TSN_SERVER "localhost" + #define TSN_PORT 8888 + + #define TSN_CONNECT_STEPS 2 + + GSList *tsn_connections = NULL; + + int chat_id=0; + + //HACK + char ALREADY_LOOKING = FALSE; + + // /HACK + struct tsn_data { + int fd; + gchar *login; + }; + + GaimRoomlist* local_chats; + + // Use a macro to not process variable arguments + #define TSN_SEND_PACKET(gc, command, format, args...) {char buffer[1024]; snprintf(buffer, sizeof(buffer), format, ##args); tsn_write_packet(gc, command, buffer);} + + // Macro to check strings + #define EQUALS(strx,stry) (!strncmp(strx, stry, strlen(stry))) + + + static void tsn_close(GaimConnection *gc); + + + // Send a packet to the TSN daemon + static void tsn_write_packet(GaimConnection *gc, + const char* command, + const char *message) + { + struct tsn_data *tsndata = (struct tsn_data *)gc->proto_data; + int len, wrote; + + // Calculate length + len = strlen(command) + strlen(message) + 3; + + wrote = write(tsndata->fd, (const void*) &len, 4); + if (wrote != 4) { + printf("Error sending length: (%d) %s\n",wrote, strerror(errno)); + } + wrote += write(tsndata->fd, (const void*) command, strlen(command)); + wrote += write(tsndata->fd, (const void*) "+|+", 3); + wrote += write(tsndata->fd, (const void*) message, strlen(message)); + + + if (wrote <= 0) { + printf("Error sending data %s\n",strerror(errno)); + } + } + + + //Called when user has selected witch chat to talk in + static void tsn_select_chat_cb(GaimConnection *gc, const char *entry){ + TSN_SEND_PACKET(gc, "select_chat", "%s",entry); + } + + //Returns a pointer to the chat given as input + static GaimConversation *tsn_find_chat(GaimConnection *gc, const char *name) + { + GSList *bcs = gc->buddy_chats; + + while (bcs) { + GaimConversation *b = bcs->data; + if (!gaim_utf8_strcasecmp(b->name, name)) + return b; + bcs = bcs->next; + } + + return NULL; + } + + //Called when Gaim receives a message from the local server + static void tsn_callback(gpointer data, + gint source, + GaimInputCondition condition) + { + GaimConnectionUiOps *ops; + GaimConnection *gc = data; + struct tsn_data *tsndata = gc->proto_data; + GaimConversation *c; + GaimAccount *account; + GaimConvIm *gcim; + GaimConvChat *gcchat; + gchar* command; + + int len; + + gchar buffer[10240]; + + memset(buffer, 0, sizeof(buffer)); + + if (read(source, &len, 4) < 4) { + printf("Missing length\n"); + // Close down + tsn_close(gc); + return; + } + + if( len > sizeof(buffer)) { + printf("Message too long (%d > %d)\n", len, sizeof(buffer)); + return; + } + + if (read(source, buffer, len) < len) { + printf("Read too few bytes!\n"); + return; + } + + //printf("Got data '%s'\n",buffer); + + // The buffer should be in the form: + // command+|+data + + // Analyze callback + command = strtok(buffer, "+|+"); + + if (command == NULL) { + gaim_connection_error(gc, _("Bad message from server, missing command")); + return; + } + + if EQUALS(command, "login") { + + gchar* user; + user = strtok(NULL, "+|+"); + + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Received login command for user: %s\n", user); + tsndata->login = g_strdup(user); + + //Our signon is complete + gaim_connection_set_state(gc, GAIM_CONNECTED); + serv_finish_login(gc); + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Finished logging on account\n"); + + return; + } + + if EQUALS(command, "shutdown") { + tsn_close(gc); + return; + } + + if EQUALS(command, "signon") { + + gchar* user; + user = strtok(NULL, "+|+"); + + //A buddy has signed on + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Buddy: %s signed on\n",user); + serv_got_update(gc, user, 1, 0, 0, 0, 0); + return; + } + + if EQUALS(command, "signoff") { + + gchar* user; + user = strtok(NULL, "+|+"); + + //A buddy has signed off + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Buddy: %s signed off\n",user); + serv_got_update(gc, user, 0, 0, 0, 0, 0); + return; + } + + if EQUALS(command, "im") { + //A IM has been received + gchar *user, *msg; + + user = strtok(NULL, "+|+"); + msg = strtok(NULL, "+|+"); + + gaim_debug(GAIM_DEBUG_MISC, "tsn", + "Received IM from: %s\n", user); + + account = gaim_connection_get_account(gc); + c=gaim_conversation_new(GAIM_CONV_IM,account,user); + gcim=gaim_conversation_get_im_data(c); + gaim_conv_im_write(gcim,user,msg,GAIM_MESSAGE_RECV,time(NULL)); + + return; + } + + if EQUALS(command, "error") { + char *msg; + msg = strtok(NULL, "+|+"); + + //A error message has been received + //This is a rewite of the gaim_connection_error function, + //that does not close Gaim account on error + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Received error message\n"); + ops = gaim_connections_get_ui_ops(); + if (ops != NULL) { + if (ops->report_disconnect != NULL) + ops->report_disconnect(gc, msg); + } + return; + } + + if EQUALS(command, "join_chat") { + + char *user, *chat; + user = strtok(NULL, "+|+"); + chat = strtok(NULL, "+|+"); + + account = gaim_connection_get_account(gc); + c=tsn_find_chat(gc,chat); + gaim_debug(GAIM_DEBUG_MISC, "tsn", + "Adding user %s to chat %s\n", user, chat); + gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), + user, NULL, GAIM_CBFLAGS_NONE, TRUE); + return; + } + + if EQUALS(command, "chat_msg") { + + char *user, *chat, *msg; + user = strtok(NULL, "+|+"); + chat = strtok(NULL, "+|+"); + msg = strtok(NULL, "+|+"); + + gaim_debug(GAIM_DEBUG_MISC, "tsn", + "Received a chat message from: %s on chat %s\n", + user, chat); + c=tsn_find_chat(gc,chat); + gcchat = GAIM_CONV_CHAT(c); + gaim_conv_chat_write(gcchat,user,msg,1,time(NULL)); + return; + } + + if EQUALS(command, "leave_chat") { + + char *user, *chat; + user = strtok(NULL, "+|+"); + chat = strtok(NULL, "+|+"); + + gaim_debug(GAIM_DEBUG_MISC, "tsn", + "Removed user %s from chat %s\n", user, chat); + c=tsn_find_chat(gc, chat); + gcchat = GAIM_CONV_CHAT(c); + gaim_conv_chat_remove_user(gcchat, user, NULL); + return; + } + + + if (EQUALS(command, "found_chat") || EQUALS(command, "found_local_chat")) { + + int i, total; + + total = atoi(strtok(NULL, "+|+")); + + // If we're getting a local chat room list, we already have the + // window open, otherwise we have to create a window first + if EQUALS(command, "found_chat") { + // Make gaim show the room list thingy + ALREADY_LOOKING = TRUE; + gaim_roomlist_show_with_account(gaim_connection_get_account(gc)); + ALREADY_LOOKING = FALSE; + } + + // Fill in the data + for (i=0; iDescription: %s
" + "Keywords: %s
" + "URL:%s", + Desc?Desc:"", Keywords?Keywords:"", + URL?URL:"", URL?URL:""); + + gaim_notify_userinfo(gc, + Nick, + _("User information"), // Title + _("User information"), // Primary + Nick, // Secondary + buffer, // Text + NULL, // Callback + NULL); // User data + } + + /* + //Received result for search after chattes, Gaim request input witch chat to join + case 6: + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Received chat search result\n"); + gaim_request_input(gc, NULL, _("Search result"), _(buf),NULL, FALSE, FALSE, NULL,_("Select chat nr"), G_CALLBACK(tsn_select_chat_cb),_("Cancel"), NULL, gc); + break; + + //Received initiate new chat message + case 7: + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Initiated chat: %s\n",buf); + account = gaim_connection_get_account(gc); + c=gaim_conversation_new(GAIM_CONV_CHAT,account,buf); + gcchat = GAIM_CONV_CHAT(c); + if (!g_slist_find(gc->buddy_chats, c)) + gc->buddy_chats = g_slist_append(gc->buddy_chats, c); + chat_id++; + gaim_conv_chat_set_id(gcchat,chat_id); + gaim_conv_window_show(gaim_conversation_get_window(c)); + gaim_conv_window_switch_conversation(gaim_conversation_get_window(c),gaim_conversation_get_index(c)); + break; + + //Add a new user to chat + case 8: + + + + //Used to send test msg to test if the connection to Gaim is active, this is done if we get a unidentified exception + case 99: + gaim_debug(GAIM_DEBUG_MISC, "tsn", "%s\n", buf); + break; + + } + g_free(buf); + */ + } + + //Called during login, connects to the local server + static void tsn_login_connect(gpointer data, gint source, GaimInputCondition cond) + { + GaimConnection *gc = data; + struct tsn_data *tsndata = (struct tsn_data *)gc->proto_data; + gchar *buf; + + if (!g_list_find(gaim_connections_get_all(), gc)) { + close(source); + return; + } + + if (source < 0) { + gaim_connection_error(gc, _("Unable to connect.")); + return; + } + + tsndata->fd = source; + + // Update the login progress status display + buf = g_strdup_printf("Logging in: %s", + gaim_account_get_username(gc->account)); + gaim_connection_update_progress(gc, buf, 1, TSN_CONNECT_STEPS); + g_free(buf); + + // Write our signon data + TSN_SEND_PACKET(gc, "login", "%s+|+%s+|+%s+|+%s", + gaim_account_get_username(gc->account), + gaim_account_get_alias(gc->account), + VERSION, + gaim_account_get_string(gc->account, "keywords", "")); + + // And set up the input watcher + gc->inpa = gaim_input_add(tsndata->fd, + GAIM_INPUT_READ, + tsn_callback, + gc); + + } + + //Called during login, start the login prosedure + static void tsn_login(GaimAccount *account) + { + GaimConnection *gc = gaim_account_get_connection(account); + + gaim_connection_update_progress(gc, _("Connecting"), 0, TSN_CONNECT_STEPS); + + gc->proto_data = g_new0(struct tsn_data, 1); + if (gaim_proxy_connect(account, + gaim_account_get_string(account, "server", TSN_SERVER), + gaim_account_get_int(account, "port", TSN_PORT), + tsn_login_connect, gc) != 0) { + gaim_connection_error(gc, _("Unable to connect.")); + } + } + + //Called when Gaim user signs off, responsible for cleaning up and informing the local server + static void tsn_close(GaimConnection *gc) + { + struct tsn_data *tsndata = (struct tsn_data *)gc->proto_data; + + if (gc->inpa) + gaim_input_remove(gc->inpa); + + if (!tsndata) + return; + + TSN_SEND_PACKET(gc, "signoff", "%s", gaim_account_get_username(gc->account)); + close(tsndata->fd); + + g_free(tsndata->login); + g_free(tsndata); + + } + + // Create an initiate-chat window thingy + GList *tsn_chat_info(GaimConnection *gc) + { + GList *m = NULL; + struct proto_chat_entry *pce; + + pce = g_new0(struct proto_chat_entry, 1); + pce->label = _("_Name:"); + pce->identifier = "name"; + m = g_list_append(m, pce); + + pce = g_new0(struct proto_chat_entry, 1); + pce->label = _("_Description:"); + pce->identifier = "description"; + m = g_list_append(m, pce); + + + pce = g_new0(struct proto_chat_entry, 1); + pce->label = _("_Keywords:"); + pce->identifier = "keywords"; + m = g_list_append(m, pce); + + return m; + } + + + static const char* tsn_list_icon(GaimAccount *a, GaimBuddy *b) + { + //Returns the name of the icon used by Gaim to represent the protocol + return "tsn"; + } + + static void tsn_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne) + { + if (b->present == GAIM_BUDDY_OFFLINE) + *se = "offline"; + } + + //Called when Gaim user wants to add a new buddy + static void tsn_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) + { + TSN_SEND_PACKET(gc, "add_buddy", "%s+|+%s", buddy->name, buddy->alias); + } + + //Called when Gaim user wants to add more then one buddy + static void tsn_add_buddies(GaimConnection *gc, GList *buddies, GList *groups) + { + while (buddies) { + GaimBuddy *buddy = buddies->data; + gaim_debug(GAIM_DEBUG_MISC, "tsn", "Buddy: %s\n",buddy->name); + TSN_SEND_PACKET(gc, "add_buddy", "%s+|+%s", buddy->name, buddy->alias); + buddies = buddies->next; + } + } + + //Called whwn Gaim user wants to remove a buddy from his buddylist + static void tsn_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) + { + TSN_SEND_PACKET(gc, "remove_buddy", "%s", buddy->name); + } + + //Called when a buddy wants to send a IM + static int tsn_send_im(GaimConnection *gc, const char *who, const char *message, GaimConvImFlags flags) + { + TSN_SEND_PACKET(gc, "send_im", "%s+|+%s", who, message); + return 1; + } + + //Called when Gaim user wants to send a chat message + static int tsn_chat_send(GaimConnection *gc, int id, const char *message) + { + GaimConversation *c = gaim_find_chat(gc, id); + GaimConvChat *gcchat; + if (!c){ + return -EINVAL; + } + //gcchat = GAIM_CONV_CHAT(c); + //gaim_conv_chat_write(gcchat,gaim_account_get_username(gc->account),message,1,time(NULL)); + TSN_SEND_PACKET(gc, "send_chat_msg", "%s+|+%s",c->name, message); + + return 0; + } + + static void tsn_start_chat(GaimConnection *gc, + const char* name) + { + GaimConversation *c; + GaimAccount *account; + GaimConvChat *gcchat; + int id; + + account = gaim_connection_get_account(gc); + + c=gaim_conversation_new(GAIM_CONV_CHAT,account,name); + + gcchat = GAIM_CONV_CHAT(c); + if (!g_slist_find(gc->buddy_chats, c)) + gc->buddy_chats = g_slist_append(gc->buddy_chats, c); + chat_id++; + gaim_conv_chat_set_id(gcchat,chat_id); + gaim_conv_window_show(gaim_conversation_get_window(c)); + gaim_conv_window_switch_conversation(gaim_conversation_get_window(c),gaim_conversation_get_index(c)); + //gaim_conv_chat_add_user(gcchat, + // gaim_account_get_alias(gc->account), + // NULL,GAIM_CBFLAGS_NONE,TRUE); + + id=gaim_conv_chat_get_id(gcchat); + + } + + void tsn_get_info(GaimConnection *gc, const char* who) { + + TSN_SEND_PACKET(gc, "get_info", "%s", who); + } + + //Called when a user joins a chat + void tsn_chat_join(GaimConnection *gc, GHashTable *data) + { + //GaimConversation *c = gaim_find_chat(gc, id); + char *name, *description, *keywords; + + name = g_hash_table_lookup(data, "name"); + //ownerid = g_hash_table_lookup(data, "owner"); + + // Create local chat window + tsn_start_chat(gc, name); + + // Create or join? + // If we have more info here, we might need to create the chat first! + description = g_hash_table_lookup(data, "description"); + keywords = g_hash_table_lookup(data, "keywords"); + + if (description != NULL) { + // Create + TSN_SEND_PACKET(gc, "new_chat", "%s+|+%s+|+%s+|+global", name, + description, keywords); + } else { + // Join + TSN_SEND_PACKET(gc, "join_chat", "%s", name); + } + } + + //Called when a user leaves a chat + static void tsn_chat_leave(GaimConnection *gc, int id) + { + GaimConversation *c = gaim_find_chat(gc, id); + if (!c) + return; + TSN_SEND_PACKET(gc, "leave_chat", "%s",c->name); + } + + + // Callback for search + static void tsn_search_for_user_cb(GaimConnection *gc, const char *entry) + { + TSN_SEND_PACKET(gc, "find_user", "%s", entry); + } + + + // Called when the user wants to search for another user + static void tsn_search_for_user(GaimPluginAction *action) + { + GaimConnection *gc; + gc = (GaimConnection *) action->context; + gaim_request_input(gc, + NULL, + _("Search for user"), + _("Look for:"), + NULL, + FALSE, + FALSE, + NULL,_("Search"), + G_CALLBACK(tsn_search_for_user_cb), + _("Cancel"), + NULL, + gc); + } + + + //Called when a user initiates a new chat, responsible for starting the chat + static void tsn_initiate_chat_cb(GaimConnection *gc, + GaimRequestFields *fields) + { + const gchar *name, *description, *keywords; + + name = gaim_request_fields_get_string(fields, "name"); + description = gaim_request_fields_get_string(fields, "description"); + keywords = gaim_request_fields_get_string(fields, "keywords"); + + tsn_start_chat(gc, name); + + TSN_SEND_PACKET(gc, "new_chat", "%s+|+%s+|+%s+|+global", name, + description, keywords); + } + + + //Called when user initiates a new chat, responsible for starting the input requester + static void tsn_initiate_new_chat(GaimPluginAction *action) + { + GaimConnection *gc; + GaimRequestFields *fields; + GaimRequestFieldGroup *group; + GaimRequestField *field; + + gc = (GaimConnection *) action->context; + + fields = gaim_request_fields_new(); + group = gaim_request_field_group_new(NULL); + gaim_request_fields_add_group(fields, group); + + field = gaim_request_field_string_new("name", _("Name"), + "", FALSE); + + gaim_request_field_group_add_field(group, field); + + field = gaim_request_field_string_new("description", + _("Description"), + "", FALSE); + + gaim_request_field_group_add_field(group, field); + + field = gaim_request_field_string_new("keywords", + _("Keywords"), + "", FALSE); + + gaim_request_field_group_add_field(group, field); + + gaim_request_fields(gc, + _("Create new chat"), + _("Create new chat"), + _("Please describe the new chat"), + fields, + _("OK"), + G_CALLBACK(tsn_initiate_chat_cb), + _("Cancel"), + NULL, + gc); + } + + //Called when user searches for a chat, responcible for sending chat search to local server + static void tsn_search_for_chat_cb(GaimConnection *gc, const char *entry) + { + TSN_SEND_PACKET(gc, "find_chat", "global+|+%s", entry); + } + + //Called during chat search, responcible for starting the input requestor + static void tsn_search_for_chat(GaimPluginAction *action) + { + GaimConnection *gc; + gc = (GaimConnection *) action->context; + gaim_request_input(gc, NULL, _("Search for chat."), _("Write the topic you would like to chat about"),NULL, FALSE, FALSE, NULL,_("Search"), G_CALLBACK(tsn_search_for_chat_cb),_("Cancel"), NULL, gc); + } + + + + GaimRoomlist *list_local_chats(GaimConnection *gc) + { + GList *fields = NULL; + GaimRoomlistField *f; + + + // Create room list + local_chats = gaim_roomlist_new(gaim_connection_get_account(gc)); + + + // Specify layout + f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, "", "ownerid", TRUE); + fields = g_list_append(fields, f); + + + f = gaim_roomlist_field_new(GAIM_ROOMLIST_FIELD_STRING, _("Topic"), "topic", FALSE); + fields = g_list_append(fields, f); + + gaim_roomlist_set_fields(local_chats, fields); + + // TODO: Can I more elegantly solve this??? + if (!ALREADY_LOOKING) { + TSN_SEND_PACKET(gc, "find_chat", "local"); + } + + //rl->proto_data = g_list_append(rl->proto_data, yrl); + + gaim_roomlist_set_in_progress(local_chats, TRUE); + + return local_chats; + } + + + //Called when users try to search for all chats on local network + static void tsn_search_for_local_chats(GaimPluginAction *action) + { + GaimConnection *gc; + gc = (GaimConnection *) action->context; + TSN_SEND_PACKET(gc, "find_chat", "local"); + } + + //This method describes witch actions are available on this account, + //and witch function should be called to handle the specific actions + static GList * tsn_actions(GaimPlugin *plugin, gpointer context) + { + GList *m = NULL; + GaimPluginAction *act; + + act = gaim_plugin_action_new(_("Search for users"),tsn_search_for_user); + m = g_list_append(m, act); + + act = gaim_plugin_action_new(_("Initiate new chat"),tsn_initiate_new_chat); + m = g_list_append(m, act); + + act = gaim_plugin_action_new(_("Search for chat"),tsn_search_for_chat); + m = g_list_append(m, act); + + return m; + } + + static GaimPlugin *my_protocol = NULL; + + //Describes witch function should be called to handle a spesific type of event + static GaimPluginProtocolInfo prpl_info = + { + 0, + NULL, /* user_splits */ + NULL, /* protocol_options */ + NO_BUDDY_ICONS, /* icon_spec */ + tsn_list_icon, /* list_icon */ + tsn_list_emblems, /* list_emblems */ + NULL, /* status_text */ + NULL, /* tooltip_text */ + NULL, /* away_states */ + NULL, /* blist_node_menu */ + tsn_chat_info, /* chat_info */ + NULL, /* chat_info_defaults */ + tsn_login, /* login */ + tsn_close, /* close */ + tsn_send_im, /* send_im */ + NULL, /* set_info */ + NULL, /* send_typing */ + tsn_get_info, /* get_info */ + NULL, /* set_away */ + NULL, /* set_idle */ + NULL, /* change_passwd */ + tsn_add_buddy, /* add_buddy */ + tsn_add_buddies, /* add_buddies */ + tsn_remove_buddy, /* remove_buddy */ + NULL, /* remove_buddies */ + NULL, /* add_permit */ + NULL, /* add_deny */ + NULL, /* rem_permit */ + NULL, /* rem_deny */ + NULL, /* set_permit_deny */ + NULL, /* warn */ + tsn_chat_join, /* join_chat */ + NULL, /* reject chat invite */ + NULL, /* chat_invite */ + NULL, + tsn_chat_leave, /* chat_leave */ + NULL, /* chat_whisper */ + tsn_chat_send, /* chat_send */ + NULL, /* keepalive */ + NULL, /* register_user */ + NULL, /* get_cb_info */ + NULL, /* get_cb_away */ + NULL, /* alias_buddy */ + NULL, /* group_buddy */ + NULL, /* rename_group */ + NULL, /* buddy_free */ + NULL, /* convo_closed */ + NULL, /* normalize */ + NULL, /* set_buddy_icon */ + NULL, /* remove_group */ + NULL, /* get_cb_real_name */ + NULL, /* set_chat_topic */ + NULL, /* find_blist_chat */ + list_local_chats, /* roomlist_get_list */ + NULL, /* roomlist_cancel */ + NULL, /* roomlist_expand_category */ + NULL, /* can_receive_file */ + NULL /* send_file */ + }; + + static GaimPluginInfo info = + { + GAIM_PLUGIN_MAGIC, + GAIM_MAJOR_VERSION, + GAIM_MINOR_VERSION, + + GAIM_PLUGIN_PROTOCOL, /**< type */ + NULL, /**< ui_requirement */ + 0, /**< flags */ + NULL, /**< dependencies */ + GAIM_PRIORITY_DEFAULT, /**< priority */ + "prpl-tsn", /**< id */ + "TSN", /**< name */ + VERSION, /**< version */ + /** summary */ + N_("TSN Protocol Plugin"), + /** description */ + N_("TSN Protocol Plugin"), + N_("Njaal Borch"), /**< author */ + N_("http://the.socialized.net"), /**< homepage */ + + NULL, /**< load */ + NULL, /**< unload */ + NULL, /**< destroy */ + + NULL, /**< ui_info */ + &prpl_info, /**< extra_info */ + NULL, + tsn_actions + }; + + //This function is called during startup, responcible for setting up initial data + static void init_plugin(GaimPlugin *plugin) + { + GaimAccountOption *option; + + option = gaim_account_option_string_new(_("Keywords"), "keywords", ""); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, + option); + + + option = gaim_account_option_string_new(_("Server"), "server", + TSN_SERVER); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, + option); + + option = gaim_account_option_int_new(_("Port"), "port", 8888); + prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, + option); + + my_protocol = plugin; + } + + GAIM_INIT_PLUGIN(tsn, init_plugin, info);