您的位置:首页 > 运维架构 > Linux

Linux QQ之客户端

2014-04-15 17:50 351 查看
客户端之登录UI

//client.c 客户端主函数

#include "const_global.h"
#include <signal.h>
#include "gui.h"

void mem_error(){
format_record("Read or write memory error.");
exit(0);
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
signal(SIGSEGV, mem_error);
land_interface();
return EXIT_SUCCESS;
}
//gui.h 前台UI实现的头文件

#ifndef GUI_H
#define GUI_H

#include <gtk/gtk.h>

void close_window(GtkWidget *, gpointer);
void close_app(GtkWidget *, gpointer);
void on_logout_event(GtkWidget *window, gpointer data);
void on_login_event(GtkWidget *, gpointer);
void on_clear_entry_event(GtkWidget *, gpointer);
void on_changed_event(GtkWidget * , gpointer);
void on_send_event(GtkWidget *, gpointer );
gboolean on_2click_record_event(GtkWidget *, GdkEventButton *, gpointer);

static void init_chat_window(char *,char *);
static void destroy_all_chat_window();
guint get_chat_thread_index(char *);
void *receive_msg_thread();

void add_list_item(GtkWidget *,char *, int);
static GtkTreeModel *create_and_fill_model(void);
static GtkWidget *create_view_and_model(void);

void chat_1to1_ui(char *);
void land_ok_ui();
void land_interface();

void show_login_status(GtkWidget *, gpointer);
void set_widget_bg(GtkWidget *, const gchar *);

typedef struct {
GtkWidget *username_entry; // uname input entry in land ui
GtkWidget *password_entry; // passwd input entry in land ui
} UserInfoGtk;

typedef struct{
guint      status;	// chat window status, 1:opened / 0:closed
//	int		 clientfd;  // connect server file describor
char peer_uid[10];  // peer userid
char peer_uname[20];// peer username
GtkWidget *window;	// chat window
GtkWidget  *input;	// send msg entry obj
GtkWidget *output;	// show msg treeview obj
//	GtkStatusIcon *trayIcon; // chat window status icon
char  address[25];
}ChatThread;

void show_msg(ChatThread *, char *, int);

static ChatThread *chat_thread[MAXFRIENDS];

static GtkWidget *window;
//static GtkStatusIcon *trayIcon;
static GtkStatusIcon *trayIcon;

//according user level to modify
static guint CURRENT_UID=0;

static pthread_t recv_msg_tid;

static int CLIENT_FD = -1;

#endif
//gui.c 前台UI的具体实现

#include "const_global.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include "gui.h"
#include "pub.h"

#define INIT 	0
#define REFRESH 1

void set_widget_bg(GtkWidget *widget, const gchar *img_file) {
GtkStyle *style;
GdkPixbuf *pixbuf;
GdkPixmap *pixmap;
gint width, height;

pixbuf = gdk_pixbuf_new_from_file(img_file, NULL );
width = gdk_pixbuf_get_width(pixbuf);
height = gdk_pixbuf_get_height(pixbuf);
pixmap = gdk_pixmap_new(NULL, width, height, 24);
gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 0);
style = gtk_style_copy(GTK_WIDGET(widget)->style);

if (style->bg_pixmap[GTK_STATE_NORMAL])
g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);

style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref(pixmap);
style->bg_pixmap[GTK_STATE_ACTIVE] = g_object_ref(pixmap);
style->bg_pixmap[GTK_STATE_PRELIGHT] = g_object_ref(pixmap);
style->bg_pixmap[GTK_STATE_SELECTED] = g_object_ref(pixmap);
style->bg_pixmap[GTK_STATE_INSENSITIVE] = g_object_ref(pixmap);
gtk_widget_set_style(GTK_WIDGET(widget), style);
g_object_unref(style);
}

void close_window(GtkWidget *window, gpointer data) {
gtk_widget_destroy(window);

if (data != NULL) {
((ChatThread *) data)->status = 0;
((ChatThread *) data)->address[0] = '\0';
}
}

void close_app(GtkWidget *window, gpointer data) {
gtk_main_quit();
}

void on_login_event(GtkWidget *button, gpointer data) {
const char *username_text = gtk_entry_get_text(
GTK_ENTRY(((UserInfoGtk *) data)->username_entry));
const char *passwd_text = gtk_entry_get_text(
GTK_ENTRY(((UserInfoGtk *) data)->password_entry));
char buf[MAXLINE], *login_result, *user_pet_name, *ip_port;
#ifndef DEBUG
if(strlen(username_text) == 0 || strlen(passwd_text) == 0) {
LOGIN_STATUS = LOGIN_FAILED;
goto End;
}
memset(buf,'\0',MAXLINE);

login_user(username_text, passwd_text, buf);
if(!strlen(buf)) {
LOGIN_STATUS = LOGIN_FAILED;
goto End;
}
strtok(buf, split); 				// action type [LOGIN|FRESH]
login_result = strtok(NULL, split); // login status [SUCCESS|FAILED] and USER_NAME
user_pet_name = strtok(NULL, split);
ip_port = strtok(NULL, split);

LOGIN_STATUS = strcmp(login_result,"SUCCESS") == 0 ? LOGIN_SUCCESS : LOGIN_FAILED;

if (LOGIN_STATUS == LOGIN_SUCCESS) {
memset(USER_ID, '\0', sizeof(USER_ID));
memset(USER_NAME,'\0',sizeof(USER_NAME));
memset(ADDRESS,'\0',sizeof(ADDRESS));
strcpy(USER_ID, username_text);
strcpy(USER_NAME, user_pet_name);
strcpy(ADDRESS, ip_port);
CLIENT_FD = open_tcp_connection();
}
#else
LOGIN_STATUS = LOGIN_SUCCESS;
strcpy(USER_ID, "00001");
strcpy(USER_NAME, "debug");
strcpy(ADDRESS, "127.0.0.1:8000");
#endif
End:
return;
}

void on_logout_event(GtkWidget *window, gpointer data) {
int clientfd;
char buf[50], *logout_result;

//	clientfd = open_tcp_connection();
clientfd = CLIENT_FD;
if( -1 == clientfd) {
format_record("ERROR: Can not connect to server, quit failed.");
return;
}
sprintf(buf, "LOGOUT%s%s%sNULL%sNULL", split, USER_ID, split, split);

if (Write(clientfd, buf, sizeof(buf)) < 0) {
format_record("ERROR: Write request to server to logout failed.");
goto End;
}
memset(buf, '\0', sizeof(buf));
if (Read(clientfd, buf, sizeof(buf)) < 0) {
format_record("ERROR: Read return result from server of login failed.");
goto End;
}

strtok(buf, split); 				 	// action type [LOGIN|REFRESH|LOGOUT]
logout_result = strtok(NULL, split); 	// login status [SUCCESS|FAILED] and USER_NAME

LOGIN_STATUS = strcmp(logout_result, "SUCCESS") == 0 ? LOGIN_OFF : LOGIN_SUCCESS;

if (LOGIN_STATUS != LOGIN_OFF) {
format_record("There is something wrong to read return result from server of logout.");
goto End;
}

memset(USER_ID, '\0', sizeof(USER_ID));
memset(USER_NAME,'\0',sizeof(USER_NAME));
memset(ADDRESS,'\0',sizeof(ADDRESS));
destroy_all_chat_window();
close_app(window, data);

End:
Close(clientfd);
CLIENT_FD = -1;
}

void on_clear_entry_event(GtkWidget *button, gpointer data) {
//	GtkTextBuffer *buffer;
//	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW( data));
//	gtk_text_buffer_set_text(buffer, "", -1);
gtk_entry_set_text((GtkEntry *) data, "");
}

void on_changed_event(GtkWidget * widget, gpointer statusbar) {
GtkTreeIter iter;
GtkTreeModel *model;
char *value = NULL;

if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(widget), &model,
&iter)) {
gtk_tree_model_get(model, &iter, COL_NAME, &value, -1);
if (value == NULL )
return;
gtk_statusbar_push(GTK_STATUSBAR(statusbar),
gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), value),
value);
g_free(value);
}
}

void on_send_event(GtkWidget *widget, gpointer data) {
char *peer_ip, *peer_port, *address;
char words[130];
if (strlen(gtk_entry_get_text(GTK_ENTRY(((ChatThread *) data)->input)))) {
sprintf(words, "%s%s%s%s%s", USER_ID, split, USER_NAME, split, gtk_entry_get_text(GTK_ENTRY(((ChatThread *) data)->input)));
//begin: send msg to peer user
address = (char *)malloc(25);
strcpy(address,((ChatThread *) data)->address);
peer_ip = strtok(address,":");
peer_port = strtok(NULL,":");
send_udp_msg(peer_ip, atoi(peer_port), words);
free(address);
//	end: send msg to peer user

//	begin: save msg to server
memset(words,'\0',sizeof(words));
sprintf(words, "SAVE_MSG%s%s%s%s%s%s",
split,USER_ID,
split,gtk_entry_get_text(GTK_ENTRY(((ChatThread *) data)->input)),
split,((ChatThread *) data)->peer_uid);
save_tcp_msg(words);
//		save_tcp_msg(CLIENT_FD,words);
//	end: save msg to server

//  begin: show msg in chat window
memset(words,'\0',sizeof(words));
sprintf(words,"%s :[%s]",gtk_entry_get_text(GTK_ENTRY(((ChatThread *) data)->input)), USER_NAME);
on_clear_entry_event(widget, GTK_ENTRY(((ChatThread *) data)->input));
show_msg((ChatThread *) data, words, SELF_ALIGN);
//	end: show msg in chat window
} else {
format_record("Can not send null character.");
}
}

void add_list_item(GtkWidget *list, char *item_text, int alignment) {
GtkWidget *list_item, *label;
if (strlen(item_text)) {
//		gtk_container_add(GTK_CONTAINER(list),gtk_list_item_new_with_label(item_text));
label = gtk_label_new(item_text);
list_item = gtk_list_item_new();
gtk_misc_set_alignment(GTK_MISC(label),alignment,0);
// left/up alignment
//		gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
// right/up alignment
//		gtk_misc_set_alignment(GTK_MISC(label),1,0);
gtk_container_add(GTK_CONTAINER(list_item), label);
gtk_container_add(GTK_CONTAINER(list), list_item);
} else {
format_record("No data!");
}
}

static void destroy_all_chat_window(){
int index = 0;
for (index=CURRENT_UID-1; index >= 0; index--)
free(chat_thread[index]);
CURRENT_UID = 0;
}

static void init_chat_window(char *peer_uid, char *peer_uname){
chat_thread[CURRENT_UID] = (ChatThread *) malloc(sizeof(ChatThread));
memset(chat_thread[CURRENT_UID], '\0', sizeof(ChatThread));
strcpy(chat_thread[CURRENT_UID]->peer_uid, peer_uid);
strcpy(chat_thread[CURRENT_UID]->peer_uname, peer_uname);
chat_thread[CURRENT_UID]->status = 0;
//	chat_thread[CURRENT_UID]->clientfd = -1;
//	chat_thread[CURRENT_UID]->trayIcon = gtk_status_icon_new_from_file("ico/qq2.ico");
CURRENT_UID++;
}

guint get_chat_thread_index(char *uid) {
int index;
for(index=0; index < MAXFRIENDS; index++){
if(!strcmp(chat_thread[index]->peer_uid, uid)) break;
}
if (index >= MAXFRIENDS){
format_record("ERROR: Can not find proper uid for chat_thread.");
}
return index;
}

void show_msg(ChatThread *chat_thread, char *msg, int alignment){
add_list_item(GTK_WIDGET(chat_thread->output), msg, alignment);
gtk_widget_show_all(GTK_WIDGET(chat_thread->output));
}

void show_dialog(char *msgtip){
GtkWidget *dialog;
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,"%s",msgtip);
gtk_window_set_title(GTK_WINDOW(dialog), "Information");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}

/*icon******代码**********开始*/

guint change_icon(gpointer data) {
char text[10];
strcpy(text, gtk_status_icon_get_tooltip_text(trayIcon));
if (strcmp(text, USER_NAME) != 0) {
gtk_status_icon_set_from_file(trayIcon, "ico/qq.ico");
gtk_status_icon_set_tooltip(trayIcon, USER_NAME);
} else {
gtk_status_icon_set_from_file(trayIcon, "ico/qq2.ico");
gtk_status_icon_set_tooltip(trayIcon, (((ChatThread *)data)->peer_uid));
}
return 1;
}

guint change_self_icon() {
gtk_status_icon_set_from_file(trayIcon, "ico/qq.ico");
gtk_status_icon_set_tooltip(trayIcon, USER_NAME);
return 1;
}

void trayView(GtkMenuItem *item, gpointer window){
gtk_window_present(GTK_WINDOW(window));
}

void show_about(GtkMenuItem *item, gpointer window){
show_dialog("Personal chat software.\nProblems call QQ:393608596.\nThank you!");
}

void trayIconActivated(GObject *trayIcon, gpointer data){
char peer_uid[10];
strcpy(peer_uid, gtk_status_icon_get_tooltip_text(GTK_STATUS_ICON(trayIcon)));
if(strcmp(peer_uid,USER_NAME) != 0){
chat_1to1_ui(peer_uid);
gtk_status_icon_set_blinking(GTK_STATUS_ICON(trayIcon), FALSE);
change_self_icon(GTK_STATUS_ICON(trayIcon));
}else{
gtk_window_present(GTK_WINDOW(data));
}
}

void trayIconPopup(GtkStatusIcon *status_icon, guint button, guint32 activate_time, gpointer popUpMenu){
gtk_menu_popup(GTK_MENU(popUpMenu), NULL, NULL, gtk_status_icon_position_menu, status_icon, button, activate_time);
}

gboolean delete_event(GtkWidget *window, GdkEvent *event, gpointer data){
return FALSE;
}

gboolean window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer trayIcon) {
if (event->changed_mask == GDK_WINDOW_STATE_ICONIFIED
&& (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED
|| event->new_window_state
== (GDK_WINDOW_STATE_ICONIFIED
| GDK_WINDOW_STATE_MAXIMIZED))) {
gtk_widget_hide(GTK_WIDGET(widget));
} else if (event->changed_mask == GDK_WINDOW_STATE_WITHDRAWN
&& (event->new_window_state == GDK_WINDOW_STATE_ICONIFIED
|| event->new_window_state
== (GDK_WINDOW_STATE_ICONIFIED
| GDK_WINDOW_STATE_MAXIMIZED))) {
}
return TRUE;
}

guint show_trayicon(GtkWidget *window) {
GtkWidget *menu, *menuItemView, *menuItemExit, *about;

trayIcon = gtk_status_icon_new_from_file("ico/qq.ico");
menu = gtk_menu_new();

menuItemView = gtk_menu_item_new_with_label("Window");
about = gtk_menu_item_new_with_label("About");
menuItemExit = gtk_menu_item_new_with_label("Exit");

g_signal_connect(G_OBJECT(menuItemView), "activate", G_CALLBACK(trayView), window);
g_signal_connect(G_OBJECT(about), "activate", G_CALLBACK(show_about), window);
g_signal_connect(G_OBJECT(menuItemExit), "activate", G_CALLBACK(close_app), NULL);

gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItemView);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), about);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItemExit);
gtk_widget_show_all(menu);

gtk_status_icon_set_tooltip(trayIcon, USER_NAME);
gtk_status_icon_set_visible(trayIcon, TRUE);
g_signal_connect(GTK_STATUS_ICON(trayIcon), "activate",
GTK_SIGNAL_FUNC(trayIconActivated), window);
g_signal_connect(GTK_STATUS_ICON(trayIcon), "popup_menu",
GTK_SIGNAL_FUNC(trayIconPopup), menu);

g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(close_app), NULL);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), trayIcon);
g_signal_connect(G_OBJECT(window), "window_state_event", G_CALLBACK(window_state_event), trayIcon);

return 0;
}

void *receive_msg_thread(){
int socketfd;
guint uindex;
char *buf_return, *peer_uid, *peer_uname, *buf_stream;
socketfd = open_udp_server_running(ADDRESS);
buf_return = (char *) malloc(MAXLINE);
buf_stream = (char *) malloc(MAXLINE);
while (1) {
memset(buf_return, '\0', MAXLINE);
memset(buf_stream, '\0', MAXLINE);
receive_udp_msg(socketfd, buf_return);
if (strlen(buf_return) <= 0) break;
peer_uid = strtok(buf_return, split);
peer_uname = strtok(NULL, split);
sprintf(buf_stream, "[%s]: ", peer_uname);
strcat(buf_stream, strtok(NULL, split));
/*
* show the offline msg about save msg of db
* read one record one by one
* do connect db server then get records by recycling output
*/
uindex = get_chat_thread_index(peer_uid);
//		check peer user chat window status[0:closed 1:opened]
if (chat_thread[uindex]->status == 0) {
change_icon(chat_thread[uindex]);
gtk_status_icon_set_blinking(GTK_STATUS_ICON(trayIcon), TRUE);
} else {
show_msg(chat_thread[uindex], buf_stream, PEER_ALIGN);
}
}
free(buf_return);
free(buf_stream);
Close(socketfd);
pthread_exit(0);
}

void fill_model_data(GtkTreeStore *treestore, int opt) {
GtkTreeIter toplevel, child;
int clientfd;
char buf[MAXLINE], *action_type, *role_type, *group_name,
*friend_id, *friend_name, *friend_status;

clientfd = open_tcp_connection();
if (-1 == clientfd) {
return ;
}
sprintf(buf, "FRESH%s%s%sNULL%sNULL", split, USER_ID, split, split);

if (Write(clientfd, buf, sizeof(buf)) < 0) {
format_record(
"ERROR: Write request to server to fresh friend list failed.");
return ;
}
memset(buf, 0, sizeof(buf));
action_type = (char *) malloc(10);
role_type = (char *) malloc(10);
group_name = (char *) malloc(10);
friend_id = (char *) malloc(10);
friend_name = (char *) malloc(20);
friend_status = (char *) malloc(2);

while (1) {
if (Read(clientfd, buf, sizeof(buf)) > 0) {
strcpy(action_type, strtok(buf, split));
strcpy(role_type, strtok(NULL, split));
if (strcmp(role_type, "GROUP") == 0) {
strcpy(group_name, strtok(NULL, split));
gtk_tree_store_append(treestore, &toplevel, NULL );
gtk_tree_store_set(treestore, &toplevel, 0, group_name, -1);
} else if (strcmp(role_type, "FRIEND") == 0) {
gtk_tree_store_append(treestore, &child, &toplevel);

strcpy(friend_id, strtok(NULL, split));
gtk_tree_store_set(treestore, &child, COL_ID, friend_id, -1);
strcpy(friend_name, strtok(NULL, split));
gtk_tree_store_set(treestore, &child, COL_NAME, friend_name, -1);
strcpy(friend_status, strtok(NULL, split));
gtk_tree_store_set(treestore, &child, COL_STATUS,
(atoi(friend_status) == 1) ? "Online" : "Offline", -1);

if(INIT == opt) init_chat_window(friend_id, friend_name);

} else if (strcmp(role_type, "NULL") == 0) {
break;
} else {
// do else
break;
}
} else
break;
}
free(action_type);
free(role_type);
free(group_name);
free(friend_id);
free(friend_name);
free(friend_status);
Close(clientfd);
}

guint refresh_tree_store(GtkWidget *view) {
GtkTreeStore *treestore;
treestore = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(view)));
gtk_tree_store_clear(treestore);
fill_model_data(treestore, REFRESH);
return 1;
}

static GtkTreeModel *create_and_fill_model(void) {
GtkTreeStore *treestore;
treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING);
fill_model_data(treestore, INIT);
return GTK_TREE_MODEL(treestore);
}

static GtkWidget *create_view_and_model(void) {
GtkTreeViewColumn *col[NUM_COLS];
GtkCellRenderer *renderer;
GtkWidget *view;
GtkTreeModel *model;
int col_index;
view = gtk_tree_view_new();
set_widget_bg(view, "ico/bg.jpg");

renderer = gtk_cell_renderer_text_new();
for (col_index = 0; col_index < NUM_COLS; col_index++) {
col[col_index] = gtk_tree_view_column_new();
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col[col_index]);
gtk_tree_view_column_pack_start(col[col_index], renderer, TRUE);
gtk_tree_view_column_add_attribute(col[col_index], renderer, "text", col_index);
gtk_tree_view_column_set_reorderable (col[col_index], TRUE);
}
gtk_tree_view_column_set_title(col[0], "Friends List");

model = create_and_fill_model();
gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
g_object_unref(model);

return view;
}

void chat_1to1_ui(char *peer_uid) {
GtkWidget *table, *entry, *cancle;
GtkWidget *send, *scrollwindow, *frame;
GtkTooltips *tooltips;
GtkAdjustment *horizontal, *vertical;
guint id;

#ifndef DEBUG
id = get_chat_thread_index(peer_uid);
if (chat_thread[id]->status) return;
#else
id = 0;
chat_thread[id] = (ChatThread *)malloc(sizeof(ChatThread));
strcpy(chat_thread[id]->peer_uname, "TestPeer");
#endif

chat_thread[id]->status = 1;
chat_thread[id]->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(chat_thread[id]->window), chat_thread[id]->peer_uname);
gtk_window_set_default_size(GTK_WINDOW(chat_thread[id]->window), 450, 450);
gtk_container_set_border_width(GTK_CONTAINER(chat_thread[id]->window), 15);
gtk_window_set_position(GTK_WINDOW(chat_thread[id]->window), GTK_WIN_POS_CENTER);

table = gtk_table_new(CHAT_WINDOW_SIZE, CHAT_WINDOW_SIZE, TRUE);
gtk_container_add(GTK_CONTAINER(chat_thread[id]->window), table);

chat_thread[id]->output = gtk_list_new();
vertical = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 1, 10, 0));
horizontal = GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 0, 1, 10, 0));

scrollwindow = gtk_scrolled_window_new(horizontal, vertical);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow),
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

frame = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
gtk_table_attach(GTK_TABLE(table), frame, 0, CHAT_WINDOW_SIZE, 0, 6,
GTK_FILL, GTK_FILL, 0, 0);

gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwindow),
chat_thread[id]->output);
gtk_container_add(GTK_CONTAINER(frame), scrollwindow);
gtk_list_scroll_vertical(GTK_LIST(chat_thread[id]->output), GTK_SCROLL_END, 1);

chat_thread[id]->input = gtk_entry_new_with_max_length(100);
gtk_widget_set_size_request(chat_thread[id]->input, 300, 40);
gtk_table_attach_defaults(GTK_TABLE(table), chat_thread[id]->input, 0, 8, 6, 7);
send = gtk_button_new_with_label("send");
gtk_widget_set_size_request(send, 70, 30);
gtk_table_attach(GTK_TABLE(table), send, 7, 8, 7, 8, 0, 0, 0, 0);
cancle = gtk_button_new_with_label("cancle");
gtk_widget_set_size_request(cancle, 70, 30);
gtk_table_attach(GTK_TABLE(table), cancle, 6, 7, 7, 8, 0, 0, 0, 0);

tooltips = gtk_tooltips_new();
gtk_tooltips_set_tip(tooltips, chat_thread[id]->input, "发送内容不能为空", NULL );

#ifndef DEBUG
request_peer_user_address(peer_uid, chat_thread[id]->address);
#else
strcpy(chat_thread[id]->address, "10.10.10.1:1234");
#endif

g_signal_connect(G_OBJECT(send), "clicked", G_CALLBACK(on_send_event),
chat_thread[id]);
g_signal_connect(G_OBJECT(cancle), "clicked", G_CALLBACK(on_clear_entry_event),
chat_thread[id]->input);
g_signal_connect(G_OBJECT(chat_thread[id]->input), "activate", G_CALLBACK(on_send_event),
chat_thread[id]);
g_signal_connect(G_OBJECT(chat_thread[id]->window), "destroy", G_CALLBACK(close_window),
chat_thread[id]);

gtk_widget_show_all(chat_thread[id]->window);
}

gboolean on_2click_record_event(GtkWidget *view, GdkEventButton *event, gpointer data) {
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeSelection *selection;
char *value1 = NULL, *value2 = NULL;

selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
switch (event->type) {
case GDK_2BUTTON_PRESS:
if (event->button != MOUSE_LEFT_CLICK)
break;
if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection),
&model, &iter)) {
gtk_tree_model_get(model, &iter, COL_ID, &value1, COL_NAME, &value2, -1);
if (value1 == NULL || value2 == NULL ) break;
//			chat_1to1_ui(value1, value2);
chat_1to1_ui(value1);
g_free(value1);
g_free(value2);
}
break;
case GDK_BUTTON_PRESS:
break;
default:
format_record("No answer for this action.");
break;
}
return FALSE;
}

void land_ok_ui() {
GtkWidget *land_ok_window, *vbox, *statusbar;
GtkWidget *view;
GtkTreeSelection *selection;
GtkWidget *image, *image_box, *name_label;

char ok_ui_title[33];// len(id)[10] + len(name)[20] +'()'[2] +'\0'[1] = 33
#ifndef DEBUG
memset(ok_ui_title,'\0',sizeof(ok_ui_title));
sprintf(ok_ui_title,"%s(%s)",USER_NAME,USER_ID);
#endif

land_ok_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(land_ok_window), GTK_WIN_POS_MOUSE);
gtk_window_set_icon_from_file(GTK_WINDOW(land_ok_window), "ico/qq.ico", NULL);
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(land_ok_window), TRUE); // hide taskbar
gtk_widget_set_size_request(land_ok_window, 280, 500);
gtk_window_set_title(GTK_WINDOW(land_ok_window), ok_ui_title);

vbox = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(land_ok_window), vbox);

name_label = gtk_label_new(USER_NAME);
image = gtk_image_new_from_file("ico/qq.ico");
image_box = gtk_hbox_new(FALSE, 10);
gtk_box_pack_start(GTK_BOX(image_box), image, TRUE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(image_box), name_label, TRUE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), image_box, FALSE, FALSE, 0);
#ifndef DEBUG
view = create_view_and_model();
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);

statusbar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 1);

g_signal_connect(selection, "changed", G_CALLBACK(on_changed_event), statusbar);
g_signal_connect(view, "button_press_event", G_CALLBACK(on_2click_record_event),
NULL );
g_signal_connect(G_OBJECT(land_ok_window), "destroy", G_CALLBACK(on_logout_event),
NULL );

g_timeout_add(6000, (GtkFunction)refresh_tree_store, view);
#else
g_signal_connect(G_OBJECT(land_ok_window), "destroy", G_CALLBACK(gtk_main_quit),
NULL);
#endif

show_trayicon(land_ok_window);
#ifndef DEBUG
pthread_create(&recv_msg_tid, NULL, receive_msg_thread, NULL);
#endif
gtk_widget_show_all(land_ok_window);
gtk_main();
}

void show_login_status(GtkWidget *button, gpointer login_info_label) {
const char *error_show =
"<span foreground=\"red\"><b>Access denied!</b></span>";
const char *info_show =
"<span foreground=\"green\"><b>Access granted!</b></span>";
if (LOGIN_STATUS == LOGIN_SUCCESS) {
//		gtk_label_set_markup(GTK_LABEL(login_info_label), info_show);
close_window(window, NULL );
land_ok_ui();
} else {
gtk_label_set_markup(GTK_LABEL(login_info_label), error_show);
}
}

void land_interface() {
GtkWidget *username_label, *password_label;
GtkWidget *username_entry, *password_entry;
GtkWidget *ok_button;
GtkWidget *hbox1, *hbox2, *hbox3, *vbox;
GtkWidget *left_blank_label, *right_blank_label, *login_info_label;
UserInfoGtk user_info;

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "GtkLogin");
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 200, 150);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);

g_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(close_app),
NULL );

username_label = gtk_label_new("Username:");
password_label = gtk_label_new("Password:");
user_info.username_entry = username_entry = gtk_entry_new_with_max_length(10);
user_info.password_entry = password_entry = gtk_entry_new_with_max_length(10);
gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);

left_blank_label = gtk_label_new("");
right_blank_label = gtk_label_new("");
ok_button = gtk_button_new_with_label("Login");
login_info_label = gtk_label_new("");

g_signal_connect(GTK_OBJECT(ok_button), "clicked",
GTK_SIGNAL_FUNC(on_login_event), &user_info);
g_signal_connect(G_OBJECT(username_entry), "activate",
G_CALLBACK(on_login_event),&user_info);
g_signal_connect(G_OBJECT(password_entry), "activate",
G_CALLBACK(on_login_event),&user_info);
g_signal_connect(GTK_OBJECT(ok_button), "clicked",
GTK_SIGNAL_FUNC(show_login_status), login_info_label);
g_signal_connect(GTK_OBJECT(ok_button), "clicked",
GTK_SIGNAL_FUNC(on_clear_entry_event), password_entry);

hbox1 = gtk_hbox_new(TRUE, 0);
hbox2 = gtk_hbox_new(TRUE, 0);
hbox3 = gtk_hbox_new(TRUE, 0);
vbox = gtk_vbox_new(FALSE, 0);

gtk_box_pack_start(GTK_BOX(hbox1), username_label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox1), username_entry, FALSE, FALSE, 5);

gtk_box_pack_start(GTK_BOX(hbox2), password_label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox2), password_entry, FALSE, FALSE, 5);

gtk_box_pack_start(GTK_BOX(hbox3), left_blank_label, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(hbox3), ok_button, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox3), right_blank_label, FALSE, FALSE, 5);

gtk_box_pack_start(GTK_BOX(vbox), hbox1, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox3, FALSE, FALSE, 5);

gtk_box_pack_start(GTK_BOX(vbox), login_info_label, FALSE, FALSE, 3);

gtk_container_add(GTK_CONTAINER(window), vbox);

set_widget_bg(window, "ico/bg.jpg");

gtk_widget_show_all(window);
gtk_main();
}
//const_global.h 全局变量和通用头文件的包含头文件

#ifndef CONST_GLOBAL_H
#define CONST_GLOBAL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <time.h>
#include <sys/types.h>
#include <regex.h>
#include <memory.h>

#include "xini.h"

#define MOUSE_LEFT_CLICK 0x1
#define MOUSE_MIDDLE_CLICK 0x2
#define MOUSE_RIGHT_CLICK 0x3

#define CHAT_WINDOW_SIZE 8
#define MAXFRIENDS 10
#define MAX_SQL_LEN 180
#define MAXLINE 200

// define show the alignment
#define PEER_ALIGN 0
#define SELF_ALIGN 1
// peer: left
// self: right

#define CLIENT_CFG_FILE "config/client_cfg.ini"
#define SERVER_CFG_FILE "config/server_cfg.ini"

enum {
LOGIN_OFF = 0, LOGIN_ON, LOGIN_SUCCESS, LOGIN_FAILED
};

enum {
COL_ID = 0, COL_NAME, COL_STATUS, NUM_COLS
};

enum {
REGISTER = 0, LOGIN, SEND_MEG, SEND_FILE, EXIT
};

static int LOGIN_STATUS = 0;
static char USER_ID[10];
static char USER_NAME[20];
static char ADDRESS[30]; //such as "IP:PORT"
static char split[10] = "#@@#";

static XINI ini ;

#endif


先发这些吧,通讯相关的(socket、pthread)下次贴出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: