[c++]代码库
/***************************************************************************
* Copyright (C) 2010 by lwp *
* levin108@gmail.com *
* *
* 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 "fx_include.h"
#ifdef USE_GSTREAMER
#include <gst/gst.h>
#endif
#include <glib/gi18n.h>
#include <sys/select.h>
#include <locale.h>
#include <glib.h>
fd_set fd_read;
gint presence_count = 0;
gint window_pos_x;
gint window_pos_y;
gint window_pos_x_old = 0;
gint window_pos_y_old = 0;
gint start_popup_presence = 0;
extern struct unacked_list *unackedlist;
GStaticMutex mutex = G_STATIC_MUTEX_INIT;
GdkScreen *current_screen;
static void fx_main_process_pggetgroupinfo(FxMain *fxmain , const gchar *sipmsg);
static void fx_main_process_pgpresencechanged(FxMain *fxmain , const gchar *sipmsg);
static gboolean key_press_func(GtkWidget *widget , GdkEventKey *event
, gpointer data);
FxMain *fx_main_new() {
FxMain *fxmain = (FxMain *)malloc(sizeof(FxMain));
memset(fxmain , 0 , sizeof(FxMain));
fxmain->clist = fx_list_new(NULL);
fxmain->mlist = fx_list_new(NULL);
fxmain->slist = fx_list_new(NULL);
fxmain->tlist = fx_list_new(NULL);
fxmain->shlist = fx_list_new(NULL);
fxmain->pglist = fx_list_new(NULL);
return fxmain;
}
#if 0
static void fx_main_position_func(GtkWidget *UNUSED(widget) , GdkEventConfigure *event ,
gpointer UNUSED(user_data)) {
window_pos_x = event->x;
window_pos_y = event->y;
}
#endif
void fx_main_initialize(FxMain *fxmain) {
int window_width , window_height;
Config *config;
fxmain->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name(fxmain->window , "mainwindow");
gtk_window_set_title(GTK_WINDOW(fxmain->window) , "OpenFetion");
current_screen = gdk_screen_get_default();
config = fetion_config_new();
fetion_config_load_size(config);
if(config->window_width == 0) {
window_width = gdk_screen_get_width(current_screen);
window_height = gdk_screen_get_height(current_screen);
window_pos_x = window_width - WINDOW_WIDTH - 200;
window_pos_y = (window_height - WINDOW_HEIGHT) / 2;
} else {
window_pos_x = config->window_pos_x;
window_pos_y = config->window_pos_y;
}
fetion_config_free(config);
gtk_window_move(GTK_WINDOW(fxmain->window) , window_pos_x , window_pos_y);
gtk_container_set_border_width(GTK_CONTAINER(fxmain->window) , 0);
g_signal_connect(G_OBJECT(fxmain->window)
, "delete-event"
, G_CALLBACK(fx_main_delete)
, fxmain);
g_signal_connect(G_OBJECT(fxmain->window)
, "key-press-event"
, G_CALLBACK(key_press_func)
, fxmain);
g_signal_connect(G_OBJECT(fxmain->window)
, "destroy"
, G_CALLBACK(fx_main_destroy)
, fxmain);
g_signal_connect(G_OBJECT(fxmain->window)
, "window-state-event"
, G_CALLBACK(fx_main_window_state_func)
, fxmain);
#if 0
g_signal_connect(G_OBJECT(fxmain->window)
, "configure-event"
, G_CALLBACK(fx_main_position_func)
, NULL);
#endif
gtk_window_set_default_size(
GTK_WINDOW(fxmain->window),
WINDOW_WIDTH , WINDOW_HEIGHT);
GdkPixbuf *icon = gdk_pixbuf_new_from_file_at_size(
SKIN_DIR"fetion.svg" , 48 , 48 , NULL);
gtk_window_set_icon(GTK_WINDOW(fxmain->window) , icon);
fxmain->trayIcon = gtk_status_icon_new_from_file(
SKIN_DIR"offline.svg");
gtk_status_icon_set_tooltip(fxmain->trayIcon, "OpenFetion");
#ifdef USE_LIBNOTIFY
fxmain->notify = notify_notification_new_with_status_icon("welcome"
, "" , NULL , fxmain->trayIcon);
notify_notification_set_timeout(fxmain->notify , 2500);
#endif
fxmain->iconConnectId = g_signal_connect(
GTK_STATUS_ICON(fxmain->trayIcon),
"activate",
GTK_SIGNAL_FUNC(fx_main_tray_activate_func),
fxmain);
g_signal_connect(GTK_STATUS_ICON(fxmain->trayIcon),
"popup-menu",
GTK_SIGNAL_FUNC(fx_main_tray_popmenu_func),
fxmain);
fxmain->mainbox = gtk_vbox_new(FALSE , 4);
gtk_container_add(GTK_CONTAINER(fxmain->window) , fxmain->mainbox);
fxmain->loginPanel = fx_login_new();
fx_login_initialize(fxmain);
gtk_widget_show_all(fxmain->window);
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
}
void fx_main_free(FxMain *fxmain) {
if(fxmain->user != NULL)
fetion_user_free(fxmain->user);
free(fxmain);
}
void fx_main_set_user(FxMain *fxmain , User *user) {
fxmain->user = user;
}
void fx_main_history_init(FxMain *fxmain) {
fxmain->history = fetion_history_new(fxmain->user);
}
void update() {
g_usleep(1);
while(gtk_events_pending()) {
gtk_main_iteration();
}
}
TimeOutArgs *timeout_args_new(FxMain *fxmain , FetionSip *sip , const gchar *sipuri) {
TimeOutArgs *args = (TimeOutArgs *)malloc(sizeof(TimeOutArgs));
memset(args , 0 , sizeof(TimeOutArgs));
args->fxmain = fxmain;
args->sip = sip;
args->terminated = FALSE;
strcpy(args->sipuri , sipuri);
return args;
}
GtkWidget *fx_main_create_menu(const gchar *name
, const gchar *iconpath
, GtkWidget *parent
, void (*func)(GtkWidget *item , gpointer data)
, gpointer data
) {
GtkWidget *item = gtk_image_menu_item_new_with_label(name);
GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_size(iconpath , 16 , 16 , NULL);
GtkWidget *img = gtk_image_new_from_pixbuf(pb);
g_object_unref(pb);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img);
gtk_menu_shell_append(GTK_MENU_SHELL(parent) , item);
if(func != NULL)
g_signal_connect(item , "activate" , G_CALLBACK(func) , data);
return item;
}
GtkWidget *fx_main_create_menu1(const gchar *name
, const gchar *stockid
, GtkWidget *parent
, void (*func)(GtkWidget *item , gpointer data)
, gpointer data
) {
GtkWidget *item = gtk_image_menu_item_new_with_label(name);
#if 0
GtkWidget *img = gtk_image_new_from_stock(stockid , GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img);
#endif
gtk_menu_shell_append(GTK_MENU_SHELL(parent) , item);
if(func != NULL)
g_signal_connect(item , "activate" , G_CALLBACK(func) , data);
return item;
}
void fx_main_process_notification(FxMain *fxmain , const gchar *sipmsg) {
gint event;
gint notification_type;
gchar *xml;
fetion_sip_parse_notification(sipmsg , ¬ification_type , &event , &xml);
g_usleep(1);
switch(notification_type) {
case NOTIFICATION_TYPE_PRESENCE:
switch(event) {
case NOTIFICATION_EVENT_PRESENCECHANGED :
fx_main_process_presence(fxmain , xml);
break;
default:
break;
}
case NOTIFICATION_TYPE_CONVERSATION :
if(event == NOTIFICATION_EVENT_USERLEFT) {
fx_main_process_user_left(fxmain , sipmsg);
break;
}
break;
case NOTIFICATION_TYPE_REGISTRATION :
if(event == NOTIFICATION_EVENT_DEREGISTRATION) {
fx_main_process_deregistration(fxmain);
break;
}
break;
case NOTIFICATION_TYPE_SYNCUSERINFO :
if(event == NOTIFICATION_EVENT_SYNCUSERINFO) {
fx_main_process_syncuserinfo(fxmain , xml);
break;
}
break;
case NOTIFICATION_TYPE_CONTACT :
if(event == NOTIFICATION_EVENT_ADDBUDDYAPPLICATION) {
fx_main_process_addbuddyapplication(fxmain , sipmsg);
break;
}
break;
case NOTIFICATION_TYPE_PGGROUP :
if(event == NOTIFICATION_EVENT_PGGETGROUPINFO) {
fx_main_process_pggetgroupinfo(fxmain , sipmsg);
break;
}
if(event == NOTIFICATION_EVENT_PRESENCECHANGED) {
fx_main_process_pgpresencechanged(fxmain , sipmsg);
break;
}
break;
default:
break;
}
g_free(xml);
}
static void *update_data(void *data) {
FxMain *fxmain = (FxMain *)data;
User *user = fxmain->user;
fetion_user_save(user);
fetion_contact_save(user);
fx_tree_update_portrait(data);
return NULL;
}
static void popup_online_notify(FxMain *fxmain, Contact *contact) {
#ifdef USE_LIBNOTIFY
gchar notifySummary[256];
gchar notifyText[1024];
gchar iconPath[256];
GdkPixbuf *pixbuf;
Config *config;
config = fxmain->user->config;
if(start_popup_presence &&
presence_count > fxmain->user->contactCount &&
config->onlineNotify == ONLINE_NOTIFY_ENABLE) {
sprintf(iconPath , "%s/%s.jpg",
config->iconPath , contact->sId);
sprintf(notifySummary,
_("%s , now ONLINE") , contact->nickname);
sprintf(notifyText ,
_("Phone Number: %s\n"
"Fetion Number: %s\n"
"Signature: %s")
, contact->mobileno == NULL ||
strlen(contact->mobileno) == 0 ?
"未知" : contact->mobileno
, contact->sId
, contact->impression );
pixbuf = gdk_pixbuf_new_from_file_at_size(
iconPath,
NOTIFY_IMAGE_SIZE,
NOTIFY_IMAGE_SIZE , NULL);
if(!pixbuf)
pixbuf = gdk_pixbuf_new_from_file_at_size(
SKIN_DIR"fetion.svg",
NOTIFY_IMAGE_SIZE,
NOTIFY_IMAGE_SIZE , NULL);
notify_notification_update(fxmain->notify , notifySummary
, notifyText , NULL);
notify_notification_set_icon_from_pixbuf(fxmain->notify , pixbuf);
notify_notification_show(fxmain->notify , NULL);
g_object_unref(pixbuf);
}
#endif
}
void fx_main_process_presence(FxMain *fxmain , const gchar *xml) {
gchar *crc = NULL;
gchar *name;
gint oldstate , count;
Contact *contactlist;
Contact *contact;
User *user = fxmain->user;
GtkWidget *treeView = fxmain->mainPanel->treeView;
GtkTreeModel *model;
FxChat *fxchat;
GtkTreeIter iter;
GtkTreeIter parentIter;
contactlist = fetion_user_parse_presence_body(xml , user);
contact = contactlist;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
foreach_contactlist(contactlist , contact) {
if(fx_tree_get_buddy_iter_by_userid(model , contact->userId , &iter) == -1)
continue;
presence_count ++;
/* all presence information has been pushed
* then start update local data and buddy portrait */
if(presence_count == user->contactCount)
g_thread_create(update_data, fxmain, FALSE, NULL);
gtk_tree_model_get(model , &iter
, B_CRC_COL , &crc
, B_STATE_COL , &oldstate
, -1);
gdk_threads_enter();
fxchat = fx_list_find_chat_by_sipuri(fxmain->clist , contact->sipuri);
if(oldstate > 0 && contact->state <= 0 && contact->serviceStatus == STATUS_NORMAL) {
gtk_tree_model_iter_parent(model , &parentIter , &iter);
gtk_tree_model_get(model , &parentIter
, G_ONLINE_COUNT_COL , &count
, -1);
count --;
gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter
, G_ONLINE_COUNT_COL , count
, -1);
fx_tree_move_to_the_last(model , &iter);
}
if(oldstate <= 0 && contact->state > 0 && contact->serviceStatus == STATUS_NORMAL) {
gtk_tree_model_iter_parent(model , &parentIter , &iter);
gtk_tree_model_get(model , &parentIter
, G_ONLINE_COUNT_COL , &count
, -1);
count ++;
gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter
, G_ONLINE_COUNT_COL , count
, -1);
fx_tree_move_to_the_last(model , &iter);
fx_tree_move_to_the_first(model , &iter);
popup_online_notify(fxmain, contact);
}
if(fxchat)
fxchat->state = contact->state;
name = (contact->nickname == NULL || strlen(contact->localname) == 0) ?
contact->nickname : contact->localname;
gtk_tree_store_set(GTK_TREE_STORE(model) , &iter
, B_NAME_COL , g_markup_escape_text(name, -1)
, B_SIPURI_COL , contact->sipuri
, B_IMPRESSION_COL , g_markup_escape_text(contact->impression, -1)
, B_PHONENUM_COL , contact->mobileno
, B_USERID_COL , contact->userId
, B_STATE_COL , contact->state
, B_IDENTITY_COL , contact->identity
, B_DEVICE_COL , contact->devicetype
, B_RELATIONSTATUS_COL , contact->relationStatus
, B_SERVICESTATUS_COL , contact->serviceStatus
, B_CARRIERSTATUS_COL , contact->carrierStatus
, B_CARRIER_COL , contact->carrier
, B_CRC_COL , contact->portraitCrc
, B_IMAGE_CHANGED_COL , crc == NULL ? IMAGE_CHANGED :
(strcmp(crc , contact->portraitCrc) == 0 ? IMAGE_NOT_CHANGED : IMAGE_CHANGED)
, -1);
g_free(crc);
gdk_threads_leave();
}
}
static void process_system_message(const char *sipmsg) {
gint showonce;
gint type;
gchar *msg;
gchar *url;
FxSysmsg *sysmsg;
fetion_sip_parse_sysmsg(sipmsg , &type , &showonce
, &msg , &url);
if(type == 0) {
sysmsg = fx_sysmsg_new();
fx_sysmsg_initialize(sysmsg);
fx_sysmsg_bind(sysmsg , msg , url);
gtk_dialog_run(GTK_DIALOG(sysmsg->dialog));
gtk_widget_destroy(sysmsg->dialog);
g_free(sysmsg);
}
}
static void process_group_message(FxMain *fxmain , Message *message) {
FxPGGroup *fxpgcur;
FxPGGroup *fxpg;
PGGroupMember *memcur;
FxList *pglist;
FxList *cur;
User *user;
Config *config;
GdkPixbuf *pixbuf;
gchar path[1024];
gchar *sid;
user = fxmain->user;
config = user->config;
pglist = fxmain->pglist;
foreach_list(pglist , cur) {
fxpgcur = (FxPGGroup *)(cur->data);
if(strcmp(fxpgcur->pggroup->pguri,
message->pguri) == 0) {
fxpg = fxpgcur;
break;
}
}
gdk_threads_enter();
if(fxpg == NULL || fxpg->hasFocus == CHAT_DIALOG_NOT_FOCUSED ) {
if(fxpg == NULL) {
if(config->autoPopup == AUTO_POPUP_ENABLE) {
fxpg = pg_create_window(fxmain , message->pguri);
foreach_pg_member(fxpg->pggroup->member , memcur) {
if(strcmp(memcur->sipuri , message->sipuri) == 0)
pg_add_message(fxpg , message->message
, &(message->sendtime) , memcur);
}
} else {
cur = fx_list_new(message);
fx_list_append(fxmain->mlist , cur);
}
} else {
foreach_pg_member(fxpg->pggroup->member , memcur) {
if(strcmp(memcur->sipuri , message->sipuri) == 0)
pg_add_message(fxpg , message->message , &(message->sendtime) , memcur);
}
}
sid = fetion_sip_get_pgid_by_sipuri(message->pguri);
snprintf(path , sizeof(path) - 1 , "%s/PG%s.jpg" , config->iconPath , sid);
g_free(sid);
pixbuf = gdk_pixbuf_new_from_file(path , NULL);
if(pixbuf == NULL)
pixbuf = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg" , NULL);
gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(fxmain->trayIcon) , pixbuf);
g_object_unref(pixbuf);
gtk_status_icon_set_blinking(GTK_STATUS_ICON(fxmain->trayIcon) , TRUE);
g_signal_handler_disconnect(fxmain->trayIcon , fxmain->iconConnectId);
fxmain->iconConnectId = g_signal_connect(G_OBJECT(fxmain->trayIcon)
, "activate"
, GTK_SIGNAL_FUNC(fx_main_message_func)
, fxmain);
} else {
foreach_pg_member(fxpg->pggroup->member , memcur) {
if(strcmp(memcur->sipuri , message->sipuri) == 0)
pg_add_message(fxpg , message->message , &(message->sendtime) , memcur);
}
}
gdk_threads_leave();
if(config->isMute == MUTE_DISABLE)
fx_sound_play_file(RESOURCE_DIR"newmessage.wav");
}
static void popup_msg_notify(FxMain *fxmain, Contact *senderContact, Message *msg) {
#ifdef USE_LIBNOTIFY
Config *config = fxmain->user->config;
GdkPixbuf *notifyIcon;
gchar *senderSid;
gchar iconPath[256];
gchar notifySum[256];
if(config->msgAlert == MSG_ALERT_ENABLE) {
if(senderContact) {
sprintf(iconPath, "%s/%s.jpg",
config->iconPath, senderContact->sId);
senderSid = fetion_sip_get_sid_by_sipuri(msg->sipuri);
sprintf(notifySum, _("%s(%s) said:"),
senderContact->nickname , senderContact->sId);
g_free(senderSid);
notifyIcon = gdk_pixbuf_new_from_file_at_size(
iconPath , 48 , 48 , NULL);
notify_notification_update(fxmain->notify,
notifySum, msg->message , NULL);
if(!notifyIcon)
notifyIcon = gdk_pixbuf_new_from_file_at_size(
SKIN_DIR"fetion.svg", 48, 48, NULL);
notify_notification_set_icon_from_pixbuf(
fxmain->notify , notifyIcon);
notify_notification_show(fxmain->notify , NULL);
g_object_unref(notifyIcon);
}
}
#endif
}
void fx_main_process_message(FxMain *fxmain , FetionSip *sip , const gchar *sipmsg) {
Message *msg;
FxList *clist;
FxList *mitem;
FxChat *fxchat;
User *user;
Config *config;
gchar path[256];
gchar *sid;
GdkPixbuf *pb;
Contact *senderContact;
clist = fxmain->clist;
user = fxmain->user;
config = user->config;
fetion_sip_parse_message(sip , sipmsg , &msg);
/* group message */
if(msg->pguri) {
process_group_message(fxmain , msg);
return;
}
fxchat = fx_list_find_chat_by_sipuri(clist , msg->sipuri);
sid = fetion_sip_get_sid_by_sipuri(msg->sipuri);
senderContact = fetion_contact_list_find_by_sipuri(
user->contactList , msg->sipuri);
/* system message */
if(strlen(sid) < 5 || strcmp(sid , "10000") == 0) {
g_free(sid);
if(config->closeSysMsg == CLOSE_SYSMSG_ENABLE)
return;
gdk_threads_enter();
process_system_message(sipmsg);
gdk_threads_leave();
fetion_message_free(msg);
return;
}
if(senderContact)
fx_main_add_history(fxmain, senderContact->nickname,
senderContact->userId, msg->message, 0);
gdk_threads_enter();
if(!fxchat || fxchat->hasFocus == CHAT_DIALOG_NOT_FOCUSED) {
/* chat window does not exist */
if(!fxchat) {
/* auto popup enabled */
if(config->autoPopup == AUTO_POPUP_ENABLE) {
fxchat = fx_main_create_chat_window(fxmain , msg->sipuri);
if(!fxchat) {
fetion_message_free(msg);
gdk_threads_leave();
return;
}
fx_chat_add_message(fxchat , msg->message,
&(msg->sendtime) , 0 , msg->sysback);
fetion_message_free(msg);
gdk_threads_leave();
return;
} else {
/* chat window doesn`t exist and auto-pupup wasn`t enabled
* just push message into message queue,wait for user action */
mitem = fx_list_new(msg);
fx_list_append(fxmain->mlist , mitem );
popup_msg_notify(fxmain, senderContact, msg);
}
/* chat window exist,but not focused */
} else {
fx_chat_add_message(fxchat , msg->message,
&(msg->sendtime) , 0 , msg->sysback);
fxchat->unreadMsgCount ++;
fx_chat_update_window(fxchat);
}
sprintf(path , "%s/%s.jpg" , config->iconPath , sid);
g_free(sid);
pb = gdk_pixbuf_new_from_file(path , NULL);
if(!pb)
pb = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg" , NULL);
gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(fxmain->trayIcon) , pb);
g_object_unref(pb);
gtk_status_icon_set_blinking(GTK_STATUS_ICON(fxmain->trayIcon) , TRUE);
g_signal_handler_disconnect(fxmain->trayIcon , fxmain->iconConnectId);
fxmain->iconConnectId = g_signal_connect(G_OBJECT(fxmain->trayIcon)
, "activate"
, GTK_SIGNAL_FUNC(fx_main_message_func)
, fxmain);
/* no message was pushed into the message queue,just free it */
if(fxchat && fxchat->hasFocus == CHAT_DIALOG_NOT_FOCUSED)
fetion_message_free(msg);
} else {
fx_chat_add_message(fxchat , msg->message,
&(msg->sendtime) , 0, msg->sysback);
/* message was showed in the chat dialog directly,just free it */
fetion_message_free(msg);
}
gdk_threads_leave();
if(config->isMute == MUTE_DISABLE)
fx_sound_play_file(RESOURCE_DIR"newmessage.wav");
}
void fx_main_process_user_left(FxMain *fxmain , const gchar *msg) {
gchar *sipuri;
FxList *clist;
FxChat *fxchat;
Conversation *conv;
clist = fxmain->clist;
fetion_sip_parse_userleft(msg , &sipuri);
/* remove sip struct from stack */
fx_list_remove_sip_by_sipuri(fxmain->slist , sipuri);
/* if fxchat exist , set current sip struct to NULL ,
* and exit thread, orelse just exit current thread */
fxchat = fx_list_find_chat_by_sipuri(clist , sipuri);
if(!fxchat) {
debug_info("User %s left conversation" , sipuri);
debug_info("Thread exit");
g_free(sipuri);
g_thread_exit(0);
}
conv = fxchat->conv;
conv->currentSip = NULL;
debug_info("User %s left conversation" , sipuri);
debug_info("Thread exit");
g_free(sipuri);
g_thread_exit(0);
}
FxChat *fx_main_create_chat_window(FxMain *fxmain , const gchar *sipuri) {
Conversation *conv;
FxChat *fxchat;
FxList *citem;
Contact *contact;
gchar *sid;
if((fxchat = fx_list_find_chat_by_sipuri(fxmain->clist , sipuri)) != NULL)
return fxchat;
conv = fetion_conversation_new(fxmain->user , sipuri , NULL);
/* this buddy is not in the friend list*/
if(!conv) {
sid = fetion_sip_get_sid_by_sipuri(sipuri);
if(strlen(sid) < 8 || strcmp(sid , "10000") == 0) {
g_free(sid);
return NULL;
}
contact = fetion_contact_get_contact_info_by_no(fxmain->user , sid , FETION_NO);
if(!contact)
return NULL;
/* replace the sipuri*/
memset(contact->sipuri, 0, sizeof(contact->sipuri));
strcpy(contact->sipuri , sipuri);
fetion_contact_list_append(fxmain->user->contactList , contact);
conv = fetion_conversation_new(fxmain->user , sipuri , NULL);
}
if(!conv)
return NULL;
fxchat = fx_chat_new(fxmain , conv);
fx_chat_initialize(fxchat);
citem = fx_list_new(fxchat);
fx_list_append(fxmain->clist , citem);
return fxchat;
}
void fx_main_process_invitation(FxMain *fxmain , const gchar *sipmsg) {
gchar *sipuri;
FetionSip *osip;
FetionSip *sip;
FxList *list;
TimeOutArgs *timeout;
gchar event[16];
ThreadArgs *args;
args = (ThreadArgs *)malloc(sizeof(ThreadArgs));
sip = fxmain->user->sip;
memset(event, 0, sizeof(event));
if(fetion_sip_get_attr(sipmsg , "N" , event) != -1)
return;
fetion_sip_parse_invitation(sip,
fxmain->user->config->proxy,
sipmsg , &osip , &sipuri);
list = fx_list_new(osip);
fx_list_append(fxmain->slist , list);
args->fxmain = fxmain;
args->sip = osip;
/* create a thread to listen in this channel */
g_thread_create(fx_main_listen_thread_func,
args , FALSE , NULL);
/* start send keep alive message throuth chat chanel
* and put the timeout information into stack */
debug_info("Start periodically sending keep alive request");
timeout = timeout_args_new(fxmain , osip , sipuri);
list = fx_list_new(timeout);
fx_list_append(fxmain->tlist , list);
}
#if 0
static void process_share_action_accept(FxMain *fxmain
, FetionSip *sip , const char *sipmsg , const char *sipuri) {
return;
}
static void process_share_action_cancel(FxMain *fxmain
, FetionSip *sip , const char *sipmsg , const char *sipuri) {
return;
}
#endif
void fx_main_process_incoming(FxMain *fxmain
, FetionSip *sip , const gchar *sipmsg) {
IncomingType type;
IncomingActionType action;
gchar *sipuri;
FxChat *fxchat;
fetion_sip_parse_incoming(sip , sipmsg , &sipuri , &type , &action);
switch(type) {
case INCOMING_NUDGE : {
gdk_threads_enter();
fxchat = fx_main_create_chat_window(fxmain , sipuri);
gdk_threads_leave();
fx_chat_nudge_in_thread(fxchat);
gdk_threads_enter();
fx_chat_add_information(fxchat , _("Receive a window jitter"));
gdk_threads_leave();
debug_info("Received a nudge from %s" , sipuri);
break;
}
case INCOMING_SHARE_CONTENT : {
switch(action) {
case INCOMING_ACTION_ACCEPT :
//process_share_action_accept(fxmain , sip , sipmsg , sipuri);
break;
case INCOMING_ACTION_CANCEL :
//process_share_action_cancel(fxmain , sip , sipmsg , sipuri);
break;
default:
break;
}
break;
}
default:
break;
}
}
static void fx_main_process_group(FxMain *fxmain , const gchar *xml) {
User *user = fxmain->user;
PGGroup *pgcur;
user->pggroup = pg_group_parse_list(xml);
if(user->pggroup == NULL)
return;
pg_group_get_info(user , user->pggroup);
foreach_pg_group(user->pggroup , pgcur) {
pg_group_send_invitation(user , pgcur);
pg_group_get_group_members(user , pgcur);
}
}
void fx_main_process_sipc(FxMain *fxmain , const gchar *sipmsg) {
int callid;
int code;
char *xml = NULL;
User *user = fxmain->user;
struct unacked_list *ulist;
PGGroup *pggroup = user->pggroup;
PGGroup *pgcur;
code = fetion_sip_parse_sipc(sipmsg , &callid , &xml);
/* get group info response */
if(callid == user->pgGroupCallId) {
gdk_threads_enter();
fx_main_process_group(fxmain , xml);
gdk_threads_leave();
return;
}
foreach_unacked_list(unackedlist , ulist) {
if(callid == ulist->message->callid) {
unacked_list_remove(unackedlist , ulist);
fetion_message_free(ulist->message);
free(ulist);
return;
}
}
if(pggroup != NULL) {
foreach_pg_group(pggroup , pgcur) {
#if 0
/* get member contact info response */
foreach_pg_member(pgcur->member , memcur) {
if(memcur->getContactInfoCallId == callid) {
memcur->contact = pg_group_parse_contact_info(xml);
return;
}
}
#endif
/* group invitation response */
if(pgcur->inviteCallId == callid && code == 200) {
if(pgcur->hasAcked == 0) {
pg_group_send_invite_ack(user , sipmsg);
pgcur->hasAcked = 1;
return;
}
}
/* get group member response */
if(pgcur->getMembersCallId == callid) {
pg_group_parse_member_list(pggroup , sipmsg);
pg_group_subscribe(user , pgcur);
return;
}
}
}
free(xml);
}
void fx_main_process_deregistration(FxMain *fxmain) {
gdk_threads_enter();
fx_util_popup_warning(fxmain , _("Your fetion login elsewhere. You are forced quit."));
gdk_threads_leave();
gtk_main_quit();
}
void fx_main_process_syncuserinfo(FxMain *fxmain , const gchar *xml) {
Contact *contact;
GtkTreeIter iter;
GtkTreeIter cIter;
gchar *userid;
GtkTreeModel *model = gtk_tree_view_get_model(
GTK_TREE_VIEW(fxmain->mainPanel->treeView));
contact = fetion_user_parse_syncuserinfo_body(xml , fxmain->user);
if(!contact)
return;
gtk_tree_model_get_iter_root(model , &iter);
do {
if(gtk_tree_model_iter_children(model , &cIter , &iter)) {
do {
gtk_tree_model_get(model , &cIter , B_USERID_COL , &userid , -1);
if(strcmp(userid , contact->userId) == 0) {
gdk_threads_enter();
gtk_tree_store_set(GTK_TREE_STORE(model) , &cIter
, B_SIPURI_COL , contact->sipuri
, B_RELATIONSTATUS_COL , contact->relationStatus
, -1);
gdk_threads_leave();
g_free(userid);
goto end;
}
g_free(userid);
} while(gtk_tree_model_iter_next(model , &cIter));
}
} while(gtk_tree_model_iter_next(model , &iter));
end:
return;
}
void *fx_main_process_addbuddyapplication_thread(void *data) {
struct Args {
FxMain *fxmain;
gchar sipmsg[2048];
} *args = (struct Args *)data;
gchar *userid;
gchar *sipuri;
gchar *desc;
gint phrase;
FxApp *fxapp;
fetion_sip_parse_addbuddyapplication(args->sipmsg,
&sipuri , &userid , &desc , &phrase);
fxapp = fx_app_new(args->fxmain, sipuri,
userid , desc , phrase);
gdk_threads_enter();
fx_app_initialize(fxapp);
gtk_dialog_run(GTK_DIALOG(fxapp->dialog));
gtk_widget_destroy(fxapp->dialog);
gdk_threads_leave();
return NULL;
}
void fx_main_process_addbuddyapplication(FxMain *fxmain , const char *sipmsg) {
struct Args {
FxMain *fxmain;
char sipmsg[2048];
} *args = (struct Args *)malloc(sizeof(struct Args));
memset(args , 0 , sizeof(struct args));
args->fxmain = fxmain;
strcpy(args->sipmsg , sipmsg);
g_thread_create(fx_main_process_addbuddyapplication_thread , args , FALSE , NULL);
}
void fx_main_destroy(GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain = (FxMain *)data;
User *user = fxmain->user;
if(user) {
Config *config = user->config;
fetion_config_save_size(config);
}
gtk_main_quit();
}
gboolean fx_main_delete(GtkWidget *widget , GdkEvent *UNUSED(event) , gpointer data) {
FxMain *fxmain = (FxMain *)data;
FxClose *fxclose;
Config *config;
int ret;
int window_width;
int window_height;
int window_x;
int window_y;
if(fxmain->user) {
config = fxmain->user->config;
gtk_window_get_position(GTK_WINDOW(fxmain->window),
&window_x, &window_y);
config->window_pos_x = window_x;
config->window_pos_y = window_y;
gtk_window_get_size(GTK_WINDOW(fxmain->window),
&window_width, &window_height);
config->window_width = window_width;
config->window_height = window_height;
}
if(fxmain->user) {
if(config->closeAlert == CLOSE_ALERT_ENABLE) {
fxclose = fx_close_new(fxmain);
fx_close_initialize(fxclose);
ret = gtk_dialog_run(GTK_DIALOG(fxclose->dialog));
if(ret == GTK_RESPONSE_OK) {
if(fx_close_alert(fxclose) == CLOSE_ALERT_DISABLE) {
config->closeMode = fx_close_get_action(fxclose);
config->closeAlert = CLOSE_ALERT_DISABLE;
fetion_config_save(fxmain->user);
}
if(fx_close_get_action(fxclose) == CLOSE_DESTROY_MODE) {
gtk_widget_destroy(fxclose->dialog);
free(fxclose);
gtk_widget_destroy(widget);
return FALSE;
} else {
gtk_widget_destroy(fxclose->dialog);
gtk_widget_hide_on_delete(widget);
return TRUE;
}
} else {
gtk_widget_destroy(fxclose->dialog);
return TRUE;
}
}
} else {
fx_main_destroy(widget , fxmain);
return FALSE;
}
if(fxmain->user != NULL && fxmain->user->loginStatus != -1) {
config = fxmain->user->config;
if(config->closeMode == CLOSE_ICON_MODE) {
gtk_widget_hide_on_delete(widget);
return TRUE;
} else {
gtk_widget_destroy(widget);
return FALSE;
}
}
return FALSE;
}
gboolean fx_main_window_state_func(GtkWidget *widget
, GdkEventWindowState *event , gpointer data) {
FxMain *fxmain;
Config *config;
fxmain = (FxMain *)data;
config = fxmain->user == NULL ? NULL : fxmain->user->config;
if(config) {
if(event->changed_mask == GDK_WINDOW_STATE_ICONIFIED &&
event->new_window_state == GDK_WINDOW_STATE_ICONIFIED) {
if(config->canIconify == ICON_CAN) {
gtk_window_get_position(GTK_WINDOW(widget)
, &window_pos_x_old , &window_pos_y_old);
return TRUE;
} else {
return FALSE;
}
}
}
return FALSE;
}
void fx_main_tray_activate_func(GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain;
Config *config = NULL;
fxmain = (FxMain *)data;
if(fxmain->user && fxmain->user->config)
config = fxmain->user->config;
if(!config)
return;
gtk_window_deiconify(GTK_WINDOW(fxmain->window));
if(GTK_WIDGET_VISIBLE(fxmain->window)) {
if(config->canIconify == ICON_CAN) {
gtk_window_iconify(GTK_WINDOW(fxmain->window));
gtk_window_get_position(GTK_WINDOW(fxmain->window)
, &window_pos_x_old , &window_pos_y_old);
gtk_widget_hide(fxmain->window);
}
} else {
//gtk_window_deiconify(GTK_WINDOW(fxmain->window));
gtk_widget_show(fxmain->window);
}
if(window_pos_x_old == 0 && window_pos_y_old == 0) {
window_pos_x_old = window_pos_x;
window_pos_y_old = window_pos_y;
}
gtk_window_move(GTK_WINDOW(fxmain->window),
window_pos_x_old , window_pos_y_old);
}
static void fx_main_mute_clicked(
GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain;
User *user;
Config *config;
fxmain = (FxMain *)data;
user = fxmain->user;
config = user->config;
if(config->isMute == MUTE_ENABLE)
config->isMute = MUTE_DISABLE;
else
config->isMute = MUTE_ENABLE;
fetion_config_save(user);
}
static void fx_main_direct_sms_clicked(
GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain;
FxDSMS *fxdsms;
fxmain = (FxMain *)data;
fxdsms = fx_dsms_new(fxmain);
if(fxmain->user->carrierStatus == CARRIER_STATUS_DOWN) {
fx_util_popup_warning(fxmain,
SERVICE_DOWN_MESSAGE);
return;
}
fx_dsms_initialize(fxdsms);
}
void fx_main_tray_popmenu_func(
GtkWidget *UNUSED(widget),
guint button , guint activate_time,
gpointer data) {
FxMain *fxmain;
User *user;
Config *config;
GtkWidget *item;
GtkWidget *menu;
GtkWidget *statemenu;
GtkWidget *submenu;
gchar stateMenu[48];
gint i;
typedef struct {
FxMain *fxmain;
StateType type;
} Args;
Args *args;
fxmain = (FxMain *)data;
user = fxmain->user;
struct {
const gchar *name;
const gchar *icon;
int type;
} presence[] = {
{ N_("Online") , SKIN_DIR"online.svg" , P_ONLINE } ,
{ N_("Leave") , SKIN_DIR"away.svg" , P_AWAY } ,
{ N_("Busy") , SKIN_DIR"busy.svg" , P_BUSY } ,
{ N_("Hide") , SKIN_DIR"invisible.svg" , P_HIDDEN } ,
{ N_("Eating out") , SKIN_DIR"away.svg" , P_OUTFORLUNCH } ,
{ N_("Do Not Disturb") , SKIN_DIR"away.svg" , P_DONOTDISTURB } ,
{ N_("Back Soon") , SKIN_DIR"away.svg" , P_RIGHTBACK } ,
{ N_("Meeting") , SKIN_DIR"away.svg" , P_MEETING } ,
{ N_("Calling") , SKIN_DIR"away.svg" , P_ONTHEPHONE} ,
{ NULL , NULL , -1}
};
menu = gtk_menu_new();
fx_main_create_menu1(_("About OpenFetion") , GTK_STOCK_ABOUT
, menu , fx_main_about_fetion_clicked , NULL);
if(fxmain->user && fxmain->user->loginStatus != -1) {
config = fxmain->user->config;
item = gtk_check_menu_item_new_with_label(_("Close sound"));
if(config->isMute == MUTE_ENABLE)
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(item) , TRUE);
else
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(item) , FALSE);
g_signal_connect(item, "activate",
G_CALLBACK(fx_main_mute_clicked) , fxmain);
gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item);
item = gtk_check_menu_item_new_with_label(_("Receive SMS"));
if(strcmp(user->smsOnLineStatus , "0.00:00:00") &&
strcmp(user->smsOnLineStatus , "0.0:0:0"))
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , FALSE);
else
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , TRUE);
gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item);
g_signal_connect(item, "activate",
G_CALLBACK(fx_head_set_sms_clicked) , fxmain);
fx_main_create_menu1(_("Information query") , GTK_STOCK_FIND
, menu , fx_main_info_lookup_clicked , fxmain);
statemenu = fx_main_create_menu1(_("Edit statement"),
GTK_STOCK_INFO , menu , NULL , NULL);
submenu = gtk_menu_new();
for(i = 0 ; presence[i].type != -1 ; i++) {
args = (Args *)malloc(sizeof(Args));
args->fxmain = fxmain;
args->type = presence[i].type;
sprintf(stateMenu , "%s " , _(presence[i].name));
fx_main_create_menu(stateMenu , presence[i].icon
, submenu , fx_main_set_state_clicked , args);
}
gtk_menu_item_set_submenu(GTK_MENU_ITEM(statemenu) , submenu);
statemenu = fx_main_create_menu1(_("Message Function"),
GTK_STOCK_INFO , menu , NULL , NULL);
submenu = gtk_menu_new();
fx_main_create_menu(_("SMS to many") , SKIN_DIR"groupsend.png"
, submenu , fx_main_send_to_many_clicked , fxmain);
fx_main_create_menu(_("SMS directly") , SKIN_DIR"directsms.png"
, submenu , fx_main_direct_sms_clicked , fxmain);
if(fxmain->user->boundToMobile == BOUND_MOBILE_ENABLE)
fx_main_create_menu(_("SMS myself") , SKIN_DIR"myselfsms.png"
, submenu , fx_main_send_to_myself_clicked , fxmain);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(statemenu) , submenu);
fx_main_create_menu1(_("Add contact") , GTK_STOCK_ADD
, menu , fx_main_add_buddy_clicked , fxmain);
fx_main_create_menu1(_("Personal setting") , GTK_STOCK_EDIT
, menu , fx_main_personal_setting_clicked , fxmain);
fx_main_create_menu1(_("System setting") , GTK_STOCK_PREFERENCES
, menu , fx_main_system_setting_clicked , fxmain);
}
fx_main_create_menu1(_("Exit OpenFetion ") , GTK_STOCK_QUIT
, menu , fx_main_destroy , fxmain);
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL
, button , activate_time);
}
int main(int argc , char *argv[]) {
FxMain *fxmain = fx_main_new();
setlocale(LC_ALL, "");
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
bindtextdomain(GETTEXT_PACKAGE , LOCALE_DIR);
textdomain(GETTEXT_PACKAGE);
if(!g_thread_supported())
g_thread_init(NULL);
gdk_threads_init();
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, 0 );
#ifdef USE_GSTREAMER
gst_init(&argc , &argv);
#endif
#ifdef USE_LIBNOTIFY
notify_init("Openfetion");
#endif
gtk_init(&argc , &argv);
fx_conn_init(fxmain);
fx_main_initialize(fxmain);
return 0;
}
static void chat_listen_thread_end(FxMain *fxmain, const char *sipuri) {
FxList *clist;
FxChat *fxchat;
Conversation *conv;
clist = fxmain->clist;
if(!sipuri || strlen(sipuri) == 0)
return;
fx_list_remove_sip_by_sipuri(fxmain->slist , sipuri);
fxchat = fx_list_find_chat_by_sipuri(clist , sipuri);
if(!fxchat) {
debug_info("User %s left conversation" , sipuri);
debug_info("Thread exit");
g_thread_exit(0);
}
conv = fxchat->conv;
conv->currentSip = NULL;
debug_info("User %s left conversation" , sipuri);
debug_info("Thread exit");
g_thread_exit(0);
}
void *fx_main_listen_thread_func(void *data) {
ThreadArgs *args;
FxMain *fxmain;
FetionSip *sip;
SipMsg *msg;
SipMsg *pos;
User *user;
gint type;
gint ret;
gint error;
args = (ThreadArgs *)data;
fxmain = args->fxmain;
user = fxmain->user;
sip = args->sip;
struct timeval tv;
debug_info("A new thread entered");
sip = (sip == NULL ? fxmain->user->sip : sip);
for(;;) {
if(!fxmain)
g_thread_exit(0);
FD_ZERO(&fd_read);
g_static_mutex_lock(&mutex);
if(!sip || !sip->tcp) {
debug_info("thread exited");
g_thread_exit(0);
}
FD_SET(sip->tcp->socketfd, &fd_read);
g_static_mutex_unlock(&mutex);
tv.tv_sec = 13;
tv.tv_usec = 0;
ret = select(sip->tcp->socketfd + 1, &fd_read, NULL, NULL, &tv);
if(ret == 0)
continue;
if (ret == -1) {
debug_info ("Error.. to read socket %d,exit thread",
sip->tcp->socketfd);
if(sip != user->sip) {
debug_info("Error.. thread sip freed\n");
g_free(sip);
}
g_thread_exit(0);
}
if (!FD_ISSET (sip->tcp->socketfd, &fd_read)) {
g_usleep (100);
continue;
}
msg = fetion_sip_listen(sip, &error);
if(!msg && error) {
/* if it is the main listening thread */
if(sip == user->sip) {
gdk_threads_enter();
printf("\n\nError ...... break out...\n\n");
fx_conn_offline(fxmain);
gdk_threads_leave();
g_thread_exit(0);
} else {
printf("\n\n Error ... user listen thread break out\n\n");
chat_listen_thread_end(fxmain, sip->sipuri);
tcp_connection_free(sip->tcp);
g_thread_exit(0);
}
}
pos = msg;
while(pos) {
type = fetion_sip_get_type(pos->message);
switch(type) {
case SIP_NOTIFICATION :
fx_main_process_notification(fxmain , pos->message);
break;
case SIP_MESSAGE:
fx_main_process_message(fxmain , sip , pos->message);
break;
case SIP_INVITATION:
fx_main_process_invitation(fxmain , pos->message);
break;
case SIP_INCOMING :
fx_main_process_incoming(fxmain , sip , pos->message);
break;
case SIP_SIPC_4_0:
fx_main_process_sipc(fxmain , pos->message);
break;
default:
//printf("%s\n" , pos->message);
break;
}
pos = pos->next;
}
if(msg)
fetion_sip_message_free(msg);
}
return NULL;
}
void fx_main_message_func(GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain;
FxList *mlist;
FxList *cur;
FxList *tmp;
FxChat *fxchat;
FxPGGroup *fxpg;
PGGroupMember *memcur;
Message *msg;
fxmain = (FxMain *)data;
mlist = fxmain->mlist;
cur = mlist->pre;
#ifdef USE_LIBNOTIFY
notify_notification_close(fxmain->notify , NULL);
#endif
while(cur != fxmain->mlist) {
msg = (Message *)(cur->data);
/* ordinary message */
if(!msg->pguri) {
fxchat = fx_main_create_chat_window(fxmain , msg->sipuri);
if(!fxchat) {
g_print("Unknow Message\n");
g_print("%s:%s\n" , msg->sipuri , msg->message);
continue;
}
fx_chat_add_message(fxchat , msg->message,
&(msg->sendtime) , 0 , msg->sysback);
} else {
/*group message*/
fxpg = pg_create_window(fxmain , msg->pguri);
foreach_pg_member(fxpg->pggroup->member , memcur) {
if(strcmp(memcur->sipuri , msg->sipuri) == 0) {
pg_add_message(fxpg, msg->message,
&(msg->sendtime) , memcur );
break;
}
}
}
fetion_message_free(msg);
tmp = cur;
cur = cur->pre;
fx_list_remove(tmp);
free(tmp);
}
fx_head_set_state_image(fxmain , fxmain->user->state);
gtk_status_icon_set_blinking(
GTK_STATUS_ICON(fxmain->trayIcon) , FALSE);
g_signal_handler_disconnect(fxmain->trayIcon,
fxmain->iconConnectId);
fxmain->iconConnectId = g_signal_connect(
G_OBJECT(fxmain->trayIcon)
, "activate"
, GTK_SIGNAL_FUNC(fx_main_tray_activate_func)
, fxmain);
foreach_list(fxmain->clist, cur) {
fxchat = (FxChat *)cur->data;
if(fxchat->unreadMsgCount != 0)
gtk_window_present(GTK_WINDOW(fxchat->dialog));
}
}
gboolean fx_main_register_func(User *user) {
if(fetion_user_keep_alive(user) < 0) {
debug_info("keep alive terminated");
return FALSE;
}
return TRUE;
}
gboolean fx_main_check_func(FxMain *fxmain) {
struct unacked_list *list;
struct tm *now;
char *msg;
time_t now_t;
time_t msg_time_t;
long seconds;
start_popup_presence = 1;
if(fxmain->user->state == P_OFFLINE) {
debug_info("Error.. check function exited");
return FALSE;
}
now = get_currenttime();
foreach_unacked_list(unackedlist , list) {
now_t = mktime(now);
msg_time_t = mktime(&(list->message->sendtime));
seconds = (long)now_t - (long)msg_time_t;
if(seconds > 20) {
unacked_list_remove(unackedlist , list);
msg = contruct_message_sip(fxmain->user->sId , list->message);
fx_main_process_message(fxmain , fxmain->user->sip , msg);
free(msg);
fetion_message_free(list->message);
free(list);
}
}
idle_autoaway(fxmain);
return TRUE;
}
void fx_main_about_fetion_clicked(GtkWidget *UNUSED(widget) , gpointer UNUSED(data)) {
show_about();
}
void fx_main_send_to_myself_clicked(GtkWidget *widget , gpointer data) {
fx_bottom_on_sendtome_clicked(widget , data);
}
void fx_main_send_to_many_clicked(GtkWidget *widget , gpointer data) {
fx_bottom_on_sendtomany_clicked(widget , data);
}
void fx_main_personal_setting_clicked(GtkWidget *widget , gpointer data) {
fx_bottom_on_setting_clicked(widget , data);
}
void fx_main_system_setting_clicked(GtkWidget *UNUSED(widget) , gpointer data) {
FxMain *fxmain = (FxMain *)data;
FxSet *fxset = fx_set_new(fxmain);
fx_set_initialize(fxset);
g_object_set(fxset->notebook , "page" , 1 , NULL);
gtk_window_set_position(GTK_WINDOW(fxset->dialog) , GTK_WIN_POS_CENTER);
gtk_dialog_run(GTK_DIALOG(fxset->dialog));
gtk_widget_destroy(fxset->dialog);
}
void fx_main_set_state_clicked(GtkWidget *widget , gpointer data) {
fx_head_change_state_func(widget , data);
}
void fx_main_add_buddy_clicked(GtkWidget *widget , gpointer data) {
fx_bottom_on_addfriend_clicked(widget , data);
}
void fx_main_info_lookup_clicked(GtkWidget *widget , gpointer data) {
fx_bottom_on_lookup_clicked(widget , data);
}
FetionSip *fx_list_find_sip_by_sipuri(FxList *fxlist , const char *sipuri) {
FxList *cur;
FetionSip *sip;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
sip = (FetionSip *)(cur->data);
sid = fetion_sip_get_sid_by_sipuri(sip->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
return sip;
}
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
}
return NULL;
}
void fx_list_remove_sip_by_sipuri(FxList *fxlist , const char *sipuri) {
FxList *cur;
FetionSip *sip;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
sip = (FetionSip *)(cur->data);
sid = fetion_sip_get_sid_by_sipuri(sip->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
debug_info("Removing sip from sip list");
cur->next->pre = cur->pre;
cur->pre->next = cur->next;
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
g_free(cur);
break;
}
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
}
}
FxChat *fx_list_find_chat_by_sipuri(FxList *fxlist , const char *sipuri) {
FxChat *fxchat;
FxList *cur;
Contact *contact;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
fxchat = (FxChat *)(cur->data);
contact = fxchat->conv->currentContact;
sid = fetion_sip_get_sid_by_sipuri(contact->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
g_free(sid);
g_free(sid1);
return fxchat;
}
g_free(sid);
g_free(sid1);
}
return NULL;
}
void fx_list_remove_chat_by_sipuri(FxList *fxlist , const char *sipuri) {
FxList *cur;
Contact *contact;
FxChat *fxchat;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
fxchat = (FxChat *)(cur->data);
contact = fxchat->conv->currentContact;
if(!contact) {
printf("Unknown FxChat\n");
continue;
}
sid = fetion_sip_get_sid_by_sipuri(contact->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
debug_info("Removing chat struct from chat list");
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
cur->next->pre = cur->pre;
cur->pre->next = cur->next;
break;
}
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
}
}
TimeOutArgs *fx_list_find_timeout_by_sipuri(FxList *fxlist , const char *sipuri) {
TimeOutArgs *args;
FxList *cur;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
args = (TimeOutArgs *)(cur->data);
sid = fetion_sip_get_sid_by_sipuri(args->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
return args;
}
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
}
return NULL;
}
void fx_list_remove_timeout_by_sipuri(FxList *fxlist , const char *sipuri) {
FxList *cur;
TimeOutArgs *args;
gchar *sid;
gchar *sid1;
foreach_list(fxlist , cur) {
args = (TimeOutArgs *)(cur->data);
sid = fetion_sip_get_sid_by_sipuri(args->sipuri);
sid1 = fetion_sip_get_sid_by_sipuri(sipuri);
if(strcmp(sid , sid1) == 0) {
cur->next->pre = cur->pre;
cur->pre->next = cur->next;
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
g_free(cur);
break;
}
g_free(sid);
sid = NULL;
g_free(sid1);
sid1 = NULL;
}
}
void fx_list_remove_pg_by_sipuri(FxList *fxlist , const char *sipuri) {
FxList *cur;
FxPGGroup *fxpg;
foreach_list(fxlist , cur) {
fxpg = (FxPGGroup *)(cur->data);
if(strcmp(fxpg->pggroup->pguri , sipuri) == 0) {
cur->next->pre = cur->pre;
cur->pre->next = cur->next;
g_free(cur);
break;
}
}
}
void fx_main_add_history(FxMain *fxmain, const char *name,
const char *sid, const char *msg, int issend) {
History *history;
struct tm *now;
User *user;
user = fxmain->user;
now = get_currenttime();
history = fetion_history_message_new(name
, sid , *now , msg , issend);
g_static_mutex_lock(&mutex);
fetion_history_add(fxmain->history , history);
fetion_history_message_free(history);
g_static_mutex_unlock(&mutex);
}
static void fx_main_process_pggetgroupinfo(FxMain *fxmain , const char *sipmsg) {
PGGroup *pggroup = fxmain->user->pggroup;
pg_group_parse_info(pggroup , sipmsg);
gdk_threads_enter();
fx_tree_bind_pg_data(fxmain);
gdk_threads_leave();
}
static void fx_main_process_pgpresencechanged(FxMain *fxmain , const char *sipmsg) {
PGGroup *pggroup = fxmain->user->pggroup;
pg_group_parse_member(pggroup , sipmsg);
#if 0
PGGroup *pgcur;
/* get member contact info of current group */
foreach_pg_group(pggroup , pgcur) {
if(pgcur->hasDetails == 0)
pg_group_update_group_info(fxmain->user , pgcur);
}
#endif
}
static gboolean key_press_func(GtkWidget *widget , GdkEventKey *event
, gpointer data) {
if(event->keyval == GDK_w) {
if(event->state & GDK_CONTROL_MASK) {
gtk_window_iconify(GTK_WINDOW(widget));
return TRUE;
} else {
return FALSE;
}
}
if(event->keyval == GDK_q) {
if(event->state & GDK_CONTROL_MASK) {
fx_main_delete(widget , NULL , data);
return TRUE;
} else {
return FALSE;
}
}
return FALSE;
}
[源代码打包下载]
初级程序员
by: 我的程序员之路 发表于:2013-05-05 20:17:20 顶(0) | 踩(0) 回复
强大
回复评论