#include "gtkyahoo.h" /* Maybe I should put these in a "private" header file */ static void on_chat_activate(GtkEditable * editable, gpointer user_data); static void on_send_clicked(GtkButton * button, gpointer user_data); static void on_close_clicked(GtkButton * button, gpointer user_data); static void on_invitemore_clicked(GtkButton * button, gpointer user_data); static gboolean on_conf_delete_event(GtkWidget * widget, GdkEvent * event, gpointer user_data); static void conf_msg(char *conf_id, char *sender, char *message, GtkWindow * window); static GtkWidget *create_conference_window(void); /* static data */ static GHashTable *conf_hash = NULL; /***************************************************************************/ /* Implementation (local) functions */ /***************************************************************************/ inline GHashTable *conf_get_hash() { if (NULL == conf_hash) conf_hash = g_hash_table_new(g_str_hash, g_str_equal); return conf_hash; } static void conf_msg(char *conf_id, char *sender, char *message, GtkWindow * window) { char *coloured_user = NULL, *colour = NULL; int coloured_user_len = -1; GtkText *blah = NULL; if (0L == ((long) conf_id | (long) sender | (long) message | (long) colour | (long) window)) return; if (0 == strcmp(sender, current_user)) { colour = YAHOO_COLOR_BLACK; } else { colour = YAHOO_COLOR_BLUE; } blah = GTK_TEXT(gtk_object_get_data(GTK_OBJECT(window), "blah")); if (show_timestamp) append_to_textbox(GTK_WIDGET(window), GTK_WIDGET(blah), make_timestamp()); coloured_user_len = (strlen(sender) + strlen(YAHOO_STYLE_BOLDON) + strlen(YAHOO_STYLE_BOLDOFF) + strlen(colour) + 4); coloured_user = (char *) malloc(coloured_user_len); (void) snprintf(coloured_user, coloured_user_len, "%s%s%s%s: ", YAHOO_STYLE_BOLDON, colour, sender, YAHOO_STYLE_BOLDOFF); append_to_textbox(GTK_WIDGET(window), GTK_WIDGET(blah), coloured_user); free(coloured_user); coloured_user = NULL; coloured_user_len = -1; append_to_textbox(GTK_WIDGET(window), GTK_WIDGET(blah), message); append_to_textbox(GTK_WIDGET(window), GTK_WIDGET(blah), "\n"); gdk_window_raise(GTK_WIDGET(window)->window); } void conference_incomming(char *conf_id, char *sender, char *message) { if (0 != strcmp(sender, current_user)) { GtkWindow *window = (GtkWindow *) g_hash_table_lookup(conf_get_hash(), (gconstpointer) conf_id); if (NULL != window) conf_msg(conf_id, sender, message, window); else DBG_Print("conference", "received message \"%s\" from \"%s\" for conference \"%s\" but couldn't find an open conference window!", message, sender, conf_id); } else { DBG_Print("conference", "Ignoring echo of my own message!"); } } static GtkWidget *create_conference_window(void) { GtkWidget *conf; GtkWidget *conf_halves; GtkWidget *conf_top; GtkWidget *blah_scr; GtkWidget *blah; GtkWidget *attendees_scr; GtkWidget *attendees; GtkWidget *attendees_lbl; GtkWidget *conf_bottom; GtkWidget *chat; GtkWidget *hbox1; GtkWidget *hbuttonbox5; GtkWidget *invitemore; GtkWidget *hbuttonbox4; GtkWidget *send; GtkWidget *close; GtkTooltips *tooltips; tooltips = gtk_tooltips_new(); conf = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_object_set_data(GTK_OBJECT(conf), "conf", conf); gtk_window_set_title(GTK_WINDOW(conf), "Conference:"); conf_halves = gtk_vbox_new(FALSE, 0); gtk_widget_ref(conf_halves); gtk_object_set_data_full(GTK_OBJECT(conf), "conf_halves", conf_halves, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(conf_halves); gtk_container_add(GTK_CONTAINER(conf), conf_halves); gtk_container_set_border_width(GTK_CONTAINER(conf_halves), 2); conf_top = gtk_hbox_new(FALSE, 0); gtk_widget_ref(conf_top); gtk_object_set_data_full(GTK_OBJECT(conf), "conf_top", conf_top, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(conf_top); gtk_box_pack_start(GTK_BOX(conf_halves), conf_top, TRUE, TRUE, 0); blah_scr = gtk_scrolled_window_new(NULL, NULL); gtk_widget_ref(blah_scr); gtk_object_set_data_full(GTK_OBJECT(conf), "blah_scr", blah_scr, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(blah_scr); gtk_box_pack_start(GTK_BOX(conf_top), blah_scr, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(blah_scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); blah = gtk_text_new(NULL, NULL); gtk_widget_ref(blah); gtk_object_set_data_full(GTK_OBJECT(conf), "blah", blah, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(blah); gtk_container_add(GTK_CONTAINER(blah_scr), blah); gtk_widget_set_usize(blah, 317, 242); gtk_tooltips_set_tip(tooltips, blah, "These are the messages left by the other attendees", NULL); attendees_scr = gtk_scrolled_window_new(NULL, NULL); gtk_widget_ref(attendees_scr); gtk_object_set_data_full(GTK_OBJECT(conf), "attendees_scr", attendees_scr, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(attendees_scr); gtk_box_pack_start(GTK_BOX(conf_top), attendees_scr, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(attendees_scr), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); attendees = gtk_clist_new(1); gtk_widget_ref(attendees); gtk_object_set_data_full(GTK_OBJECT(conf), "attendees", attendees, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(attendees); gtk_container_add(GTK_CONTAINER(attendees_scr), attendees); gtk_widget_set_usize(attendees, 93, -2); gtk_tooltips_set_tip(tooltips, attendees, "The other attendees of this conference", NULL); gtk_clist_set_column_width(GTK_CLIST(attendees), 0, 80); gtk_clist_column_titles_hide(GTK_CLIST(attendees)); attendees_lbl = gtk_label_new("Attendees"); gtk_widget_ref(attendees_lbl); gtk_object_set_data_full(GTK_OBJECT(conf), "attendees_lbl", attendees_lbl, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(attendees_lbl); gtk_clist_set_column_widget(GTK_CLIST(attendees), 0, attendees_lbl); conf_bottom = gtk_vbox_new(FALSE, 0); gtk_widget_ref(conf_bottom); gtk_object_set_data_full(GTK_OBJECT(conf), "conf_bottom", conf_bottom, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(conf_bottom); gtk_box_pack_start(GTK_BOX(conf_halves), conf_bottom, FALSE, FALSE, 0); chat = gtk_entry_new(); gtk_widget_ref(chat); gtk_object_set_data_full(GTK_OBJECT(conf), "chat", chat, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(chat); gtk_box_pack_start(GTK_BOX(conf_bottom), chat, FALSE, FALSE, 0); gtk_tooltips_set_tip(tooltips, chat, "Enter your messages here", NULL); hbox1 = gtk_hbox_new(FALSE, 0); gtk_widget_ref(hbox1); gtk_object_set_data_full(GTK_OBJECT(conf), "hbox1", hbox1, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(hbox1); gtk_box_pack_start(GTK_BOX(conf_bottom), hbox1, TRUE, TRUE, 0); hbuttonbox5 = gtk_hbutton_box_new(); gtk_widget_ref(hbuttonbox5); gtk_object_set_data_full(GTK_OBJECT(conf), "hbuttonbox5", hbuttonbox5, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(hbuttonbox5); gtk_box_pack_start(GTK_BOX(hbox1), hbuttonbox5, FALSE, FALSE, 0); invitemore = gtk_button_new_with_label("Invite"); gtk_widget_ref(invitemore); gtk_object_set_data_full(GTK_OBJECT(conf), "invitemore", invitemore, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(invitemore); gtk_container_add(GTK_CONTAINER(hbuttonbox5), invitemore); GTK_WIDGET_SET_FLAGS(invitemore, GTK_CAN_DEFAULT); hbuttonbox4 = gtk_hbutton_box_new(); gtk_widget_ref(hbuttonbox4); gtk_object_set_data_full(GTK_OBJECT(conf), "hbuttonbox4", hbuttonbox4, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(hbuttonbox4); gtk_box_pack_start(GTK_BOX(hbox1), hbuttonbox4, TRUE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox4), GTK_BUTTONBOX_END); send = gtk_button_new_with_label("Send"); gtk_widget_ref(send); gtk_object_set_data_full(GTK_OBJECT(conf), "send", send, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(send); gtk_container_add(GTK_CONTAINER(hbuttonbox4), send); GTK_WIDGET_SET_FLAGS(send, GTK_CAN_DEFAULT); close = gtk_button_new_with_label("Close"); gtk_widget_ref(close); gtk_object_set_data_full(GTK_OBJECT(conf), "close", close, (GtkDestroyNotify) gtk_widget_unref); gtk_widget_show(close); gtk_container_add(GTK_CONTAINER(hbuttonbox4), close); GTK_WIDGET_SET_FLAGS(close, GTK_CAN_DEFAULT); gtk_signal_connect(GTK_OBJECT(conf), "delete_event", GTK_SIGNAL_FUNC(on_conf_delete_event), NULL); gtk_signal_connect(GTK_OBJECT(chat), "activate", GTK_SIGNAL_FUNC(on_chat_activate), conf); gtk_signal_connect(GTK_OBJECT(invitemore), "clicked", GTK_SIGNAL_FUNC(on_invitemore_clicked), conf); gtk_signal_connect(GTK_OBJECT(send), "clicked", GTK_SIGNAL_FUNC(on_send_clicked), conf); gtk_signal_connect(GTK_OBJECT(close), "clicked", GTK_SIGNAL_FUNC(on_close_clicked), conf); gtk_widget_grab_focus(chat); gtk_object_set_data(GTK_OBJECT(conf), "tooltips", tooltips); return conf; } static void on_chat_activate(GtkEditable * editable, gpointer user_data) { GtkWindow *window = GTK_WINDOW(user_data); char *userlist = NULL, **userarray = NULL, *msg = NULL, *conf_id = NULL; userlist = gtk_object_get_data(GTK_OBJECT(window), "userlist"); userarray = yahoo_list2array(userlist); conf_id = gtk_object_get_data(GTK_OBJECT(window), "conf_id"); conf_msg(conf_id, current_user, msg = gtk_editable_get_chars(editable, 0, -1), window); DBG_Print("conference", "Sending message \"%s\" to conference \"%s\"", msg, conf_id); yahoo_cmd_conf_msg(context, conf_id, userarray, msg); yahoo_arraykill(userarray); gtk_editable_delete_text(editable, 0, -1); } static void on_send_clicked(GtkButton * button, gpointer user_data) { GtkEditable *editable = GTK_EDITABLE(gtk_object_get_data(GTK_OBJECT(user_data), "chat")); on_chat_activate(editable, user_data); } static void close_conference(GtkWindow * window) { char *userlist = NULL, **userarray = NULL, *conf_id = NULL; DBG_Print("conference", "Bye-bye conference window!"); conf_id = (char *) gtk_object_get_data(GTK_OBJECT(window), "conf_id"); userlist = (char *) gtk_object_get_data(GTK_OBJECT(window), "userlist"); userarray = yahoo_list2array(userlist); free(userlist); yahoo_cmd_conf_logoff(context, conf_id, userarray); yahoo_arraykill(userarray); g_hash_table_remove(conf_get_hash(), conf_id); gtk_widget_destroy(GTK_WIDGET(window)); } static void on_close_clicked(GtkButton * button, gpointer user_data) { close_conference(GTK_WINDOW(user_data)); } static void on_invitemore_clicked(GtkButton * button, gpointer user_data) { } static gboolean on_conf_delete_event(GtkWidget * widget, GdkEvent * event, gpointer user_data) { close_conference(GTK_WINDOW(widget)); return FALSE; } /***************************************************************************/ /* Interface (global) functions */ /***************************************************************************/ void conference_join_existing(char *hosted_by, char **other_invitees, char *inticement) { } void conference_start_new(void) { } GtkWidget *create_conference(char *hosted_by, char *host, char **invited, char *message) { gchar title1[] = "Conference: ", *title = NULL; int title_length = 0; GtkCList *attendees = NULL; GtkWidget *conf = create_conference_window(); attendees = GTK_CLIST(gtk_object_get_data(GTK_OBJECT(conf), "attendees")); title = (gchar *) malloc(title_length = (strlen(title1) + strlen(hosted_by) + 1)); (void) snprintf(title, title_length, "%s%s", title1, hosted_by); gtk_window_set_title(GTK_WINDOW(conf), title); if (invited) { gchar *invitee = NULL, *row[] = { host, NULL }; int i = 0; gtk_clist_freeze(attendees); gtk_clist_set_selectable(attendees, gtk_clist_append(attendees, row), FALSE); while (NULL != (invitee = invited[i++])) { row[0] = invitee; gtk_clist_set_selectable(attendees, gtk_clist_append(attendees, row), FALSE); } /* I haven't got "add the host here yet!!!" */ gtk_clist_thaw(attendees); } { int len = 0; char *userlist = NULL, *invitees = yahoo_array2list(invited); userlist = (char *) malloc(len = (strlen(invitees) + 2 + strlen(host))); (void) snprintf(userlist, len, "%s,%s", invitees, host); free(invitees); invitees = NULL; gtk_object_set_data(GTK_OBJECT(conf), "userlist", userlist); } gtk_object_set_data(GTK_OBJECT(conf), "conf_id", hosted_by); g_hash_table_insert(conf_get_hash(), g_strdup(hosted_by), conf); gtk_widget_show(conf); return conf; }