/*************************************************************************** |
* 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) 回复
强大
回复评论