Mercurial > pidgin
diff plugins/crazychat/cc_gaim_plugin.c @ 11218:ed017b9c532d
[gaim-migrate @ 13350]
crazychat commit, first one.
committer: Tailor Script <tailor@pidgin.im>
author | Charlie Stockman <chuckleberry> |
---|---|
date | Tue, 09 Aug 2005 07:10:23 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/crazychat/cc_gaim_plugin.c Tue Aug 09 07:10:23 2005 +0000 @@ -0,0 +1,482 @@ +#include <stdio.h> +#include <assert.h> +#include <internal.h> +#include <plugin.h> +#include <gtkplugin.h> +#include <gtkblist.h> +#include <gtkutils.h> +#include <connection.h> +#include <conversation.h> +#include <network.h> +#include <gtk/gtkgl.h> +#include <GL/gl.h> +#include <GL/glu.h> +#include "crazychat.h" +#include "cc_network.h" +#include "cc_interface.h" +#include "cc_gtk_gl.h" +#include "util.h" + +/* --- begin type and global variable definitions --- */ + +static struct crazychat cc_info; + +/* --- begin function declarations --- */ + +/** + * Called by gaim plugin to start CrazyChat + * @param cc the crazychat struct + */ +static void cc_init(struct crazychat *cc); + +/** + * Called by gaim plugin to destroy CrazyChat + * @param cc the crazychat struct + */ +static void cc_destroy(struct crazychat *cc); + + +/** + * Buddy menu drawing callback. Adds a CrazyChat menuitem. + * @param menu the buddy menu widget + * @param b the buddy whose menu this is + */ +static gboolean cc_buddy_menu(GtkWidget *menu, GaimBuddy *b); + +/** + * Buddy menu callback. Initiates the CrazyChat session. + * @param item the gtk buddy menu item + * @param b the buddy whose menu the item was in + */ +static void cc_menu_cb(GtkMenuItem *item, GaimBuddy *b); + +/** + * IM callback. Handles receiving a CrazyChat session request. + * @param account the account we received the IM on + * @param sender the buddy who we received the message from + * @param message the message we received + * @param flags IM flags + * @param data user data + */ +static gboolean receive_im_cb(GaimAccount *account, char **sender, + char **message, int *flags, void *data); + +/** + * Displaying IM callback. Drops CrazyChat messages from IM window. + * @param account the account we are displaying the IM on + * @param conv the conversation we are displaying the IM on + * @param message the message we are displaying + * @param data user data + */ +static gboolean display_im_cb(GaimAccount *account, GaimConversation *conv, + char **message, void *data); + +/** + * Callback for CrazyChat plugin configuration frame + * @param plugin the plugin data + * @return the configuration frame + */ +static GtkWidget *get_config_frame(GaimPlugin *plugin); + +/** + * TCP port callback. Changes the port used to listen for new CC sessions + * @param spin the spinner button whose value changed + * @param data user data + */ +static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc); + +/** + * UDP port callback. Changes the port used to send/recv CC session frames + * @param spin the spinner button whose value changed + * @param data user data + */ +static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc); + +/** + * Features enabling/disabling callback. Initializes the input processing + * or shuts it down. + * @param data user data + */ +static void features_enable_cb(struct crazychat *cc); + +/** + * User signed on callback. Now we have a buddy list to connect a signal + * handler to. + * @param gc the gaim connection we are signed on + * @param plugin our plugin struct + */ +static gboolean cc_signed_on(GaimConnection *gc, void *plugin); + +/** + * Plugin loading callback. If a buddy list exists, connect our buddy menu + * drawing callback to the signal handler, otherwise, connect a signed on + * signal handler so we know when we get a buddy list. + * @param plugin our plugin struct + */ +static gboolean plugin_load(GaimPlugin *plugin); + +/** + * Plugin unloading callback. Disconnect all handlers and free data. + * @param plugin our plugin struct + */ +static gboolean plugin_unload(GaimPlugin *plugin); + + +/* --- end function declarations --- */ + + +#define CRAZYCHAT_PLUGIN_ID "gtk-crazychat" + +static GaimGtkPluginUiInfo ui_info = { + get_config_frame /**< get_config_frame */ +}; + +static GaimPluginInfo info = { + 2, /**< api_version */ + GAIM_PLUGIN_STANDARD, /**< type */ + GAIM_GTK_PLUGIN_TYPE, /**< ui_requirement */ + 0, /**< flags */ + NULL, /**< dependencies */ + GAIM_PRIORITY_DEFAULT, /**< priority */ + + CRAZYCHAT_PLUGIN_ID, /**< id */ + N_("Crazychat"), /**< name */ + VERSION, /**< version */ + /** summary */ + N_("Plugin to establish a Crazychat session."), + /** description */ + N_("Uses Gaim to obtain buddy ips to connect for a Crazychat session"), + "\n" + "William Chan <chanman@stanford.edu>\n" + "Ian Spiro <ispiro@stanford.edu>\n" + "Charlie Stockman<stockman@stanford.edu>\n" + "Steve Yelderman<scy@stanford.edu>", /**< author */ + GAIM_WEBSITE, /**< homepage */ + + plugin_load, /**< load */ + plugin_unload, /**< unload */ + NULL, /**< destroy */ + + &ui_info, /**< ui_info */ + &cc_info /**< extra_info */ +}; + +/* --- end plugin struct definition --- */ + +static void cc_init(struct crazychat *cc) +{ + /* initialize main crazychat thread */ + + assert(cc); + memset(cc, 0, sizeof(*cc)); + + /* initialize network configuration */ + cc->tcp_port = DEFAULT_CC_PORT; + cc->udp_port = DEFAULT_CC_PORT; + + /* disable input subsystem */ + //cc->features_state = 0; + + /* initialize input subsystem */ + cc->features_state = 1; + cc->input_data = init_input(cc); +} + +static void cc_destroy(struct crazychat *cc) +{ + assert(cc); + + if (cc->features_state) { + destroy_input(cc->input_data); + } + memset(cc, 0, sizeof(*cc)); +} + +static gboolean cc_buddy_menu(GtkWidget *menu, GaimBuddy *b) +{ + GtkWidget *menuitem; + + menuitem = gtk_menu_item_new_with_mnemonic("CrazyChat"); + g_signal_connect(G_OBJECT(menuitem), "activate", + G_CALLBACK(cc_menu_cb), b); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + return FALSE; +} + +static void cc_menu_cb(GtkMenuItem *item, GaimBuddy *b) +{ + assert(item); + assert(b); + + /* send the invite */ + cc_net_send_invite(&cc_info, b->name, b->account); +} + +static gboolean receive_im_cb(GaimAccount *account, char **sender, + char **message, int *flags, void *data) +{ + struct crazychat *cc; + + cc = (struct crazychat*)data; + assert(cc); + if (!strncmp(*message, CRAZYCHAT_INVITE_CODE, + strlen(CRAZYCHAT_INVITE_CODE))) { + Debug(*message); + char *split = strchr(*message, '!'); + assert(split); + *split = 0; + split++; + cc_net_recv_invite(account, cc, *sender, + &(*message)[strlen(CRAZYCHAT_INVITE_CODE)], + split); + return TRUE; + } else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE, + strlen(CRAZYCHAT_ACCEPT_CODE))) { + cc_net_recv_accept(account, cc, *sender, + &(*message)[strlen(CRAZYCHAT_ACCEPT_CODE)]); + return TRUE; + } else if (!strncmp(*message, CRAZYCHAT_READY_CODE, + strlen(CRAZYCHAT_READY_CODE))) { + cc_net_recv_ready(account, cc, *sender); + return TRUE; + } + + return FALSE; +} + +static gboolean display_im_cb(GaimAccount *account, GaimConversation *conv, + char **message, void *data) +{ + struct crazychat *cc; + + cc = (struct crazychat*)data; + assert(cc); + if (!strncmp(*message, CRAZYCHAT_INVITE_CODE, + strlen(CRAZYCHAT_INVITE_CODE))) { + return TRUE; + } else if (!strncmp(*message, CRAZYCHAT_ACCEPT_CODE, + strlen(CRAZYCHAT_ACCEPT_CODE))) { + return TRUE; + } else if (!strncmp(*message, CRAZYCHAT_READY_CODE, + strlen(CRAZYCHAT_READY_CODE))) { + return TRUE; + } + + return FALSE; +} + +static GtkWidget *get_config_frame(GaimPlugin *plugin) +{ + GtkWidget *ret; + GtkWidget *frame; + GtkWidget *vbox, *hbox; + GtkWidget *drawing_area; + GtkWidget *label; + GtkAdjustment *adj; + GtkWidget *spinner; + GtkWidget *button, *button1, *button2; + GSList *group; + struct draw_info *info; + struct crazychat *cc; + + cc = (struct crazychat*)plugin->info->extra_info; + assert(cc); + + /* create widgets */ + + /* creating the config frame */ + ret = gtk_vbox_new(FALSE, 18); + gtk_container_set_border_width(GTK_CONTAINER(ret), 12); + + /* make the network configuration frame */ + frame = gaim_gtk_make_frame(ret, _("Network Configuration")); + gtk_widget_show(frame); + + /* add boxes for packing purposes */ + vbox = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(frame), vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + /* add widgets to row 1 */ + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show(hbox); + label = gtk_label_new(_("TCP port")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15); + gtk_widget_show(label); + adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1, + G_MAXUSHORT, 1, 1000, 0); + spinner = gtk_spin_button_new(adj, 1, 0); + g_signal_connect(G_OBJECT(spinner), "value_changed", + G_CALLBACK(tcp_port_cb), cc); + gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); + gtk_widget_show(spinner); + label = gtk_label_new(_("UDP port")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15); + gtk_widget_show(label); + adj = (GtkAdjustment*)gtk_adjustment_new(DEFAULT_CC_PORT, 1, + G_MAXUSHORT, 1, 1000, 0); + spinner = gtk_spin_button_new(adj, 1, 0); + g_signal_connect(G_OBJECT(spinner), "value_changed", + G_CALLBACK(udp_port_cb), cc); + gtk_box_pack_start(GTK_BOX(hbox), spinner, FALSE, FALSE, 0); + gtk_widget_show(spinner); + + /* make the feature configuration frame */ + frame = gaim_gtk_make_frame(ret, _("Feature Calibration")); + gtk_widget_show(frame); + + /* add hbox for packing purposes */ + hbox = gtk_hbox_new(TRUE, 40); + gtk_box_pack_start(GTK_BOX(frame), hbox, TRUE, TRUE, 0); + gtk_widget_show(hbox); + + /* add feature calibration options */ + + /* add vbox for packing purposes */ + vbox = gtk_vbox_new(TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + /* add enabled / disabled */ + button1 = gtk_radio_button_new_with_label(NULL, _("Enabled")); + gtk_box_pack_start(GTK_BOX(vbox), button1, TRUE, TRUE, 0); + gtk_widget_show(button1); + + group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button1)); + button2 = gtk_radio_button_new_with_label(group, _("Disabled")); + gtk_box_pack_start(GTK_BOX(vbox), button2, TRUE, TRUE, 0); + gtk_widget_show(button2); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button1), + cc->features_state); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button2), + !cc->features_state); + g_signal_connect_swapped(G_OBJECT(button1), "toggled", + G_CALLBACK(features_enable_cb), cc); + + /* add vbox for packing purposes */ + vbox = gtk_vbox_new(TRUE, 0); + gtk_box_pack_end(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show(vbox); + + /* add calibrate button */ + button = gtk_button_new_with_label("Calibrate"); + gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, FALSE, 0); + gtk_widget_show(button); + + gtk_widget_show(ret); + + return ret; +} + +static void tcp_port_cb(GtkSpinButton *spin, struct crazychat *cc) +{ + assert(spin); + assert(cc); + cc->tcp_port = gtk_spin_button_get_value_as_int(spin); + Debug("New tcp port: %d\n", cc->tcp_port); +} + +static void udp_port_cb(GtkSpinButton *spin, struct crazychat *cc) +{ + assert(spin); + assert(cc); + cc->udp_port = gtk_spin_button_get_value_as_int(spin); + Debug("New udp port: %d\n", cc->udp_port); +} + +static void features_enable_cb(struct crazychat *cc) +{ + Debug("Changing features state\n"); + cc->features_state = !cc->features_state; + if (cc->features_state) { + cc->input_data = init_input(cc); + } else { + if (cc->input_data) { + gtk_widget_destroy(cc->input_data->widget); + } + } +} + +static gboolean cc_signed_on(GaimConnection *gc, void *plugin) +{ + struct crazychat *extra; + void *conv_handle; + + assert(plugin); + extra = (struct crazychat*)((GaimPlugin*)plugin)->info->extra_info; + gaim_signal_disconnect + (gaim_connections_get_handle(), "signed-on", + plugin, GAIM_CALLBACK(cc_signed_on)); + gaim_signal_connect(GAIM_GTK_BLIST + (gaim_get_blist()), + "drawing-menu", plugin, + GAIM_CALLBACK(cc_buddy_menu), NULL); + conv_handle = gaim_conversations_get_handle(); + gaim_signal_connect(conv_handle, "received-im-msg", plugin, + GAIM_CALLBACK(receive_im_cb), extra); + gaim_signal_connect(conv_handle, "displaying-im-msg", plugin, + GAIM_CALLBACK(display_im_cb), extra); + return FALSE; +} + +static gboolean plugin_load(GaimPlugin *plugin) +{ + GaimBuddyList *buddy_list; + void *conv_handle; + + if (cc_init_gtk_gl()) + return FALSE; + + cc_init(&cc_info); + buddy_list = gaim_get_blist(); + if (buddy_list) { + gaim_signal_connect(GAIM_GTK_BLIST + (buddy_list), + "drawing-menu", plugin, + GAIM_CALLBACK(cc_buddy_menu), NULL); + conv_handle = gaim_conversations_get_handle(); + gaim_signal_connect(conv_handle, "received-im-msg", plugin, + GAIM_CALLBACK(receive_im_cb), &cc_info); + gaim_signal_connect(conv_handle, "displaying-im-msg", plugin, + GAIM_CALLBACK(display_im_cb), &cc_info); + } else { + gaim_signal_connect + (gaim_connections_get_handle(), "signed-on", + plugin, GAIM_CALLBACK(cc_signed_on), plugin); + } + + Debug("CrazyChat plugin loaded.\n"); + + return TRUE; +} + +static gboolean plugin_unload(GaimPlugin *plugin) +{ + void *conv_handle; + struct crazychat *extra; + assert(plugin); + extra = (struct crazychat*) plugin->info->extra_info; + cc_destroy(extra); + conv_handle = gaim_conversations_get_handle(); + gaim_signal_disconnect(GAIM_GTK_BLIST + (gaim_get_blist()), + "drawing-menu", plugin, + GAIM_CALLBACK(cc_buddy_menu)); + gaim_signal_disconnect(conv_handle, "received-im", plugin, + GAIM_CALLBACK(receive_im_cb)); + gaim_signal_disconnect(conv_handle, "displaying-im-msg", plugin, + GAIM_CALLBACK(display_im_cb)); + Debug("CrazyChat plugin unloaded.\n"); + return TRUE; +} + +static void init_plugin(GaimPlugin *plugin) +{ + gtk_gl_init(NULL, NULL); + memset(&cc_info, 0, sizeof(cc_info)); + Debug("CrazyChat plugin initialized\n"); +} + +GAIM_INIT_PLUGIN(crazychat, init_plugin, info)