| /****************************************************************************\ |
| * grid.c - put display grid info here |
| ***************************************************************************** |
| * Copyright (C) 2002-2006 The Regents of the University of California. |
| * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). |
| * Written by Danny Auble <da@llnl.gov>, et. al. |
| * UCRL-CODE-226842. |
| * |
| * This file is part of SLURM, a resource management program. |
| * For details, see <http://www.llnl.gov/linux/slurm/>. |
| * |
| * SLURM is free software; you can redistribute it and/or modify it under |
| * the terms of the GNU General Public License as published by the Free |
| * Software Foundation; either version 2 of the License, or (at your option) |
| * any later version. |
| * |
| * In addition, as a special exception, the copyright holders give permission |
| * to link the code of portions of this program with the OpenSSL library under |
| * certain conditions as described in each individual source file, and |
| * distribute linked combinations including the two. You must obey the GNU |
| * General Public License in all respects for all of the code used other than |
| * OpenSSL. If you modify file(s) with this exception, you may extend this |
| * exception to your version of the file(s), but you are not obligated to do |
| * so. If you do not wish to do so, delete this exception statement from your |
| * version. If you delete this exception statement from all source files in |
| * the program, then also delete it here. |
| * |
| * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY |
| * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
| * details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with SLURM; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| \*****************************************************************************/ |
| #include "sview.h" |
| |
| List grid_button_list = NULL; |
| List blinking_button_list = NULL; |
| |
| char *sview_colors[] = {"#0000FF", "#00FF00", "#00FFFF", "#FFFF00", |
| "#FF0000", "#4D4DC6", "#F09A09", "#BDFA19", |
| "#715627", "#6A8CA2", "#4C7127", "#25B9B9", |
| "#A020F0", "#8293ED", "#FFA500", "#FFC0CB", |
| "#8B6914", "#18A24E", "#F827FC", "#B8A40C"}; |
| int sview_colors_cnt = 20; |
| |
| GStaticMutex blinking_mutex = G_STATIC_MUTEX_INIT; |
| |
| |
| static void _open_node(GtkWidget *widget, GdkEventButton *event, |
| grid_button_t *grid_button) |
| { |
| GError *error = NULL; |
| char title[100]; |
| ListIterator itr = NULL; |
| popup_info_t *popup_win = NULL; |
| |
| #ifdef HAVE_BG |
| snprintf(title, 100, |
| "Info about base partition %s", grid_button->node_name); |
| #else |
| snprintf(title, 100, "Info about node %s", grid_button->node_name); |
| #endif |
| itr = list_iterator_create(popup_list); |
| while((popup_win = list_next(itr))) { |
| if(popup_win->spec_info) |
| if(!strcmp(popup_win->spec_info->title, title)) { |
| break; |
| } |
| } |
| list_iterator_destroy(itr); |
| |
| if(!popup_win) { |
| popup_win = create_popup_info(INFO_PAGE, NODE_PAGE, title); |
| popup_win->spec_info->search_info->gchar_data = |
| g_strdup(grid_button->node_name); |
| if (!g_thread_create((gpointer)popup_thr, popup_win, |
| FALSE, &error)) |
| { |
| g_printerr ("Failed to create grid popup thread: " |
| "%s\n", |
| error->message); |
| return; |
| } |
| } else |
| gtk_window_present(GTK_WINDOW(popup_win->popup)); |
| return; |
| } |
| |
| #ifdef HAVE_BG |
| static void _open_block(GtkWidget *widget, GdkEventButton *event, |
| grid_button_t *grid_button) |
| { |
| GError *error = NULL; |
| char title[100]; |
| ListIterator itr = NULL; |
| popup_info_t *popup_win = NULL; |
| |
| snprintf(title, 100, |
| "Info about block containing %s", grid_button->node_name); |
| |
| itr = list_iterator_create(popup_list); |
| while((popup_win = list_next(itr))) { |
| if(popup_win->spec_info) |
| if(!strcmp(popup_win->spec_info->title, title)) { |
| break; |
| } |
| } |
| list_iterator_destroy(itr); |
| |
| if(!popup_win) { |
| popup_win = create_popup_info(INFO_PAGE, BLOCK_PAGE, title); |
| popup_win->spec_info->search_info->search_type = |
| SEARCH_BLOCK_NODENAME; |
| popup_win->spec_info->search_info->gchar_data = |
| g_strdup(grid_button->node_name); |
| if (!g_thread_create((gpointer)popup_thr, popup_win, |
| FALSE, &error)) |
| { |
| g_printerr ("Failed to create block " |
| "grid popup thread: %s\n", |
| error->message); |
| return; |
| } |
| } else |
| gtk_window_present(GTK_WINDOW(popup_win->popup)); |
| return; |
| } |
| #endif |
| |
| /* |
| * Comparator used for sorting buttons |
| * |
| * returns: -1: button_a->inx > button_b->inx |
| * 0: rec_a == rec_b |
| * 1: rec_a < rec_b |
| * |
| */ |
| static int _sort_button_inx(grid_button_t *button_a, grid_button_t *button_b) |
| { |
| int inx_a = button_a->inx; |
| int inx_b = button_b->inx; |
| |
| if (inx_a < inx_b) |
| return -1; |
| else if (inx_a > inx_b) |
| return 1; |
| return 0; |
| } |
| |
| void _put_button_as_down(grid_button_t *grid_button, int state) |
| { |
| GtkWidget *image = NULL; |
| GdkColor color; |
| |
| if(GTK_IS_EVENT_BOX(grid_button->button)) { |
| return; |
| } |
| gtk_widget_destroy(grid_button->button); |
| |
| grid_button->button = gtk_event_box_new(); |
| gtk_tooltips_set_tip(grid_button->tip, |
| grid_button->button, |
| grid_button->node_name, |
| "click for node stats"); |
| gtk_widget_set_size_request(grid_button->button, 10, 10); |
| gtk_event_box_set_above_child(GTK_EVENT_BOX(grid_button->button), |
| FALSE); |
| g_signal_connect(G_OBJECT(grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| grid_button); |
| if(grid_button->table) |
| gtk_table_attach(grid_button->table, grid_button->button, |
| grid_button->table_x, |
| (grid_button->table_x+1), |
| grid_button->table_y, |
| (grid_button->table_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| |
| gdk_color_parse("black", &color); |
| gtk_widget_modify_bg(grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| gdk_color_parse("white", &color); |
| gtk_widget_modify_bg(grid_button->button, |
| GTK_STATE_PRELIGHT, &color); |
| if(state == NODE_STATE_DRAIN) |
| image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR, |
| GTK_ICON_SIZE_SMALL_TOOLBAR); |
| else |
| image = gtk_image_new_from_stock(GTK_STOCK_CANCEL, |
| GTK_ICON_SIZE_SMALL_TOOLBAR); |
| gtk_container_add(GTK_CONTAINER(grid_button->button), image); |
| gtk_widget_show_all(grid_button->button); |
| return; |
| } |
| |
| void _put_button_as_up(grid_button_t *grid_button) |
| { |
| if(GTK_IS_BUTTON(grid_button->button)) { |
| return; |
| } |
| gtk_widget_destroy(grid_button->button); |
| grid_button->button = gtk_button_new(); |
| gtk_widget_set_size_request(grid_button->button, 10, 10); |
| gtk_tooltips_set_tip(grid_button->tip, |
| grid_button->button, |
| grid_button->node_name, |
| "click for node stats"); |
| g_signal_connect(G_OBJECT(grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| grid_button); |
| if(grid_button->table) |
| gtk_table_attach(grid_button->table, grid_button->button, |
| grid_button->table_x, |
| (grid_button->table_x+1), |
| grid_button->table_y, |
| (grid_button->table_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| gtk_widget_show_all(grid_button->button); |
| return; |
| } |
| |
| #ifdef HAVE_BG |
| static int _block_in_node(int *bp_inx, int inx) |
| { |
| int j=0; |
| if(bp_inx[j] >= 0) { |
| if ((bp_inx[j] == inx) |
| && (bp_inx[j+1] == inx)) |
| return 1; |
| } |
| return 0; |
| } |
| #endif |
| |
| extern void destroy_grid_button(void *arg) |
| { |
| grid_button_t *grid_button = (grid_button_t *)arg; |
| if(grid_button) { |
| if(grid_button->button) { |
| gtk_widget_destroy(grid_button->button); |
| grid_button->button = NULL; |
| } |
| xfree(grid_button->node_name); |
| xfree(grid_button); |
| } |
| } |
| |
| /* we don't set the call back for the button here because sometimes we |
| * need to get a different call back based on what we are doing with |
| * the button, an example of this would be in |
| * add_extra_bluegene_buttons were the small block buttons do |
| * something different than they do regularly |
| */ |
| |
| extern grid_button_t *create_grid_button_from_another( |
| grid_button_t *grid_button, char *name, int color_inx) |
| { |
| grid_button_t *send_grid_button = NULL; |
| GdkColor color; |
| uint16_t node_base_state; |
| |
| if(!grid_button || !name) |
| return NULL; |
| if(color_inx >= 0) |
| color_inx %= sview_colors_cnt; |
| |
| send_grid_button = xmalloc(sizeof(grid_button_t)); |
| memcpy(send_grid_button, grid_button, sizeof(grid_button_t)); |
| node_base_state = send_grid_button->state & NODE_STATE_BASE; |
| /* need to set the table to empty because we will want to fill |
| this into the new table later */ |
| send_grid_button->table = NULL; |
| if((color_inx >= 0) && node_base_state == NODE_STATE_DOWN) { |
| GtkWidget *image = gtk_image_new_from_stock( |
| GTK_STOCK_CANCEL, |
| GTK_ICON_SIZE_SMALL_TOOLBAR); |
| send_grid_button->button = gtk_event_box_new(); |
| gtk_event_box_set_above_child( |
| GTK_EVENT_BOX(send_grid_button->button), |
| FALSE); |
| gdk_color_parse("black", &color); |
| gtk_widget_modify_bg(send_grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| gdk_color_parse("white", &color); |
| gtk_widget_modify_bg(send_grid_button->button, |
| GTK_STATE_PRELIGHT, &color); |
| gtk_container_add( |
| GTK_CONTAINER(send_grid_button->button), |
| image); |
| } else if((color_inx >= 0) |
| && send_grid_button->state & NODE_STATE_DRAIN) { |
| GtkWidget *image = gtk_image_new_from_stock( |
| GTK_STOCK_DIALOG_ERROR, |
| GTK_ICON_SIZE_SMALL_TOOLBAR); |
| |
| send_grid_button->button = gtk_event_box_new(); |
| gtk_event_box_set_above_child( |
| GTK_EVENT_BOX(send_grid_button->button), |
| FALSE); |
| gdk_color_parse("black", &color); |
| gtk_widget_modify_bg(send_grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| gdk_color_parse("white", &color); |
| gtk_widget_modify_bg(send_grid_button->button, |
| GTK_STATE_PRELIGHT, &color); |
| gtk_container_add( |
| GTK_CONTAINER(send_grid_button->button), |
| image); |
| } else { |
| send_grid_button->button = gtk_button_new(); |
| if(color_inx >= 0) |
| gdk_color_parse(sview_colors[color_inx], &color); |
| else |
| gdk_color_parse("white", &color); |
| gtk_widget_modify_bg(send_grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| } |
| gtk_widget_set_size_request(send_grid_button->button, 10, 10); |
| send_grid_button->tip = gtk_tooltips_new(); |
| |
| send_grid_button->node_name = xstrdup(name); |
| |
| gtk_tooltips_set_tip(send_grid_button->tip, |
| send_grid_button->button, |
| send_grid_button->node_name, |
| "click for node stats"); |
| if(color_inx >= 0) |
| send_grid_button->color = sview_colors[color_inx]; |
| else |
| send_grid_button->color = "white"; |
| return send_grid_button; |
| } |
| |
| extern char *change_grid_color(List button_list, int start, int end, |
| int color_inx) |
| { |
| ListIterator itr = NULL; |
| grid_button_t *grid_button = NULL; |
| uint16_t node_base_state; |
| GdkColor color; |
| |
| if(!button_list) |
| return NULL; |
| |
| itr = list_iterator_create(button_list); |
| color_inx %= sview_colors_cnt; |
| gdk_color_parse(sview_colors[color_inx], &color); |
| while((grid_button = list_next(itr))) { |
| if ((grid_button->inx < start) |
| || (grid_button->inx > end)) |
| continue; |
| node_base_state = grid_button->state & NODE_STATE_BASE; |
| if (node_base_state == NODE_STATE_DOWN) { |
| _put_button_as_down(grid_button, NODE_STATE_DOWN); |
| } else if (grid_button->state & NODE_STATE_DRAIN) { |
| _put_button_as_down(grid_button, NODE_STATE_DRAIN); |
| } else { |
| _put_button_as_up(grid_button); |
| grid_button->color = sview_colors[color_inx]; |
| gtk_widget_modify_bg(grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| } |
| } |
| list_iterator_destroy(itr); |
| return sview_colors[color_inx]; |
| } |
| |
| extern void get_button_list_from_main(List *button_list, int start, int end, |
| int color_inx) |
| { |
| ListIterator itr = NULL; |
| ListIterator button_itr = NULL; |
| grid_button_t *grid_button = NULL; |
| grid_button_t *send_grid_button = NULL; |
| |
| if(!*button_list) |
| *button_list = list_create(destroy_grid_button); |
| |
| color_inx %= sview_colors_cnt; |
| |
| itr = list_iterator_create(grid_button_list); |
| while((grid_button = list_next(itr))) { |
| if ((grid_button->inx < start) |
| || (grid_button->inx > end)) |
| continue; |
| button_itr = list_iterator_create(*button_list); |
| while((send_grid_button = list_next(button_itr))) { |
| if(send_grid_button->inx == grid_button->inx) |
| break; |
| } |
| list_iterator_destroy(button_itr); |
| if(send_grid_button) |
| continue; |
| |
| send_grid_button = create_grid_button_from_another( |
| grid_button, grid_button->node_name, color_inx); |
| if(send_grid_button) { |
| g_signal_connect(G_OBJECT(send_grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| send_grid_button); |
| list_append(*button_list, send_grid_button); |
| } |
| } |
| list_iterator_destroy(itr); |
| return; |
| } |
| |
| extern List copy_main_button_list() |
| { |
| ListIterator itr = NULL; |
| grid_button_t *grid_button = NULL; |
| grid_button_t *send_grid_button = NULL; |
| List button_list = list_create(destroy_grid_button); |
| |
| itr = list_iterator_create(grid_button_list); |
| while((grid_button = list_next(itr))) { |
| send_grid_button = create_grid_button_from_another( |
| grid_button, grid_button->node_name, -1); |
| if(send_grid_button) { |
| g_signal_connect(G_OBJECT(send_grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| send_grid_button); |
| list_append(button_list, send_grid_button); |
| } |
| } |
| list_iterator_destroy(itr); |
| return button_list; |
| } |
| |
| #ifdef HAVE_BG |
| extern void add_extra_bluegene_buttons(List *button_list, int inx, |
| int *color_inx) |
| { |
| node_select_info_msg_t *node_select_ptr = NULL; |
| bg_info_record_t *bg_info_ptr = NULL; |
| int error_code = SLURM_SUCCESS; |
| ListIterator itr = NULL; |
| grid_button_t *grid_button = NULL; |
| grid_button_t *send_grid_button = NULL; |
| int i=0; |
| char *nodes = NULL; |
| char tmp_nodes[256]; |
| int found = 0; |
| int coord_y=0; |
| |
| error_code = get_new_info_node_select(&node_select_ptr, 0); |
| |
| if (error_code != SLURM_SUCCESS |
| && error_code != SLURM_NO_CHANGE_IN_DATA) { |
| return; |
| } |
| |
| if(!*button_list) |
| *button_list = list_create(NULL); |
| |
| *color_inx %= sview_colors_cnt; |
| |
| itr = list_iterator_create(grid_button_list); |
| while((grid_button = list_next(itr))) { |
| if (grid_button->inx == inx) |
| break; |
| } |
| list_iterator_destroy(itr); |
| |
| if(!grid_button) |
| return; |
| |
| /* remove all (if any) buttons pointing to this node since we |
| will be creating all of them */ |
| |
| itr = list_iterator_create(*button_list); |
| while((send_grid_button = list_next(itr))) { |
| if(send_grid_button->inx == grid_button->inx) |
| list_remove(itr); |
| } |
| list_iterator_destroy(itr); |
| |
| for (i=0; i < node_select_ptr->record_count; i++) { |
| bg_info_ptr = &node_select_ptr->bg_info_array[i]; |
| if(!_block_in_node(bg_info_ptr->bp_inx, inx)) |
| continue; |
| found = 1; |
| nodes = bg_info_ptr->nodes; |
| if(bg_info_ptr->ionodes) { |
| sprintf(tmp_nodes, "%s[%s]", nodes, |
| bg_info_ptr->ionodes); |
| nodes = tmp_nodes; |
| } |
| send_grid_button = create_grid_button_from_another( |
| grid_button, nodes, *color_inx); |
| if(send_grid_button) { |
| send_grid_button->table_x = 0; |
| send_grid_button->table_y = coord_y++; |
| g_signal_connect( |
| G_OBJECT(send_grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_block), |
| send_grid_button); |
| |
| list_append(*button_list, send_grid_button); |
| (*color_inx)++; |
| } |
| } |
| if(!found) { |
| send_grid_button = create_grid_button_from_another( |
| grid_button, grid_button->node_name, *color_inx); |
| if(send_grid_button) { |
| send_grid_button->table_x = 0; |
| send_grid_button->table_y = coord_y++; |
| g_signal_connect( |
| G_OBJECT(send_grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| send_grid_button); |
| |
| list_append(*button_list, send_grid_button); |
| (*color_inx)++; |
| } |
| } |
| |
| } |
| #endif |
| |
| extern void add_extra_cr_buttons(List *button_list, node_info_t *node_ptr) |
| { |
| /* FIXME: this is here for consumable resources "multi-core" |
| and what not to add buttons for each. This needs to be added |
| when HP is done with the multi-core code. */ |
| return; |
| } |
| |
| extern void put_buttons_in_table(GtkTable *table, List button_list) |
| { |
| int table_x=0, table_y=0; |
| #ifndef HAVE_BG |
| int coord_x=0, coord_y=0; |
| #endif |
| grid_button_t *grid_button = NULL; |
| ListIterator itr = NULL; |
| int node_count = list_count(button_list); |
| |
| list_sort(button_list, (ListCmpF) _sort_button_inx); |
| |
| #ifdef HAVE_BG |
| node_count = DIM_SIZE[X]; |
| table_x = DIM_SIZE[X] + DIM_SIZE[Z]; |
| table_y = (DIM_SIZE[Z] * DIM_SIZE[Y]) + DIM_SIZE[Y]; |
| #else |
| if(node_count < 50) { |
| table_x = 1; |
| } else if(node_count < 500) { |
| table_x = 10; |
| } else { |
| table_x=20; |
| } |
| table_y = node_count/table_x; |
| table_y++; |
| #endif |
| //g_print("the table size is y=%d x=%d\n", table_y, table_x); |
| gtk_table_resize(table, table_y, table_x); |
| itr = list_iterator_create(button_list); |
| while((grid_button = list_next(itr))) { |
| #ifdef HAVE_BG |
| grid_button->table = table; |
| gtk_table_attach(table, grid_button->button, |
| grid_button->table_x, |
| (grid_button->table_x+1), |
| grid_button->table_y, |
| (grid_button->table_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| if(!grid_button->table_x) |
| gtk_table_set_row_spacing(table, |
| grid_button->table_y, 5); |
| #else |
| grid_button->table = table; |
| grid_button->table_x = coord_x; |
| grid_button->table_y = coord_y; |
| gtk_table_attach(table, grid_button->button, |
| coord_x, (coord_x+1), coord_y, (coord_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| |
| coord_x++; |
| |
| if(coord_x == table_x) { |
| coord_x = 0; |
| coord_y++; |
| if(!(coord_y%10)) { |
| gtk_table_set_row_spacing( |
| table, coord_y-1, 5); |
| } |
| |
| } |
| |
| if(coord_y == table_y) |
| break; |
| |
| if(coord_x && !(coord_x%10)) { |
| gtk_table_set_col_spacing(table, |
| coord_x-1, |
| 5); |
| } |
| #endif |
| } |
| list_iterator_destroy(itr); |
| |
| gtk_widget_show_all(GTK_WIDGET(table)); |
| } |
| |
| extern int get_system_stats(GtkTable *table) |
| { |
| int error_code = SLURM_SUCCESS; |
| node_info_msg_t *node_info_ptr = NULL; |
| List node_list = NULL; |
| int changed = 1; |
| static GtkWidget *label = NULL; |
| char error_char[100]; |
| |
| if(label) |
| gtk_widget_destroy(label); |
| |
| if((error_code = get_new_info_node(&node_info_ptr, force_refresh)) |
| == SLURM_NO_CHANGE_IN_DATA) { |
| changed = 0; |
| } else if (error_code != SLURM_SUCCESS) { |
| snprintf(error_char, 100, "slurm_load_node: %s\n", |
| slurm_strerror(error_code)); |
| label = gtk_label_new(error_char); |
| gtk_table_attach_defaults(table, label, 0, 1, 0, 1); |
| gtk_widget_show(label); |
| |
| return SLURM_ERROR; |
| } |
| |
| ba_init(node_info_ptr); |
| if(grid_button_list) |
| return SLURM_SUCCESS; |
| grid_button_list = list_create(destroy_grid_button); |
| node_list = create_node_info_list(node_info_ptr, changed); |
| setup_grid_table(main_grid_table, grid_button_list, node_list); |
| gtk_widget_show_all(GTK_WIDGET(main_grid_table)); |
| return SLURM_SUCCESS; |
| } |
| |
| extern int setup_grid_table(GtkTable *table, List button_list, List node_list) |
| { |
| int error_code = SLURM_SUCCESS; |
| int x=0, table_x=0, table_y=0; |
| int coord_x=0, coord_y=0, i=0; |
| grid_button_t *grid_button = NULL; |
| int node_count = 0; |
| ListIterator itr = NULL; |
| sview_node_info_t *sview_node_info_ptr = NULL; |
| #ifdef HAVE_BG |
| int y=0, z=0, x_offset=0, y_offset=0; |
| #endif |
| |
| if(!node_list) { |
| g_print("setup_grid_table: no node_list given\n"); |
| return SLURM_ERROR; |
| } |
| |
| #ifdef HAVE_BG |
| node_count = DIM_SIZE[X]; |
| table_x = DIM_SIZE[X] + DIM_SIZE[Z]; |
| table_y = (DIM_SIZE[Z] * DIM_SIZE[Y]) + DIM_SIZE[Y]; |
| #else |
| node_count = list_count(node_list); |
| if(node_count < 50) { |
| table_x = 1; |
| } else if(node_count < 500) { |
| table_x = 10; |
| } else { |
| table_x=20; |
| } |
| table_y = node_count/table_x; |
| table_y++; |
| #endif |
| |
| gtk_table_resize(table, table_y, table_x); |
| itr = list_iterator_create(node_list); |
| #ifdef HAVE_BG |
| /* ok this is going to look much different than smap since we |
| * get the nodes from the controller going up from the Z dim |
| * instead of laying these out in a nice X fashion |
| */ |
| for (x=0; x<DIM_SIZE[X]; x++) { |
| y_offset = (DIM_SIZE[Z] * DIM_SIZE[Y]); |
| for (y=0; y<DIM_SIZE[Y]; y++) { |
| coord_y = y_offset - y; |
| x_offset = DIM_SIZE[Z] - 1; |
| for (z=0; z<DIM_SIZE[Z]; z++){ |
| coord_x = x + x_offset; |
| |
| grid_button = xmalloc(sizeof(grid_button_t)); |
| grid_button->inx = i++; |
| grid_button->table = table; |
| grid_button->table_x = coord_x; |
| grid_button->table_y = coord_y; |
| grid_button->button = gtk_button_new(); |
| grid_button->tip = gtk_tooltips_new(); |
| if(!(sview_node_info_ptr = list_next(itr))) { |
| g_print("no node for this " |
| "inx %d!!!!\n", |
| grid_button->inx); |
| goto end_it; |
| } |
| |
| grid_button->node_name = xstrdup( |
| sview_node_info_ptr->node_ptr->name); |
| |
| gtk_tooltips_set_tip(grid_button->tip, |
| grid_button->button, |
| grid_button->node_name, |
| "click for node stats"); |
| gtk_widget_set_size_request( |
| grid_button->button, 10, 10); |
| g_signal_connect(G_OBJECT(grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| grid_button); |
| list_append(button_list, grid_button); |
| |
| gtk_table_attach(table, grid_button->button, |
| coord_x, (coord_x+1), |
| coord_y, (coord_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| |
| coord_y++; |
| x_offset--; |
| } |
| y_offset -= DIM_SIZE[Z]; |
| } |
| gtk_table_set_row_spacing(table, coord_y-1, 5); |
| } |
| #else |
| for (x=0; x<node_count; x++) { |
| grid_button = xmalloc(sizeof(grid_button_t)); |
| grid_button->inx = i++; |
| grid_button->table = table; |
| grid_button->table_x = coord_x; |
| grid_button->table_y = coord_y; |
| |
| grid_button->button = gtk_button_new(); |
| grid_button->tip = gtk_tooltips_new(); |
| if(!(sview_node_info_ptr = list_next(itr))) { |
| g_print("no node for this " |
| "inx %d!!!!\n", |
| grid_button->inx); |
| goto end_it; |
| } |
| grid_button->node_name = xstrdup( |
| sview_node_info_ptr->node_ptr->name); |
| gtk_tooltips_set_tip(grid_button->tip, |
| grid_button->button, |
| grid_button->node_name, |
| "click for node stats"); |
| gtk_widget_set_size_request(grid_button->button, 10, 10); |
| g_signal_connect(G_OBJECT(grid_button->button), |
| "button-press-event", |
| G_CALLBACK(_open_node), |
| grid_button); |
| list_append(button_list, grid_button); |
| |
| gtk_table_attach(table, grid_button->button, |
| coord_x, (coord_x+1), coord_y, (coord_y+1), |
| GTK_SHRINK, GTK_SHRINK, |
| 1, 1); |
| |
| coord_x++; |
| |
| if(coord_x == table_x) { |
| coord_x = 0; |
| coord_y++; |
| if(!(coord_y%10)) { |
| gtk_table_set_row_spacing(table, |
| coord_y-1, 5); |
| } |
| |
| } |
| |
| if(coord_y == table_y) |
| break; |
| |
| if(coord_x && !(coord_x%10)) { |
| gtk_table_set_col_spacing(table, |
| coord_x-1, 5); |
| } |
| } |
| #endif |
| |
| end_it: |
| list_iterator_destroy(itr); |
| list_sort(button_list, (ListCmpF) _sort_button_inx); |
| |
| return error_code; |
| } |
| |
| extern void sview_init_grid() |
| { |
| node_info_msg_t *node_info_ptr = NULL; |
| int error_code = SLURM_SUCCESS; |
| node_info_t *node_ptr = NULL; |
| int i = 0; |
| uint16_t node_base_state; |
| ListIterator itr = NULL; |
| grid_button_t *grid_button = NULL; |
| GdkColor color; |
| |
| if((error_code = get_new_info_node(&node_info_ptr, force_refresh)) |
| == SLURM_NO_CHANGE_IN_DATA) { |
| return; |
| } else if (error_code != SLURM_SUCCESS) { |
| return; |
| } |
| |
| if(!grid_button_list) { |
| g_print("you need to run get_system_stats() first\n"); |
| exit(0); |
| } |
| |
| gdk_color_parse("white", &color); |
| |
| itr = list_iterator_create(grid_button_list); |
| for(i=0; i<node_info_ptr->record_count; i++) { |
| node_ptr = &node_info_ptr->node_array[i]; |
| list_iterator_reset(itr); |
| while((grid_button = list_next(itr))) { |
| if (grid_button->inx != i) |
| continue; |
| node_base_state = node_ptr->node_state |
| & NODE_STATE_BASE; |
| if (node_base_state == NODE_STATE_DOWN) { |
| _put_button_as_down(grid_button, |
| NODE_STATE_DOWN); |
| } else if (node_ptr->node_state & NODE_STATE_DRAIN) { |
| _put_button_as_down(grid_button, |
| NODE_STATE_DRAIN); |
| } else { |
| _put_button_as_up(grid_button); |
| grid_button->color = "white"; |
| gtk_widget_modify_bg(grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| } |
| grid_button->state = node_ptr->node_state; |
| break; |
| } |
| } |
| list_iterator_destroy(itr); |
| } |
| |
| extern void sview_reset_grid() |
| { |
| grid_button_t *grid_button = NULL; |
| uint16_t node_base_state; |
| ListIterator itr = NULL; |
| GdkColor color; |
| |
| if(!grid_button_list) { |
| g_print("you need to run get_system_stats() first\n"); |
| exit(0); |
| } |
| gdk_color_parse("white", &color); |
| |
| itr = list_iterator_create(grid_button_list); |
| while((grid_button = list_next(itr))) { |
| node_base_state = grid_button->state & NODE_STATE_BASE; |
| if ((node_base_state == NODE_STATE_DOWN) |
| || (grid_button->state & NODE_STATE_DRAIN)) { |
| continue; |
| } |
| gtk_widget_modify_bg(grid_button->button, |
| GTK_STATE_NORMAL, &color); |
| } |
| list_iterator_destroy(itr); |
| } |