// // Created by xajhuang on 2023/4/12. // #include #include #include "main.h" #include "misc.h" #include "task_manager.h" #include "user_errno.h" #include "zlog_module.h" #include "dhcp_network.h" #define DHCP_STEP_TIMEOUT (30) #define MAIN_WND_WIDTH (1024) #define MAIN_WND_HEIGHT (768) #define ZLOG_CFG_PATH "./config/zlog.conf" static GtkBuilder *g_mainBuilder = NULL; static PDHCP_INFO g_pDhcpInfo = NULL; static GThread *g_pEvLoopThread = NULL; static int g_runTask = FALSE; GtkBuilder *get_main_builder() { return g_mainBuilder; } U32 rand_number() { GRand *pRand = g_rand_new_with_seed(time(NULL)); return g_rand_int(pRand); } PDHCP_INFO get_dhcp_info_by_id(U32 xid) { PDHCP_INFO pInfo; U32 index = xid & 0x00FFFFFF; HASH_FIND_INT(g_pDhcpInfo, &index, pInfo); return pInfo; } static void load_css(void) { GtkCssProvider *provider; GdkDisplay *display; GdkScreen *screen; GFile *css_fp = g_file_new_for_path("./res/style.css"); GError *error = 0; provider = gtk_css_provider_new(); display = gdk_display_get_default(); screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_css_provider_load_from_file(provider, css_fp, &error); } static double calc_total_progress(PDHCP_INFO pInfo) { double pre_cnt = 0.0; pre_cnt += pInfo->step * 20; pre_cnt += pInfo->status * 5; return MIN(pre_cnt, 100.0); } static gboolean calc_step_progress(PDHCP_INFO pInfo, DHCP_STEP step) { if (pInfo->step >= step) { return TRUE; } return FALSE; } void view_popup_menu_onStatistics(GtkWidget *UNUSED(menuitem), gpointer userdata) { //PDHCP_INFO pInfo = (PDHCP_INFO)userdata; //hex_wnd_show(pInfo); } void view_popup_menu_onBinaryPkg(GtkWidget *UNUSED(menuitem), gpointer userdata) { PDHCP_INFO pInfo = (PDHCP_INFO)userdata; //GtkWidget *deatilWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndDetails")); // //g_print("Do something of %s\n", pInfo->treeId); //gtk_notebook_set_current_page(GTK_NOTEBOOK(tab), 0); //gtk_widget_show(deatilWnd); details_wnd_show(pInfo); } void view_popup_menu(GtkWidget *UNUSED(treeview), GdkEventButton *event, gpointer userdata) { GtkWidget *menu, *menuitem; menu = gtk_menu_new(); menuitem = gtk_menu_item_new_with_label("数据包详情"); g_signal_connect(menuitem, "activate", (GCallback)view_popup_menu_onBinaryPkg, userdata); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); menuitem = gtk_menu_item_new_with_label("统计信息"); g_signal_connect(menuitem, "activate", (GCallback)view_popup_menu_onStatistics, userdata); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); gtk_widget_show_all(menu); gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event); } gboolean view_onButtonPressed(GtkWidget *treeview, GdkEventButton *event, gpointer UNUSED(userdata)) { gboolean showMenu = FALSE; PDHCP_INFO p = NULL; GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); /* single click with the right mouse button? */ if (event->type == GDK_BUTTON_PRESS && event->button == 3) { /* optional: select row if no row is selected or only * one other row is selected (will only do something * if you set a tree selection mode as described later * in the tutorial) */ GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); /* Note: gtk_tree_selection_count_selected_rows() does not * exist in gtk+-2.0, only in gtk+ >= v2.2 ! */ if (gtk_tree_selection_count_selected_rows(selection) <= 1) { GtkTreePath *path; /* Get tree path for row that was clicked */ if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL)) { gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection, path); if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) { gchar *index; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COL_INDEX, &index, -1); if (index[0] != 'V') { U32 id = strtoul(index, NULL, 10); HASH_FIND_INT(g_pDhcpInfo, &id, p); if (p) { showMenu = TRUE; } } g_free(index); } gtk_tree_path_free(path); } } if (showMenu) { view_popup_menu(treeview, event, p); } return TRUE; /* we handled this */ } return FALSE; /* we did not handle this */ } gboolean view_onPopupMenu(GtkWidget *treeview, gpointer userdata) { view_popup_menu(treeview, NULL, userdata); return TRUE; /* we handled this */ } static void tree_view_data_store_create() { int i, j; PDHCP_INFO pInfo, pTemp; GtkTreeIter iter, iter_child; GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkWidget *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); int nRequest = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numRequest)); int nVni = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); gtk_tree_store_clear(store); for (i = 0; i < nRequest; i++) { int isCreateRoot = FALSE; j = 0; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { if (pInfo->vni == (nVni + i)) { char idx[64] = {0}; char mac[24] = {0}; sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", pInfo->mac[0], pInfo->mac[1], pInfo->mac[2], pInfo->mac[3], pInfo->mac[4], pInfo->mac[5]); if (!isCreateRoot) { sprintf(idx, "VNI %d", nVni + i); // 创建根节点 gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, &iter, COL_INDEX, idx, COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, FALSE, -1); // clang-format on isCreateRoot = TRUE; } gtk_tree_store_append(store, &iter_child, &iter); // clang-format off // 创建子节点 memset(idx, 0, 64); sprintf(idx, "%u", pInfo->index); gtk_tree_store_set(store, &iter_child, COL_INDEX, idx, COL_MAC, mac, COL_HOSTNAME, pInfo->hostname, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, TRUE, -1); // clang-format on memset(pInfo->treeId, 0, 32); sprintf(pInfo->treeId, "%d:%d", i, j++); } } } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); g_signal_connect(view, "button-press-event", (GCallback)view_onButtonPressed, NULL); g_signal_connect(view, "popup-menu", (GCallback)view_onPopupMenu, NULL); #if 0 for (i = 0; i < 1000; i++) { char buf[24] = {0}; char bufHost[32] = {0}; char bufVni[16] = {0}; sprintf(bufVni, "%d", i); sprintf(bufHost, "hostname%d", i); sprintf(buf, "06:01:02:%02X:%02X:%02X", (i & 0xFF0000) >> 16, (i & 0xFF00) >> 8, (i & 0xFF)); gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, &iter, COL_INDEX, bufVni, COL_MAC, buf, COL_HOSTNAME, bufHost, COL_STATUS, 20.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Discover", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Offer", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Request", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "ACK", COL_RESULT, "", COL_STATUS, 10.0, -1); // clang-format on } #endif } static gboolean tree_view_data_store_upgade(gpointer pInfo) { GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkTreeModel *model; if (!pInfo || !store || !g_runTask) { return FALSE; } model = GTK_TREE_MODEL(store); if (model && gtk_tree_model_get_iter_from_string(model, &iter, ((PDHCP_INFO)pInfo)->treeId)) { // clang-format off gtk_tree_store_set(store, &iter, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, COL_ATTR_VISIABLE, TRUE, -1); // clang-format on } return TRUE; } static void mainWnd_on_destroy(GObject *UNUSED(object), gpointer UNUSED(user_data)) { task_manager_exit(); g_thread_unref(g_pEvLoopThread); gtk_main_quit(); } int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) { pInfo->pOfferBuf.p = (U8 *)malloc(size); if (pInfo->pOfferBuf.p) { memcpy(pInfo->pOfferBuf.p, pBuf, size); pInfo->pOfferBuf.buf_size = size; return ERR_SUCCESS; } return -ERR_MALLOC_MEMORY; } int cacheDhcpAckBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) { pInfo->pAckBuf.p = (U8 *)malloc(size); if (pInfo->pAckBuf.p) { memcpy(pInfo->pAckBuf.p, pBuf, size); pInfo->pAckBuf.buf_size = size; return ERR_SUCCESS; } return -ERR_MALLOC_MEMORY; } _Noreturn static void *dhcpThreadCb(void *UNUSED(pData)) { U8 *pkg; int size = 0; PDHCP_INFO pInfo, pTemp; struct timeval now; while (TRUE) { if (!g_runTask) { g_usleep(1000); continue; } HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { switch (pInfo->step) { case STEP_BEGIN: pInfo->pDiscBuf.p = dhcp_create_discover_req(pInfo, &size); if (pInfo->pDiscBuf.p) { pInfo->pDiscBuf.buf_size = size; pInfo->step = STEP_DISCOVER; pInfo->status = STA_WAIT_START; g_idle_add(tree_view_data_store_upgade, pInfo); } break; case STEP_DISCOVER: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pDiscBuf.p, pInfo->pDiscBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pDiscBuf.buf_size) == pInfo->pDiscBuf.buf_size) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pDiscBuf.tm, NULL); pInfo->pDiscBuf.snd += 1; g_idle_add(tree_view_data_store_upgade, pInfo); } } } else if (pInfo->status == STA_SEND_REQ) { // 处理超时 gettimeofday(&now, NULL); if (now.tv_sec - pInfo->pDiscBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) { // 超时重传 pInfo->status = STA_WAIT_START; } } break; case STEP_OFFER: if (pInfo->status == STA_RECV_RSP) { pInfo->pReqBuf.p = dhcp_create_request_req(pInfo, &size); if (pInfo->pReqBuf.p) { pInfo->pReqBuf.buf_size = size; pInfo->step = STEP_REQUEST; pInfo->status = STA_WAIT_START; g_idle_add(tree_view_data_store_upgade, pInfo); } } break; case STEP_REQUEST: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pReqBuf.p, pInfo->pReqBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pReqBuf.buf_size) == pInfo->pReqBuf.buf_size) { pInfo->status = STA_SEND_REQ; gettimeofday(&pInfo->pReqBuf.tm, NULL); pInfo->pReqBuf.snd = 1; g_idle_add(tree_view_data_store_upgade, pInfo); } } } else if (pInfo->status == STA_SEND_REQ) { // 处理超时 gettimeofday(&now, NULL); if (now.tv_sec - pInfo->pReqBuf.tm.tv_sec > DHCP_STEP_TIMEOUT) { // 超时重传 pInfo->status = STA_WAIT_START; } } break; case STEP_ACK: pInfo->step = STEP_END; break; case STEP_END: break; } } g_usleep(100); } LOG_MSG(debug, "DHCP status mathine exit......\n"); } static void cleanupDHCPInfo() { PDHCP_INFO pInfo, pTemp; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { HASH_DEL(g_pDhcpInfo, pInfo); if (pInfo->pOfferBuf.p) { free(pInfo->pOfferBuf.p); } if (pInfo->pDiscBuf.p) { free(pInfo->pDiscBuf.p); } if (pInfo->pReqBuf.p) { free(pInfo->pReqBuf.p); } if (pInfo->pAckBuf.p) { free(pInfo->pAckBuf.p); } free(pInfo); } } static void mainWnd_on_tb_start(GObject *object, gpointer UNUSED(user_data)) { int i, j, index = 0; GtkTreeIter iter; PDHCP_INFO pInfo; GtkTreeModel *cobModel; gchar *pCobText; unsigned char mac[6]; U32 macVal; GtkWidget *stopButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *macBegin = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *preHostname = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtHostname")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkWidget *numVniCli = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVniClient")); GtkWidget *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); const char *strMacBegin = gtk_entry_get_text(GTK_ENTRY(macBegin)); const char *strPreHostname = gtk_entry_get_text(GTK_ENTRY(preHostname)); U32 nRequest = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numRequest)); U32 nVni = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); U32 nVniCnt = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numVniCli)); string_mac_to_bytes(strMacBegin, mac); macVal = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; cleanupDHCPInfo(); for (i = 0; i < nRequest; i++) { for (j = 0; j < nVniCnt; j++) { U32 macAddr = macVal + index; pInfo = (PDHCP_INFO)malloc(sizeof(DHCP_INFO)); if (pInfo == NULL) { fprintf(stderr, "Malloc %lu bytes memory error of %d\n", sizeof(DHCP_INFO), i); continue; } memset(pInfo, 0, sizeof(DHCP_INFO)); pInfo->index = index; pInfo->vni = nVni + i; pInfo->mac[0] = mac[0]; pInfo->mac[1] = mac[1]; pInfo->mac[2] = (macAddr & 0xFF000000) >> 24; pInfo->mac[3] = (macAddr & 0xFF0000) >> 16; pInfo->mac[4] = (macAddr & 0xFF00) >> 8; pInfo->mac[5] = (macAddr & 0xFF); sprintf(pInfo->hostname, "%s_%u", strPreHostname, pInfo->vni + index); pInfo->step = STEP_BEGIN; pInfo->status = STA_WAIT_START; HASH_ADD_INT(g_pDhcpInfo, index, pInfo); index++; } } gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(nicSelect, FALSE); tree_view_data_store_create(); gtk_widget_set_sensitive(stopButton, TRUE); cobModel = gtk_combo_box_get_model(GTK_COMBO_BOX(nicSelect)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(nicSelect), &iter); gtk_tree_model_get(cobModel, &iter, 0, &pCobText, -1); dhcp_tools_init_network(pCobText); g_runTask = TRUE; } static void mainWnd_on_tb_stop(GObject *object, gpointer UNUSED(user_data)) { GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *tbExpand = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbExpand")); g_runTask = FALSE; gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(startButton, TRUE); gtk_widget_set_sensitive(nicSelect, TRUE); gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(tbExpand), FALSE); g_object_set(G_OBJECT(tbExpand), "stock_id", "gtk-indent", NULL); } static void mainWnd_on_tb_expand(GObject *object, gpointer UNUSED(user_data)) { GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); if (gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(object))) { gtk_tree_view_expand_all(GTK_TREE_VIEW(view)); g_object_set(object, "stock_id", "gtk-unindent", NULL); } else { gtk_tree_view_collapse_all(GTK_TREE_VIEW(view)); g_object_set(object, "stock_id", "gtk-indent", NULL); } } static void mainWnd_on_tb_cleanup(GObject *UNUSED(object), gpointer UNUSED(user_data)) { GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkWidget *tbStop = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); gtk_tree_store_clear(store); cleanupDHCPInfo(); mainWnd_on_tb_stop(G_OBJECT(tbStop), NULL); } static void *uv_loop_thread(void *UNUSED(pData)) { task_manager_run(); return NULL; } int main(int args, char **argv) { int i, ret; GtkTreeIter iter; SYS_NIC_INFO info = {0}; if ((ret = zlog_init(ZLOG_CFG_PATH)) != ERR_SUCCESS) { printf("Zlog configure file [%s] init result: %d+++++\n", ZLOG_CFG_PATH, ret); zlog_profile(); return -ERR_ZLOG_INIT; } else { LOG_MOD(debug, ZLOG_MOD_INIT, "Zlog used configure file [%s]\n", ZLOG_CFG_PATH); dzlog_init(ZLOG_CFG_PATH, get_cur_process_name()); } get_all_network_info(&info); gtk_init(&args, &argv); load_css(); g_mainBuilder = gtk_builder_new(); gtk_builder_add_from_file(g_mainBuilder, "./res/main.glade", NULL); GtkWidget *mainWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndMain")); g_signal_connect(mainWnd, "destroy", G_CALLBACK(mainWnd_on_destroy), g_mainBuilder); GtkWidget *tbStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); g_signal_connect(tbStart, "clicked", G_CALLBACK(mainWnd_on_tb_start), g_mainBuilder); GtkWidget *tbStop = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); g_signal_connect(tbStop, "clicked", G_CALLBACK(mainWnd_on_tb_stop), g_mainBuilder); GtkWidget *tbExpand = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbExpand")); g_signal_connect(tbExpand, "clicked", G_CALLBACK(mainWnd_on_tb_expand), g_mainBuilder); GtkWidget *tbClean = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbCleanup")); g_signal_connect(tbClean, "clicked", G_CALLBACK(mainWnd_on_tb_cleanup), g_mainBuilder); GtkWidget *cbNic = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); for (i = 0; i < info.nicCnt; i++) { GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "lsNicName")); gtk_combo_box_set_model(GTK_COMBO_BOX(cbNic), GTK_TREE_MODEL(store)); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, info.pNicCtx[i].ethName, -1); if (i == info.nicCnt - 1) { gtk_combo_box_set_active(GTK_COMBO_BOX(cbNic), i); } } if (info.pNicCtx) { free(info.pNicCtx); } //GtkWidget *macTxt = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *numInc = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); GtkAdjustment *adj = gtk_adjustment_new(1, 1, 100000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numInc), adj); GtkWidget *numVni = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkAdjustment *adjVni = gtk_adjustment_new(1, 1, 10000000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni); GtkWidget *numVniCli = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVniClient")); GtkAdjustment *adjVniCli = gtk_adjustment_new(1, 1, 1000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVniCli), adjVniCli); //GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); details_wnd_create(g_mainBuilder); //hex_wnd_create(g_mainBuilder); #if 0 gtk_list_store_new(NUM_COLS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT); #endif GdkDisplay *display = gdk_display_get_default(); GdkMonitor *monitor = gdk_display_get_primary_monitor(display); GdkRectangle rect; gdk_monitor_get_geometry(monitor, &rect); gtk_widget_set_size_request(mainWnd, MAIN_WND_WIDTH, MAIN_WND_HEIGHT); // 设置窗口的最小大小 gtk_window_move(GTK_WINDOW(mainWnd), (rect.width - MAIN_WND_WIDTH) / 2, (rect.height - MAIN_WND_HEIGHT) / 2); gtk_builder_connect_signals(g_mainBuilder, NULL); gtk_widget_show(mainWnd); g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); g_thread_new("dhcp", dhcpThreadCb, NULL); gtk_main(); return 0; }