📄 tree.c
字号:
// call the render function on each of the slot nodes for (i=0; i < root_paths_size; i++) { if (root_nodes[i] != 0) gtk_ctree_pre_recursive(tree, root_nodes[i], render_node, NULL); }}// build ctree and pci tree nodes for buses, slots, and adaptersvoid build_from_slot(GtkCTree* tree, int index){ int just_removed = 0; GtkCTreeNode* slot_ctree_node = NULL; GtkCTreeNode* adapter_ctree_node = NULL; pci_tree_node* slot_node, *adapter_node, *bus_node; public_slot_info* tmp_slot_node = NULL; public_adapter_info* tmp_adapter_node = NULL; char tmp_char; int j; index--; // convert index since zero-based array for (j=strlen(root_paths[index])-1; j >= 0; j--) { if (root_paths[index][j] == '/') { tmp_char = root_paths[index][j]; root_paths[index][j] = '\0'; break; } } bus_node = build_pci_tree_node(root_paths[index]); if (j >= 0) root_paths[index][j] = tmp_char; slot_node = build_pci_tree_node(root_paths[index]); tmp_slot_node = (public_slot_info*) slot_node->node_info; bus_node->next = slot_node; tmp_slot_node->bus = (public_bus_info*) bus_node->node_info; slot_ctree_node = build_ctree_node(tree, NULL, root_nodes[index+1], bus_node); slot_node->node = slot_ctree_node; // Special "resetting" of g_node, when we wipe out a slot and reinstate it... // otherwise, g_node might simply go away just_removed = (g_node == root_nodes[index] && g_node != NULL); root_nodes[index] = slot_ctree_node; if (just_removed) g_node = slot_ctree_node; adapter_node = build_pci_adapter_tree_node(); tmp_adapter_node = (public_adapter_info*) adapter_node->node_info; tmp_adapter_node->slot = (public_slot_info*) slot_node->node_info; adapter_ctree_node = build_ctree_node(tree, slot_ctree_node, NULL, adapter_node); adapter_node->node = adapter_ctree_node; walk_general_layer(tree, root_paths[index], adapter_ctree_node, adapter_node, 1); }// free the memory reserved by the pci tree nodes and remove the ctree nodevoid remove_node(GtkCTree* tree, GtkCTreeNode* node, gpointer data){ pci_tree_node* tmp_p_node = NULL; pci_tree_node* p_node = (pci_tree_node*) gtk_ctree_node_get_row_data(tree, node); if (g_node == node) g_node = NULL; // free memory reserved by linked pci_tree_nodes while(p_node) { tmp_p_node = p_node->next; if (p_node->node_info) free(p_node->node_info); if (p_node) free(p_node); p_node = tmp_p_node; } // remove gtk_ctree_node gtk_ctree_remove_node(tree, node); }// return the top-most parent of the node (typically the slot node)GtkCTreeNode* get_parent(GtkCTreeNode* node){ GtkCTreeRow* tree_row; GtkCTreeNode* tree_node; tree_row = GTK_CTREE_ROW(node); do { tree_node = tree_row->parent; tree_row = GTK_CTREE_ROW(tree_node); } while (tree_row->parent != NULL); return tree_node;}// re-direct to the updated function that handles bridges (backward compatibility)// send a default value of -1 since we're not interested in bridges when this function is calledpci_tree_node* ctree_partner(GtkCTree* tree, GtkCTreeNode* node, int* priority_array){ return ctree_partner_ex(tree, node, priority_array, -1); }// return the highest-priority pci tree node in the list contained in the passed-in GtkCTree node// priority array used to weight the pci tree node types; bridges are a special case pci_tree_node* ctree_partner_ex(GtkCTree* tree, GtkCTreeNode* node, int* priority_array, int bridge_preferred){ pci_tree_node* p_node = (pci_tree_node*) gtk_ctree_node_get_row_data(tree, node); pci_tree_node* winner_node = NULL; int winner_priority = 0; if (!p_node) return NULL; while (p_node) { if (bridge_preferred >= 0) { if (p_node->type == 2) { // function if (winner_priority == priority_array[p_node->type]) { //tie int is_bridge = ((public_function_info*)p_node->node_info)->is_bridge; if (is_bridge == bridge_preferred) { //tie break by preference winner_node = p_node; winner_priority = priority_array[winner_node->type]; } } } } if (priority_array[p_node->type] > winner_priority) { winner_node = p_node; winner_priority = priority_array[winner_node->type]; } p_node = p_node->next; } return winner_node;}// generic function that calls the appropriate render node function based on function pointersvoid render_node(GtkCTree* tree, GtkCTreeNode* node, gpointer data){ pci_tree_node* pci_node_to_render = ctree_partner(tree, node, slot_based); (*(pci_node_to_render->render_node))(tree, node, pci_node_to_render); }// render a slot nodevoid render_node_from_slot(GtkCTree* tree, GtkCTreeNode* node, pci_tree_node* user_data){ char node_text[MAXLEN]; GdkFont* tree_font; gboolean expanded; public_slot_info* slot = (public_slot_info*) user_data->node_info; sprintf(node_text, "Slot %d", slot->slot_number); if (slot->attention_status && slot->is_hotpluggable) { gtk_ctree_get_node_info(tree, node, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &expanded); gtk_ctree_set_node_info(tree, node, node_text, 3, att_status_on_icon, att_status_on_icon_mask, att_status_on_icon, att_status_on_icon_mask, FALSE, expanded); } else { gtk_ctree_get_node_info(tree, node, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &expanded); gtk_ctree_set_node_info(tree, node, node_text, 3, att_status_off_icon, att_status_off_icon_mask, att_status_off_icon, att_status_off_icon_mask, FALSE, expanded); } tree_font = gdk_font_load ("-adobe-helvetica-bold-r-normal-*-*-180-*-*-p-*-iso8859-1"); if (!slot->is_hotpluggable) { // non-hotplug slot set_tree_style(black, white, tree, node, tree_font); } else { // hotpluggable slot if (slot->power) set_tree_style(green, white, tree, node, tree_font); else set_tree_style(red, white, tree, node, tree_font); }}// parse the names returned from the kudzu database and return them in a readable formvoid parse_names(char* device_name, char* driver_name, char* device, char* driver){ char* tmp; char vendor_id[MAXLEN]; char device_id[MAXLEN]; char temp_buffer[MAXLEN]; char *delim = {"|"}; // parse vendor and device names from what kudzu returns strcpy(temp_buffer, device_name); tmp = strtok(temp_buffer, delim); sprintf(vendor_id, tmp); tmp = strtok(NULL, delim); sprintf(device_id, tmp); tmp = strcat(vendor_id, " "); tmp = strcat(tmp, device_id); strcpy(device, tmp); strcpy(driver, driver_name);}// render a function nodevoid render_node_from_function(GtkCTree* tree, GtkCTreeNode* node, pci_tree_node* user_data){ int rt = 0; GdkFont* tree_font; char device_name[MAXLEN]; char parsed_device_name[MAXLEN]; char driver_name[MAXLEN]; char parsed_driver_name[MAXLEN]; char node_text[MAXLEN]; gboolean expanded; public_function_info* function = (public_function_info*) user_data->node_info; sprintf(node_text, " <empty>"); if (function) { rt = lookupDevice(function->vendor_id, function->device_id, device_name, driver_name); if (rt) { parse_names((char*) device_name, (char*) driver_name, parsed_device_name, parsed_driver_name); strcpy(function->device_name, parsed_device_name); strcpy(function->driver_name, parsed_driver_name); function->is_driverloaded = is_driverloaded(function->driver_name); sprintf(node_text, " %s", (char*) parsed_device_name); } } gtk_ctree_get_node_info(tree, node, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &expanded); gtk_ctree_set_node_info(tree, node, node_text, 5, NULL, NULL, NULL, NULL, FALSE, expanded); tree_font = gdk_font_load ("-adobe-helvetica-medium-r-normal-*-*-140-*-*-p-*-iso8859-1"); set_tree_style(black, white, tree, node, tree_font);}// return the number of children attached to the GtkCTree nodeint number_of_children(GtkCTreeNode* node){ int rt = 0; GtkCTreeNode* tmp = GTK_CTREE_ROW(node)->children; while (tmp) { rt++; tmp = GTK_CTREE_ROW(tmp)->sibling; } return rt;}// render an adapter nodevoid render_node_from_adapter(GtkCTree* tree, GtkCTreeNode* node, pci_tree_node* user_data){ int rt = 0; GdkFont* tree_font; char device_name[MAXLEN]; char parsed_device_name[MAXLEN]; char driver_name[MAXLEN]; char parsed_driver_name[MAXLEN]; char node_text[MAXLEN]; gboolean expanded; public_adapter_info* adapter = (public_adapter_info*) user_data->node_info; sprintf(node_text, " <empty>"); if (adapter->function) { if (adapter->function->subvendor_id && adapter->function->subdevice_id) rt = lookupDevice(adapter->function->subvendor_id, adapter->function->subdevice_id, device_name, driver_name); else rt = lookupDevice(adapter->function->vendor_id, adapter->function->device_id, device_name, driver_name); if (rt) { pci_tree_node* tmp_node = user_data; parse_names((char*) device_name, (char*) driver_name, parsed_device_name, parsed_driver_name); strcpy(adapter->function->device_name, parsed_device_name); strcpy(adapter->function->driver_name, parsed_driver_name); adapter->function->is_driverloaded = is_driverloaded(adapter->function->driver_name); tmp_node = ctree_partner_ex(tree, node, function_based, 0); if (tmp_node->type == 2) { public_function_info* tmp_func = (public_function_info*) tmp_node->node_info; if (tmp_func->is_bridge) { strcat((char*) parsed_device_name, " (Bridge)"); } } sprintf(node_text, parsed_device_name); } else { pci_tree_node* tmp_node = user_data; sprintf(node_text, " <unknown>"); tmp_node = ctree_partner_ex(tree, node, function_based, 0); if (tmp_node->type == 2) { public_function_info* tmp_func = (public_function_info*) tmp_node->node_info; if (tmp_func->is_bridge) { sprintf(node_text, " <unknown> (Bridge)"); } } } } else sprintf(node_text, " <empty>"); gtk_ctree_get_node_info(tree, node, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &expanded); if (adapter->function) gtk_ctree_set_node_info(tree, node, node_text, 5, card_icon, card_icon_mask, card_icon, card_icon_mask, FALSE, expanded); else gtk_ctree_set_node_info(tree, node, node_text, 5, NULL, NULL, NULL, NULL, FALSE, expanded); tree_font = gdk_font_load ("-adobe-helvetica-medium-r-normal-*-*-140-*-*-p-*-iso8859-1"); set_tree_style(black, white, tree, node, tree_font);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -