/** * 绑定iptux程序的服务监听端口. */ void bind_iptux_port() { struct sockaddr_in addr; int tcpsock, udpsock; tcpsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); socket_enable_reuse(tcpsock); udpsock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); socket_enable_reuse(udpsock); socket_enable_broadcast(udpsock); if ((tcpsock == -1) || (udpsock == -1)) { pop_error(_("Fatal Error!!\nFailed to create new socket!\n%s"), strerror(errno)); exit(1); } bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(IPTUX_DEFAULT_PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(tcpsock, (struct sockaddr *)&addr, sizeof(addr)) == -1 || bind(udpsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { close(tcpsock); close(udpsock); pop_error(_("Fatal Error!!\nFailed to bind the TCP/UDP port(2425)!\n%s"), strerror(errno)); exit(1); } cthrd.TcpSockQuote() = tcpsock; cthrd.UdpSockQuote() = udpsock; }
int main(int argc, char *argv[]) { QApplication a(argc, argv); CoreThread *coreThread = new CoreThread; //Start window MainWindow w(coreThread); w.show(); //init core system QThread *thread = new QThread; DisplayDriver *DD = new DisplayDriver; w.setConnexions(coreThread, DD); coreThread->moveToThread(thread); DD->moveToThread(thread); thread->start(); //Debug qDebug() << "hello from GUI thread : " << a.thread()->currentThreadId(); //If flash file in parameter if (argc > 1) { QString flashLink; //Get OS flashLink = argv[1]; //Start core thread w.initCoreSignal(flashLink, DD); } //Main loop a.exec(); //End delete thread; delete DD; delete coreThread; return 0; }
/** * 好友信息数据丢失默认处理函数. * 若xx并不在好友列表中,但是程序却期望能够接受xx的本次会话, * 所以必须以默认数据构建好友信息数据并插入好友列表 \n */ void UdpData::SomeoneLost() { PalInfo *pal; /* 创建好友数据 */ pal = new PalInfo; pal->ipv4 = ipv4; pal->segdes = progdt.FindNetSegDescription(ipv4); if (!(pal->version = iptux_get_section_string(buf, ':', 0))) pal->version = g_strdup("?"); if (!(pal->user = iptux_get_section_string(buf, ':', 2))) pal->user = g_strdup("???"); if (!(pal->host = iptux_get_section_string(buf, ':', 3))) pal->host = g_strdup("???"); pal->name = g_strdup(_("mysterious")); pal->group = g_strdup(_("mysterious")); pal->photo = NULL; pal->sign = NULL; pal->iconfile = g_strdup(progdt.palicon); pal->encode = g_strdup(encode ? encode : "utf-8"); FLAG_SET(pal->flags, 1); pal->packetn = 0; pal->rpacketn = 0; /* 加入好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.AttachPalToList(pal); pthread_mutex_unlock(cthrd.GetMutex()); mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); }
/** * 好友更改个人信息. */ void UdpData::SomeoneAbsence() { PalInfo *pal; const char *ptr; /* 若好友不兼容iptux协议,则需转码 */ pal = cthrd.GetPalFromList(ipv4); //利用好友链表只增不减的特性,无须加锁 ptr = iptux_skip_string(buf, size, 3); if (!ptr || *ptr == '\0') ConvertEncode(pal ? pal->encode : progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if (pal) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); }
/** * 好友对话框入口. * @param grpinf 好友群组信息 */ void DialogPeer::PeerDialogEntry(GroupInfo *grpinf) { DialogPeer *dlgpr; GtkWidget *window, *widget; dlgpr = new DialogPeer(grpinf); window = dlgpr->CreateMainWindow(); gtk_container_add(GTK_CONTAINER(window), dlgpr->CreateAllArea()); gtk_widget_show_all(window); /* 将焦点置于文本输入框 */ widget = GTK_WIDGET(g_datalist_get_data(&dlgpr->widset, "input-textview-widget")); gtk_widget_grab_focus(widget); /* 从消息队列中移除 */ pthread_mutex_lock(cthrd.GetMutex()); if (cthrd.MsglineContainItem(grpinf)) { mwin.MakeItemBlinking(grpinf, FALSE); cthrd.PopItemFromMsgline(grpinf); } pthread_mutex_unlock(cthrd.GetMutex()); /* delete dlgpr;//请不要这样做,此类将会在窗口被摧毁后自动释放 */ }
/** * 好友请求本计算机的共享文件. */ void UdpData::SomeoneAskShared() { Command cmd; pthread_t pid; PalInfo *pal; const char *limit; char *passwd; if (!(pal = cthrd.GetPalFromList(ipv4))) return; limit = cthrd.GetAccessPublicLimit(); if (!limit || *limit == '\0') { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } else if (!(iptux_get_dec_number(buf, ':', 4) & IPTUX_PASSWDOPT)) { cmd.SendFileInfo(cthrd.UdpSockQuote(), pal, IPTUX_SHAREDOPT | IPTUX_PASSWDOPT, ""); } else if ( (passwd = ipmsg_get_attach(buf, ':', 5))) { if (strcmp(passwd, limit) == 0) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } g_free(passwd); } }
/** * 好友发送个性签名. */ void UdpData::SomeoneSendSign() { PalInfo *pal; char *sign; if (!(pal = cthrd.GetPalFromList(ipv4))) return; /* 若好友不兼容iptux协议,则需转码 */ if (!FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal->encode); /* 对编码作适当调整 */ if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 更新 */ if ( (sign = ipmsg_get_attach(buf, ':', 5))) { g_free(pal->sign); pal->sign = sign; gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.UpdateItemToPaltree(ipv4); gdk_threads_leave(); } }
/** * 发送本机共享文件信息入口. * @param pal class PalInfo */ void SendFile::SendSharedInfoEntry(PalInfo *pal) { GSList *list; pthread_mutex_lock(cthrd.GetMutex()); list = cthrd.GetPublicFileList(); SendFileInfo(pal, IPTUX_SHAREDOPT, list); pthread_mutex_unlock(cthrd.GetMutex()); }
/** * 请求获取此好友的共享文件. * @param grpinf 好友群组信息 */ void DialogPeer::AskSharedFiles(GroupInfo *grpinf) { Command cmd; PalInfo *pal; if (!(grpinf->member)) pal = cthrd.GetPalFromList(grpinf->grpid); else pal = (PalInfo *)grpinf->member->data; cmd.SendAskShared(cthrd.UdpSockQuote(), pal, 0, NULL); }
/** * 好友退出. */ void UdpData::SomeoneExit() { PalInfo *pal; /* 从好友链表中删除 */ gdk_threads_enter(); if (mwin.PaltreeContainItem(ipv4)) mwin.DelItemFromPaltree(ipv4); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { cthrd.DelPalFromList(ipv4); FLAG_CLR(pal->flags, 1); } pthread_mutex_unlock(cthrd.GetMutex()); gdk_threads_leave(); }
/** *从接收文件的TreeView删除选定行(待接收和已接收都用此函数). * @param widget TreeView */ void DialogPeer::RemoveSelectedRcv(GtkWidget *widget) { GtkTreeModel *model; GtkTreeSelection *TreeSel; GtkTreeIter iter; FileInfo *file; DialogPeer *dlg; GList *list; dlg = (DialogPeer *)(g_object_get_data(G_OBJECT(widget),"dialog")); model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); //从中心结点删除 TreeSel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); list = gtk_tree_selection_get_selected_rows(TreeSel,NULL); if(!list) return; while(list) { gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, (GtkTreePath *)g_list_nth(list, 0)->data); gtk_tree_model_get(model, &iter,5,&file, -1); cthrd.PopItemFromEnclosureList(file); list = g_list_next(list); } g_list_free(list); //从列表中删除 RemoveSelectedFromTree(widget); //重新刷新窗口显示 dlg->ShowInfoEnclosure(dlg); }
/** * 回馈消息. * @param dtlist 数据链表 * @note 请不要修改链表(dtlist)中的数据 */ void DialogPeer::FeedbackMsg(const GSList *dtlist) { MsgPara para; /* 构建消息封装包 */ if (grpinf->member) para.pal = (PalInfo *)grpinf->member->data; else para.pal = cthrd.GetPalFromList(grpinf->grpid); para.stype = MESSAGE_SOURCE_TYPE_SELF; para.btype = grpinf->type; para.dtlist = (GSList *)dtlist; /* 交给某人处理吧 */ cthrd.InsertMsgToGroupInfoItem(grpinf, ¶); para.dtlist = NULL; //防止参数数据被修改 }
/** * 好友发送头像数据. */ void UdpData::SomeoneSendIcon() { PalInfo *pal; char *iconfile; if (!(pal = cthrd.GetPalFromList(ipv4)) || FLAG_ISSET(pal->flags, 2)) return; /* 接收并更新数据 */ if ( (iconfile = RecvPalIcon())) { g_free(pal->iconfile); pal->iconfile = iconfile; gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.UpdateItemToPaltree(ipv4); gdk_threads_leave(); } }
/** * 好友接收到消息. */ void UdpData::SomeoneRecvmsg() { uint32_t packetno; PalInfo *pal; if ( (pal = cthrd.GetPalFromList(ipv4))) { packetno = iptux_get_dec_number(buf, ':', 5); if (packetno == pal->rpacketn) pal->rpacketn = 0; //标记此包编号已经被回复 } }
/** * 好友上线. */ void UdpData::SomeoneEntry() { Command cmd; pthread_t pid; PalInfo *pal; /* 转换缓冲区数据编码 */ ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 通知好友本大爷在线 */ cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } }
/** * 确保好友一定在线. * @return 好友数据 */ PalInfo *UdpData::AssertPalOnline() { PalInfo *pal; if ( (pal = cthrd.GetPalFromList(ipv4))) { /* 既然好友不在线,那么他自然不在列表中 */ if (!FLAG_ISSET(pal->flags, 1)) { FLAG_SET(pal->flags, 1); gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); cthrd.UpdatePalToList(ipv4); pthread_mutex_unlock(cthrd.GetMutex()); mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); } } else { SomeoneLost(); pal = cthrd.GetPalFromList(ipv4); } return pal; }
/** * 请求文件数据入口. * @param sock tcp socket * @param fileattr 文件类型 * @param attach 附加数据 */ void SendFile::RequestDataEntry(int sock, uint32_t fileattr, char *attach) { struct sockaddr_in addr; socklen_t len; PalInfo *pal; FileInfo *file; uint32_t fileid; uint32_t filectime; /* 检查文件属性是否匹配 */ fileid = iptux_get_hex_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAll(fileid); /* 兼容windows版信鸽(IPMSG) ,这里的信鸽不是飞鸽传书(IPMSG)*/ if(!file) { fileid = iptux_get_dec_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAll(fileid); } /* 兼容adroid版信鸽(IPMSG) */ if(!file) { fileid = iptux_get_hex_number(attach, ':', 0); filectime = iptux_get_dec_number(attach, ':', 1); file = (FileInfo *)cthrd.GetFileFromAllWithPacketN(fileid,filectime); } if (!file || GET_MODE(file->fileattr) != GET_MODE(fileattr)) return; /* 检查好友数据是否存在 */ len = sizeof(addr); getpeername(sock, (struct sockaddr *)&addr, &len); if (!(pal = cthrd.GetPalFromList(addr.sin_addr.s_addr))) return; /* 发送文件数据 */ // /** // *文件信息可能被删除或修改,必须单独复制一份. // */ // file->fileown = pal; ThreadSendFile(sock, file); }
/** * 请求获取好友共享文件的密码. * @param pal class PalInfo */ void UdpData::ThreadAskSharedPasswd(PalInfo *pal) { Command cmd; gchar *passwd, *epasswd; gdk_threads_enter(); passwd = pop_obtain_shared_passwd(pal); gdk_threads_leave(); if (passwd && *passwd != '\0') { epasswd = g_base64_encode((guchar *)passwd, strlen(passwd)); cmd.SendAskShared(cthrd.UdpSockQuote(), pal, IPTUX_PASSWDOPT, epasswd); g_free(epasswd); } g_free(passwd); }
/** * 封装消息. * @param dtlist 数据链表 * @return 消息封装包 */ MsgPara *DialogPeer::PackageMsg(GSList *dtlist) { MsgPara *para; para = new MsgPara; if (!(grpinf->member)) para->pal = cthrd.GetPalFromList(grpinf->grpid); else para->pal = (PalInfo *)grpinf->member->data; para->stype = MESSAGE_SOURCE_TYPE_SELF; para->btype = grpinf->type; para->dtlist = dtlist; return para; }
/** * 广播文件信息. * @param plist 好友链表 * @param opttype 命令字选项 * @param filist 文件信息链表 */ void SendFile::BcstFileInfo(GSList *plist, uint32_t opttype, GSList *filist) { AnalogFS afs; Command cmd; char buf[MAX_UDPLEN]; size_t len; char *ptr, *name; GSList *tlist,*pallist,*filelist; FileInfo *file; /* 初始化 */ len = 0; ptr = buf; buf[0] = '\0'; pallist = plist; /* 将文件信息写入缓冲区 */ while (pallist) { filelist = filist; while (filelist) { file = (FileInfo *)filelist->data; if(file->fileown == (PalInfo *)pallist->data) { if (access(file->filepath, F_OK) == -1) { filelist = g_slist_next(filelist); continue; } file->waitFlag = 1; name = ipmsg_get_filename_pal(file->filepath); //获取面向好友的文件名 file->filesize = afs.ftwsize(file->filepath); //不得不计算文件长度了 file->packetn = cmd.Packetn(); snprintf(ptr, MAX_UDPLEN - len, "%" PRIu32 ":%s:%" PRIx64 ":%" PRIx32 ":%" PRIx32 ":\a:", file->fileid, name, file->filesize, file->filectime, file->fileattr); g_free(name); len += strlen(ptr); ptr = buf + len; } filelist = g_slist_next(filelist); } cmd.SendFileInfo(cthrd.UdpSockQuote(), (PalInfo *)pallist->data, opttype, buf); pallist = g_slist_next(pallist); } g_slist_free(filelist); }
/** * 分派UDP数据到相应的函数去进行处理. */ void UdpData::DispatchUdpData() { uint32_t commandno; /* 如果开启了黑名单处理功能,且此地址正好被列入了黑名单 */ /* 嘿嘿,那就不要怪偶心狠手辣了 */ if (FLAG_ISSET(progdt.flags, 1) && cthrd.BlacklistContainItem(ipv4)) return; /* 决定消息去向 */ commandno = iptux_get_dec_number(buf, ':', 4); switch (GET_MODE(commandno)) { case IPMSG_BR_ENTRY: SomeoneEntry(); break; case IPMSG_BR_EXIT: SomeoneExit(); break; case IPMSG_ANSENTRY: SomeoneAnsentry(); break; case IPMSG_BR_ABSENCE: SomeoneAbsence(); break; case IPMSG_SENDMSG: SomeoneSendmsg(); break; case IPMSG_RECVMSG: SomeoneRecvmsg(); break; case IPTUX_ASKSHARED: SomeoneAskShared(); break; case IPTUX_SENDICON: SomeoneSendIcon(); break; case IPTUX_SENDSIGN: SomeoneSendSign(); break; case IPTUX_SENDMSG: SomeoneBcstmsg(); break; default: break; } }
/** * 插入消息. * @param pal class PalInfo * @param btype 消息所属类型 * @param msg 消息 */ void UdpData::InsertMessage(PalInfo *pal, GroupBelongType btype, const char *msg) { MsgPara para; ChipData *chip; /* 构建消息封装包 */ para.pal = pal; para.stype = MESSAGE_SOURCE_TYPE_PAL; para.btype = btype; chip = new ChipData; chip->type = MESSAGE_CONTENT_TYPE_STRING; chip->data = g_strdup(msg); para.dtlist = g_slist_append(NULL, chip); /* 交给某人处理吧 */ cthrd.InsertMessage(¶); }
/** * 回馈错误消息. * @param pal class PalInfo * @param btype 消息归属类型 * @param error 错误串 */ void Command::FeedbackError(PalInfo *pal, GroupBelongType btype, const char *error) { MsgPara para; ChipData *chip; /* 构建消息封装包 */ para.pal = pal; para.stype = MESSAGE_SOURCE_TYPE_ERROR; para.btype = btype; chip = new ChipData; chip->type = MESSAGE_CONTENT_TYPE_STRING; chip->data = g_strdup(error); para.dtlist = g_slist_append(NULL, chip); /* 交给某人处理吧 */ cthrd.InsertMessage(¶); }
/** * 接收好友文件信息. */ void UdpData::RecvPalFile() { uint32_t packetno, commandno; const char *ptr; pthread_t pid; GData *para; packetno = iptux_get_dec_number(buf, ':', 1); commandno = iptux_get_dec_number(buf, ':', 4); ptr = iptux_skip_string(buf, size, 1); /* 只有当此为共享文件信息或文件信息不为空才需要接收 */ if ((commandno & IPTUX_SHAREDOPT) || (ptr && *ptr != '\0')) { para = NULL; g_datalist_init(¶); g_datalist_set_data(¶, "palinfo", cthrd.GetPalFromList(ipv4)); g_datalist_set_data_full(¶, "extra-data", g_strdup(ptr), GDestroyNotify(g_free)); g_datalist_set_data(¶, "packetno", GUINT_TO_POINTER(packetno)); g_datalist_set_data(¶, "commandno", GUINT_TO_POINTER(commandno)); pthread_create(&pid, NULL, ThreadFunc(RecvFile::RecvEntry), para); pthread_detach(pid); } }
/** * 发送文件信息. * @param pal class PalInfo * @param opttype 命令字选项 * @param filist 文件信息链表 */ void SendFile::SendFileInfo(PalInfo *pal, uint32_t opttype, GSList *filist) { AnalogFS afs; Command cmd; char buf[MAX_UDPLEN]; size_t len; char *ptr, *name; GSList *tlist; FileInfo *file; /* 初始化 */ len = 0; ptr = buf; buf[0] = '\0'; /* 将文件信息写入缓冲区 */ tlist = filist; while (tlist) { file = (FileInfo *)tlist->data; if (access(file->filepath, F_OK) == -1) { tlist = g_slist_next(tlist); continue; } name = ipmsg_get_filename_pal(file->filepath); //获取面向好友的文件名 file->packetn = cmd.Packetn(); snprintf(ptr, MAX_UDPLEN - len, "%" PRIu32 ":%s:%" PRIx64 ":%" PRIx32 ":%" PRIx32 ":\a", file->fileid, name, file->filesize, file->filectime, file->fileattr); g_free(name); len += strlen(ptr); ptr = buf + len; tlist = g_slist_next(tlist); } /* 发送文件信息 */ cmd.SendFileInfo(cthrd.UdpSockQuote(), pal, opttype, buf); }
/** * 发送文本消息. * @param para 消息参数 */ void DialogPeer::ThreadSendTextMsg(MsgPara *para) { Command cmd; GSList *tlist; char *ptr; int sock; tlist = para->dtlist; while (tlist) { ptr = ((ChipData *)tlist->data)->data; switch (((ChipData *)tlist->data)->type) { case MESSAGE_CONTENT_TYPE_STRING: /* 文本类型 */ cmd.SendMessage(cthrd.UdpSockQuote(), para->pal, ptr); break; case MESSAGE_CONTENT_TYPE_PICTURE: /* 图片类型 */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { pop_error(_("Fatal Error!!\nFailed to create new socket!" "\n%s"), strerror(errno)); exit(1); } cmd.SendSublayer(sock, para->pal, IPTUX_MSGPICOPT, ptr); close(sock); //关闭网络套接口 /*/* 删除此图片 */ unlink(ptr); //此文件已无用处 break; default: break; } tlist = g_slist_next(tlist); } /* 释放资源 */ delete para; }
/** * 好友在线. */ void UdpData::SomeoneAnsentry() { Command cmd; pthread_t pid; PalInfo *pal; const char *ptr; /* 若好友不兼容iptux协议,则需转码 */ ptr = iptux_skip_string(buf, size, 3); if (!ptr || *ptr == '\0') ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 更新本大爷的数据信息 */ if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } else if (strcasecmp(progdt.encode, pal->encode) != 0) cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); }
/** * 显示信息/文件接收UI(是否显示信息或文件接收). * */ void DialogPeer::ShowInfoEnclosure(DialogPeer *dlgpr) { PalInfo *palinfor; GtkTreeModel *mdltorcv,*mdlrcvd,*mdltmp; GSList *ecslist; GtkWidget *widget,*hpaned,*pbar; float progress; GdkPixbuf *pixbuf, *rpixbuf, *dpixbuf; FileInfo *file; gchar *filesize,*path; char progresstip[MAX_BUFLEN]; GtkTreeIter iter; gint receiving;//标记是不是窗口在正传送文件时被关闭,又打开的。 receiving = 0; /* 获取文件图标 */ rpixbuf = obtain_pixbuf_from_stock(GTK_STOCK_FILE); dpixbuf = obtain_pixbuf_from_stock(GTK_STOCK_DIRECTORY); //设置界面显示 palinfor = (PalInfo *)(dlgpr->grpinf->member->data); mdltorcv = (GtkTreeModel*)g_datalist_get_data(&(dlgpr->mdlset), "file-to-receive-model"); gtk_list_store_clear(GTK_LIST_STORE(mdltorcv)); mdlrcvd = (GtkTreeModel*)g_datalist_get_data(&(dlgpr->mdlset), "file-received-model"); gtk_list_store_clear(GTK_LIST_STORE(mdlrcvd)); ecslist = cthrd.GetPalEnclosure(palinfor); if(ecslist) { //只要有该好友的接收文件信息(不分待接收和未接收),就显示 hpaned = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset), "main-paned")); widget = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset), "info-frame")); gtk_widget_hide(widget); widget = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset),"file-enclosure-frame-widget")); gtk_paned_pack2(GTK_PANED(hpaned), widget, FALSE, TRUE); widget = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset),"file-receive-paned-widget")); gtk_widget_show(widget); //将从中心节点取到的数据向附件接收列表填充 dlgpr->torcvsize = 0; while (ecslist) { file = (FileInfo *)ecslist->data; filesize = numeric_to_size(file->filesize); switch (GET_MODE(file->fileattr)) { case IPMSG_FILE_REGULAR: pixbuf = rpixbuf; break; case IPMSG_FILE_DIR: pixbuf = dpixbuf; break; default: pixbuf = NULL; break; } if(file->finishedsize < file->filesize) { file->filepath = ipmsg_get_filename_me(file->filepath,&path); if(file->finishedsize > 0) receiving += 1; mdltmp = mdltorcv; dlgpr->torcvsize += file->filesize; } else mdltmp = mdlrcvd; gtk_list_store_append(GTK_LIST_STORE(mdltmp), &iter); gtk_list_store_set(GTK_LIST_STORE(mdltmp), &iter, 0, pixbuf, 1, file->fileown->name, 2, file->filepath, 3, filesize, 5,file, -1); g_free(filesize); ecslist = g_slist_next(ecslist); } g_slist_free(ecslist); //设置进度条,如果接收完成重新载入待接收和已接收列表 if(dlgpr->torcvsize == 0) { progress = 0; snprintf(progresstip, MAX_BUFLEN,_("Receiving Progress.")); } else { if(dlgpr->rcvdsize == 0) snprintf(progresstip, MAX_BUFLEN,_("%s to Receive."), numeric_to_size(dlgpr->torcvsize)); else { progress = percent(dlgpr->rcvdsize,dlgpr->torcvsize)/100; snprintf(progresstip, MAX_BUFLEN, _("%s Of %s Received."), numeric_to_size(dlgpr->rcvdsize),numeric_to_size(dlgpr->torcvsize)); } } if(progress == 1.0){ g_source_remove(dlgpr->timerrcv); snprintf(progresstip, MAX_BUFLEN,_("Mission Completed!")); } pbar = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset), "file-receive-progress-bar-widget")); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pbar),progress); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pbar),progresstip); } else { widget = GTK_WIDGET(g_datalist_get_data(&(dlgpr->widset), "file-receive-paned-widget")); gtk_widget_hide(widget); } /* 释放文件图标 */ if (rpixbuf) g_object_unref(rpixbuf); if (dpixbuf) g_object_unref(dpixbuf); if(receiving > 0) dlgpr->ReceiveFile(dlgpr); }
/** * 好友广播消息. */ void UdpData::SomeoneBcstmsg() { GroupInfo *grpinf; PalInfo *pal; uint32_t commandno, packetno; char *text; /* 如果对方兼容iptux协议,则无须再转换编码 */ pal = cthrd.GetPalFromList(ipv4); if (!pal || !FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal ? pal->encode : progdt.encode); /* 确保好友在线,并对编码作出适当调整 */ pal = AssertPalOnline(); if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 检查此消息是否过时 */ packetno = iptux_get_dec_number(buf, ':', 1); if (packetno <= pal->packetn) return; pal->packetn = packetno; /* 插入消息&在消息队列中注册 */ text = ipmsg_get_attach(buf, ':', 5); if (text && *text != '\0') { commandno = iptux_get_dec_number(buf, ':', 4); /*/* 插入消息 */ switch (GET_OPT(commandno)) { case IPTUX_BROADCASTOPT: InsertMessage(pal, GROUP_BELONG_TYPE_BROADCAST, text); break; case IPTUX_GROUPOPT: InsertMessage(pal, GROUP_BELONG_TYPE_GROUP, text); break; case IPTUX_SEGMENTOPT: InsertMessage(pal, GROUP_BELONG_TYPE_SEGMENT, text); break; case IPTUX_REGULAROPT: default: InsertMessage(pal, GROUP_BELONG_TYPE_REGULAR, text); break; } /*/* 注册消息 */ pthread_mutex_lock(cthrd.GetMutex()); switch (GET_OPT(commandno)) { case IPTUX_BROADCASTOPT: grpinf = cthrd.GetPalBroadcastItem(pal); break; case IPTUX_GROUPOPT: grpinf = cthrd.GetPalGroupItem(pal); break; case IPTUX_SEGMENTOPT: grpinf = cthrd.GetPalSegmentItem(pal); break; case IPTUX_REGULAROPT: default: grpinf = cthrd.GetPalRegularItem(pal); break; } if (!grpinf->dialog && !cthrd.MsglineContainItem(grpinf)) cthrd.PushItemToMsgline(grpinf); pthread_mutex_unlock(cthrd.GetMutex()); } g_free(text); /* 播放提示音 */ if (FLAG_ISSET(progdt.sndfgs, 1)) sndsys.Playing(progdt.msgtip); }
/** * 好友发送消息. * */ void UdpData::SomeoneSendmsg() { GroupInfo *grpinf; PalInfo *pal; Command cmd; uint32_t commandno, packetno; char *text; pthread_t pid; DialogPeer *dlgpr; GtkWidget *window; /* 如果对方兼容iptux协议,则无须再转换编码 */ pal = cthrd.GetPalFromList(ipv4); if (!pal || !FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal ? pal->encode : progdt.encode); /* 确保好友在线,并对编码作出适当调整 */ pal = AssertPalOnline(); if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 回复好友并检查此消息是否过时 */ commandno = iptux_get_dec_number(buf, ':', 4); packetno = iptux_get_dec_number(buf, ':', 1); if (commandno & IPMSG_SENDCHECKOPT) cmd.SendReply(cthrd.UdpSockQuote(), pal, packetno); if (packetno <= pal->packetn) return; pal->packetn = packetno; /* 插入消息&在消息队列中注册 */ text = ipmsg_get_attach(buf, ':', 5); if (text && *text != '\0') { /*/* 插入消息 */ // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // InsertMessage(pal, GROUP_BELONG_TYPE_BROADCAST, text); // else InsertMessage(pal, GROUP_BELONG_TYPE_REGULAR, text); } g_free(text); /*/* 注册消息 */ pthread_mutex_lock(cthrd.GetMutex()); // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // grpinf = cthrd.GetPalBroadcastItem(pal); // else grpinf = cthrd.GetPalRegularItem(pal); if (!grpinf->dialog && !cthrd.MsglineContainItem(grpinf)) cthrd.PushItemToMsgline(grpinf); pthread_mutex_unlock(cthrd.GetMutex()); /* 标记位处理 先处理底层数据,后面显示窗口*/ if (commandno & IPMSG_FILEATTACHOPT) { if ((commandno & IPTUX_SHAREDOPT) && (commandno & IPTUX_PASSWDOPT)) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedPasswd), pal); pthread_detach(pid); } else RecvPalFile(); } window = GTK_WIDGET(grpinf->dialog); //这里不知道为什么运行时一直会提示window不是object dlgpr = (DialogPeer *)(g_object_get_data(G_OBJECT(window),"dialog")); if(grpinf->dialog) dlgpr->ShowDialogPeer(dlgpr); /* 是否直接弹出聊天窗口 */ if (FLAG_ISSET(progdt.flags, 7)) { gdk_threads_enter(); if (!(grpinf->dialog)) { // switch (grpinf->type) { // case GROUP_BELONG_TYPE_REGULAR: DialogPeer::PeerDialogEntry(grpinf); // break; // case GROUP_BELONG_TYPE_SEGMENT: // case GROUP_BELONG_TYPE_GROUP: // case GROUP_BELONG_TYPE_BROADCAST: // DialogGroup::GroupDialogEntry(grpinf); // default: // break; // } } else { gtk_window_present(GTK_WINDOW(grpinf->dialog)); } gdk_threads_leave(); } /* 播放提示音 */ if (FLAG_ISSET(progdt.sndfgs, 1)) sndsys.Playing(progdt.msgtip); }