void WmLButtonDblclkProc(HWND hwnd, LPARAM lParam){ ChannelData *cd; bool changeFlg = FALSE; ChannelDataLock.on(); cd = channelDataTop; while(cd){ int x = LOWORD(lParam); int y = HIWORD(lParam); if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){ if (!(cd->isSelected())){ changeFlg = TRUE; } if (!(cd->getOpenFlg())){ changeFlg = TRUE; cd->setOpenFlg(TRUE); } else { changeFlg = TRUE; cd->setOpenFlg(FALSE); } cd->setSelected(TRUE); } else { if (cd->isSelected()){ changeFlg = TRUE; } cd->setSelected(FALSE); } /* int sx = cd->getPosX() + cd->getWidth(); int sy = cd->getPosY(); int index = 0; ServentData *sd = cd->getServentDataTop(); while(sd){ if ( ( (!cd->getOpenFlg()) && (sx + index*14 < x) && (x < sx + (index+1)*14) && (sy < y) && (y < sy + 14) ) || sd->checkDown(LOWORD(lParam), HIWORD(lParam)) ){ if (!sd->getSelected()){ changeFlg = TRUE; } sd->setSelected(TRUE); } else { if (sd->getSelected()){ changeFlg = TRUE; } sd->setSelected(FALSE); } sd = sd->getNextData(); index++; }*/ cd = cd->getNextData(); } ChannelDataLock.off(); if (changeFlg){ MakeBack(hwnd); } }
void MakeBack(HWND hwnd, UINT x, UINT y){ MakeBackLock.on(); winWidth = x; winHeight = y; if (backGra){ ::delete backBmp; ::delete backGra; } backBmp = ::new Bitmap(x,y); backGra = ::new Graphics(backBmp); // 全て白で塗りつぶし SolidBrush b(Color(255,255,255,255)); backGra->FillRectangle(&b, 0, 0, x, y); backWidth = backImage->GetWidth(); backHeight = backImage->GetHeight(); // 背景画像を描画 for (UINT xx = 0; xx < x/backWidth + 1; xx++){ for (UINT yy = 0; yy < y/backHeight + 1; yy++){ UINT width,height; if (backWidth*(xx+1) > x){ width = x % backWidth; } else { width = backWidth; } if (backHeight*(yy+1) > y){ height = y % backHeight; } else { height = backHeight; } Rect r((INT)backWidth*xx, (INT)backHeight*yy, width, height); backGra->DrawImage(backImage, r, 0, 0, (INT)width, (INT)height, UnitPixel); } } INT posX = 20; INT posY = 20; // 速度描画 drawSpeed(backGra, winWidth-205, 5); // チャンネル情報を描画 ChannelDataLock.on(); ChannelData *cd = channelDataTop; while(cd){ posY = cd->drawChannel(backGra, 20, posY); cd = cd->getNextData(); } ChannelDataLock.off(); MakeBackLock.off(); }
ChannelData *findChannelData(int channel_id){ ChannelData *cd = channelDataTop; while(cd){ if (cd->getChannelId() == channel_id){ return cd; } cd = cd->getNextData(); } return NULL; }
THREAD_PROC GUIDataUpdate(ThreadInfo *thread){ int i; // set GUI thread status to running thread->finish = false; while(thread->active){ // チャンネルデータロック ChannelDataLock.on(); // チャンネルデータの更新フラグを全てFALSEにする ChannelData *cd = channelDataTop; while(cd){ // Serventの更新フラグをFALSEにする ServentData *sv = cd->getServentDataTop(); while(sv){ sv->setEnableFlg(FALSE); sv = sv->getNextData(); } cd->setEnableFlg(FALSE); cd = cd->getNextData(); } Channel *c = chanMgr->channel; // 現在存在するチャンネル分ループ while(c){ // 既にチャンネルデータを持っているか cd = channelDataTop; // 発見フラグFALSE bool bFoundFlg = FALSE; while(cd){ if (cd->getChannelId() == c->channel_id){ //既にチャンネルデータがあるので、そのまま更新 cd->setData(c); // 更新フラグTRUE cd->setEnableFlg(TRUE); // 発見フラグTRUE bFoundFlg = TRUE; // ループ離脱 break; } // 見つからなかった場合、次のデータをチェック cd = cd->getNextData(); } // 新しいチャンネルの場合、新規データ作成 if (!bFoundFlg){ // 新規データ作成 cd = ::new ChannelData(); // データ更新 cd->setData(c); // 更新フラグTRUE cd->setEnableFlg(TRUE); // 新規データをリストの先頭に入れる cd->setNextData(channelDataTop); channelDataTop = cd; } // 次のチャンネルを取得 c = c->next; } #if 1 // COUTを検索 { bool foundFlg = false; bool foundFlg2 = false; Servent *s = servMgr->servents; while (s) { if (s->type == Servent::T_COUT && s->status == Servent::S_CONNECTED) { foundFlg = true; // ChannelData末尾まで探索 ChannelData *prev = NULL; cd = channelDataTop; while (cd) { if (cd->type == Servent::T_COUT && cd->servent_id == s->servent_id) { foundFlg2 = true; cd->setEnableFlg(true); break; } prev = cd; cd = cd->getNextData(); } cd = prev; if (foundFlg2) break; // ノード追加 if (channelDataTop) { // channelDataが空でない。cdはここでリスト末尾を指してる(はず) cd->setNextData(::new ChannelData()); cd = cd->getNextData(); memset(cd, 0, sizeof(cd)); cd->setNextData(NULL); } else { // channelDataが空 channelDataTop = ::new ChannelData(); channelDataTop->setNextData(NULL); cd = channelDataTop; } // データ設定 cd->type = s->type; cd->servent_id = s->servent_id; cd->setEnableFlg(true); } s = s->next; } // COUTが切れてたら削除 if (!foundFlg) { cd = channelDataTop; ChannelData *prev = NULL; while (cd) { // COUTの情報を削除 if (cd->type == Servent::T_COUT) { // 先頭 if (!prev) { channelDataTop = cd->getNextData(); } else { prev->setNextData(cd->getNextData()); } //::delete cd; } prev = cd; cd = cd->getNextData(); } } } #endif // チャンネルがなくなっている場合の処理 cd = channelDataTop; ChannelData *prev = NULL; while(cd){ // データを更新しなかったか if (cd->getEnableFlg() == FALSE){ // チャンネルがなくなっているので削除 ChannelData *next; next = cd->getNextData(); if (!prev){ // 先頭のデータを削除 // ここメモリリークしそう by えるー channelDataTop = next; } else { // 途中のデータを削除 prev->setNextData(next); } // 次のデータへ cd = next; } else { // データ更新済:次のデータへ prev = cd; cd = cd->getNextData(); } } Servent *s = servMgr->servents; while(s){ // 初期化 ChanHitList *chl; bool infoFlg = false; bool relay = true; bool firewalled = false; unsigned int numRelays = 0; int vp_ver = 0; char ver_ex_prefix[2] = {' ', ' '}; int ver_ex_number = 0; // 直下ホスト情報チェック unsigned int totalRelays = 0; unsigned int totalListeners = 0; ChanHit hitData; // 受信中か if ((s->type == Servent::T_RELAY) && (s->status == Servent::S_CONNECTED)){ // ホスト情報ロック chanMgr->hitlistlock.on(); // 直下ホストが受信しているチャンネルのホスト情報を取得 chl = chanMgr->findHitListByID(s->chanID); // チャンネルのホスト情報があるか if (chl){ // チャンネルのホスト情報がある場合 ChanHit *hit = chl->hit; // チャンネルのホスト情報を全走査して while(hit){ // IDが同じものであれば if (hit->servent_id == s->servent_id){ // トータルリレーとトータルリスナーを加算 totalRelays += hit->numRelays; totalListeners += hit->numListeners; // 直下であれば if (hit->numHops == 1){ // 情報を一旦保存 infoFlg = true; hitData.relay = hit->relay; hitData.firewalled = hit->firewalled; hitData.numRelays = hit->numRelays; hitData.version_vp = hit->version_vp; hitData.version_ex_prefix[0] = hit->version_ex_prefix[0]; hitData.version_ex_prefix[1] = hit->version_ex_prefix[1]; hitData.version_ex_number = hit->version_ex_number; } } // 次をチェック hit = hit->next; } } // チャンネルデータからServentを検索 bool bFoundFlg = FALSE; cd = channelDataTop; while(cd){ ServentData *sv = cd->findServentData(s->servent_id); // ServentDataがあれば if (sv && cd->getChannelId() == s->channel_id){ // データ設定 sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg); sv->setEnableFlg(TRUE); bFoundFlg = TRUE; break; } cd = cd->getNextData(); } // ServentDataが見つからなかった場合 if (!bFoundFlg){ // チャンネルデータを探す cd = channelDataTop; while(cd){ // チャンネルIDが同じか if (cd->getChannelId() == s->channel_id){ // データ設定 ServentData *sv = ::new ServentData(); sv->setData(s, &hitData, totalListeners, totalRelays, infoFlg); sv->setEnableFlg(TRUE); // チャンネルデータにServentData追加 cd->addServentData(sv); // ホスト名を取得する IdData *id = ::new IdData(cd->getChannelId(), sv->getServentId(), sv->getHost().ip); ThreadInfo *t; t = ::new ThreadInfo(); t->func = GetHostName; t->data = (void*)id; sys->startThread(t); LOG_DEBUG("resolving thread was started(%d)", id->getServentId()); // ループ終了 break; } // 次のデータへ cd = cd->getNextData(); } } // ホスト情報アンロック chanMgr->hitlistlock.off(); } s = s->next; } // 更新していないServentDataを削除 cd = channelDataTop; while(cd){ cd->deleteDisableServents(); cd = cd->getNextData(); } // チャンネルデータアンロック ChannelDataLock.off(); // 描画更新 if (guiWnd){ MakeBack(guiWnd); } // 0.1秒×10で1秒待ち for(i=0; i<2; i++) { if (!thread->active) break; sys->sleep(100); } } // set GUI thread status to terminated thread->finish = true; return 0; }
void WmRButtonDownProc(HWND hwnd, LPARAM lParam){ ChannelData *cd; bool changeFlg = FALSE; bool channel_selected = FALSE; bool servent_selected = FALSE; int channel_id = 0; int servent_id = 0; cd = channelDataTop; while(cd){ if (cd->checkDown(LOWORD(lParam), HIWORD(lParam))){ if (!(cd->isSelected())){ changeFlg = TRUE; } cd->setSelected(TRUE); channel_id = cd->getChannelId(); channel_selected = TRUE; // COUT識別 if (cd->type == Servent::T_COUT) { channel_selected = FALSE; servent_selected = TRUE; servent_id = cd->servent_id; } } else { if (cd->isSelected()){ changeFlg = TRUE; } cd->setSelected(FALSE); } ServentData *sd = cd->getServentDataTop(); while(sd){ if (sd->checkDown(LOWORD(lParam), HIWORD(lParam))){ if (!sd->getSelected()){ changeFlg = TRUE; } sd->setSelected(TRUE); servent_id = sd->getServentId(); servent_selected = TRUE; } else { if (sd->getSelected()){ changeFlg = TRUE; } sd->setSelected(FALSE); } sd = sd->getNextData(); } cd = cd->getNextData(); } if (changeFlg){ MakeBack(hwnd); } if (channel_selected){ PopupChannelMenu(channel_id); } else if (servent_selected){ PopupServentMenu(servent_id); } else { PopupOtherMenu(); } }
void PopupOtherMenu(){ POINT pos; MENUITEMINFO info, separator; HMENU hMenu; DWORD dwID; hMenu = CreatePopupMenu(); memset(&separator, 0, sizeof(MENUITEMINFO)); separator.cbSize = sizeof(MENUITEMINFO); separator.fMask = MIIM_ID | MIIM_TYPE; separator.fType = MFT_SEPARATOR; separator.wID = 8000; memset(&info, 0, sizeof(MENUITEMINFO)); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_ID | MIIM_TYPE; info.fType = MFT_STRING; info.wID = 1107; info.dwTypeData = "非リレー中のチャンネルを削除"; InsertMenuItem(hMenu, -1, true, &info); InsertMenuItem(hMenu, -1, true, &separator); if (!gbDispTop){ info.wID = 1101; info.dwTypeData = "最前面表示"; InsertMenuItem(hMenu, -1, true, &info); } else { info.wID = 1102; info.dwTypeData = "最前面解除"; InsertMenuItem(hMenu, -1, true, &info); } InsertMenuItem(hMenu, -1, true, &separator); if (!gbAllOpen){ info.wID = 1103; info.dwTypeData = "全直下展開"; InsertMenuItem(hMenu, -1, true, &info); } else { info.wID = 1104; info.dwTypeData = "全直下隠蔽"; InsertMenuItem(hMenu, -1, true, &info); } InsertMenuItem(hMenu, -1, true, &separator); if (!servMgr->autoServe){ info.wID = 1105; info.dwTypeData = "有効"; InsertMenuItem(hMenu, -1, true, &info); } else { info.wID = 1106; info.dwTypeData = "無効"; InsertMenuItem(hMenu, -1, true, &info); } GetCursorPos(&pos); dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL); DestroyMenu(hMenu); ChannelData *cd = channelDataTop; switch(dwID){ case 1101: // 最前面表示 gbDispTop = true; ::SetWindowPos(guiWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); break; case 1102: // 最前面解除 gbDispTop = false; ::SetWindowPos(guiWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); break; case 1103: // 全直下展開 gbAllOpen = true; while(cd){ cd->setOpenFlg(true); cd = cd->getNextData(); } break; case 1104: // 全直下隠蔽 gbAllOpen = false; while(cd){ cd->setOpenFlg(false); cd = cd->getNextData(); } break; case 1105: // 有効 servMgr->autoServe = true; break; case 1106: // 無効 servMgr->autoServe = false; break; case 1107: // 非リレー中のチャンネル情報を全て削除 { LOG_DEBUG("Start cleaning up unused channels"); while (cd) { if (cd->getStatus() == Channel::S_NOTFOUND || cd->getStatus() == Channel::S_IDLE) { Channel *c = chanMgr->findChannelByChannelID(cd->getChannelId()); if (c && !c->bumped) { c->thread.active = false; c->thread.finish = true; } } cd = cd->getNextData(); } LOG_DEBUG("Finish a cleanup of unused channels"); } break; } }
void PopupServentMenu(int servent_id){ POINT pos; MENUITEMINFO info, separator; HMENU hMenu; DWORD dwID; hMenu = CreatePopupMenu(); memset(&separator, 0, sizeof(MENUITEMINFO)); separator.cbSize = sizeof(MENUITEMINFO); separator.fMask = MIIM_ID | MIIM_TYPE; separator.fType = MFT_SEPARATOR; separator.wID = 8000; memset(&info, 0, sizeof(MENUITEMINFO)); info.cbSize = sizeof(MENUITEMINFO); info.fMask = MIIM_ID | MIIM_TYPE; info.fType = MFT_STRING; ServentData *sd = NULL; ChannelData *cd = channelDataTop; while(cd){ // COUT if (cd->type == Servent::T_COUT && cd->servent_id == servent_id) break; sd = cd->findServentData(servent_id); if (sd){ break; } cd = cd->getNextData(); } if (cd == NULL || sd == NULL && cd->type != Servent::T_COUT) // COUT { return; } info.wID = 1001; info.dwTypeData = "切断"; InsertMenuItem(hMenu, -1, true, &info); // InsertMenuItem(hMenu, -1, true, &separator); GetCursorPos(&pos); dwID = TrackPopupMenu(hMenu, TPM_LEFTALIGN|TPM_RETURNCMD, pos.x, pos.y, 0, guiWnd, NULL); DestroyMenu(hMenu); cd = channelDataTop; while(cd){ // COUT if (cd->type == Servent::T_COUT && cd->servent_id == servent_id) break; sd = cd->findServentData(servent_id); if (sd){ break; } cd = cd->getNextData(); } if (cd == NULL || sd == NULL && cd->type != Servent::T_COUT) // COUT { return; } Servent *s = servMgr->findServentByServentID(servent_id); if (s == NULL){ return; } switch(dwID){ case 1001: // 切断 s->thread.active = false; // COUT切断 if (s->type == Servent::T_COUT) s->thread.finish = true; break; } }
THREAD_PROC GetHostName(ThreadInfo *thread){ IdData *id = (IdData*)(thread->data); //HOSTENT *he; u_long ip; struct sockaddr_in sa; char host[256]; char *tmp; bool flg = TRUE; bool findFlg; int error; ip = htonl(id->getIpAddr()); memset(&sa, 0, sizeof(sa)); sa.sin_addr.S_un.S_addr = ip; sa.sin_family = AF_INET; for (int i=0; i<10 && flg; i++){ error = getnameinfo(reinterpret_cast<sockaddr*>(&sa), sizeof(sa), host, sizeof(host)/sizeof(host[0]), NULL, 0, NI_NAMEREQD); switch (error) { case 0: // success flg = FALSE; break; case WSAHOST_NOT_FOUND: LOG_ERROR("cannot resolve host for %s", ((tmp = inet_ntoa(sa.sin_addr)) ? tmp : "")); flg = TRUE; break; default: LOG_ERROR("an error occurred while resolving hostname of %s (%ld)", ((tmp = inet_ntoa(sa.sin_addr)) ? tmp : ""), error); } } if (error) return 0; for (flg=TRUE, findFlg=FALSE; flg; ) { ChannelDataLock.on(); ChannelData* cd = channelDataTop; while(cd){ if (cd->getChannelId() == id->getChannelId()) { findFlg = TRUE; if (cd->findServentData(id->getServentId())) { if (cd->setName(id->getServentId(), host)) { LOG_DEBUG("successfully resolved(%d)", id->getServentId()); flg = FALSE; break; } else { LOG_ERROR("cannot update servent data with resolved information"); flg = FALSE; break; } } else { LOG_DEBUG("servent data has been removed"); flg = FALSE; break; } } cd = cd->getNextData(); } // ::delete id; ChannelDataLock.off(); if (!findFlg) { LOG_DEBUG("servent data has been removed(channel)"); flg = FALSE; } sys->sleep(1000); } return 0; }