Linux QQ之客户端
2014-04-15 17:50
351 查看
客户端之登录UI
//client.c 客户端主函数
先发这些吧,通讯相关的(socket、pthread)下次贴出。
//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)下次贴出。
相关文章推荐
- 腾讯封杀所有Linux/Mac版QQ客户端
- linux下qq客户端
- 模仿QQ客户端和服务器(支持window和linux)
- Linux下的QQ客户端EVA初试以及ibus输入法问题的解决方法
- Linux QQ之客户端(续)
- 练手毛坯作品基于LINUX的"QQ闹眼子版本"(包括服务器与客户端<图形版与SHELL文字版>)
- 利用 Prism 和 Web QQ 配置 Linux 的 QQ 客户端
- Linux图形界面中客户端、服务器、窗口管理器之间的关系
- “LINUX系统”与“客户端”语言设置“不一致”导致“显示乱码”
- linux 客户端与linux服务器端连接与文件上传下载
- linux安装telnet服务端客户端
- 【Linux网络编程】基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
- 使用Active Directory执行Linux客户端身份验证
- 关于:Centoslinux 远程连接服务器时客户端一直显示:连接已复位,重新连接到(ip)
- Windows文件备份至linux客户端
- redis在linux下使用客户端
- 在Linux 上安装 QQ 这种聊天软件的方式来了解一下
- 利用TabHost制作QQ客户端标签栏效果(低版本QQ)
- 基于linux的socket编程实现ftp客户端