PageRenderTime 73ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sview/grid.c

https://github.com/cfenoy/slurm
C | 1740 lines | 1355 code | 196 blank | 189 comment | 317 complexity | 923fb975f34a48849e3a96cab30f7fc9 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /****************************************************************************\
  2. * grid.c - put display grid info here
  3. *****************************************************************************
  4. * Copyright (C) 2004-2007 The Regents of the University of California.
  5. * Copyright (C) 2008-2010 Lawrence Livermore National Security.
  6. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  7. * Written by Danny Auble <da@llnl.gov>, et. al.
  8. * CODE-OCEC-09-009. All rights reserved.
  9. *
  10. * This file is part of SLURM, a resource management program.
  11. * For details, see <http://www.schedmd.com/slurmdocs/>.
  12. * Please also read the included file: DISCLAIMER.
  13. *
  14. * SLURM is free software; you can redistribute it and/or modify it under
  15. * the terms of the GNU General Public License as published by the Free
  16. * Software Foundation; either version 2 of the License, or (at your option)
  17. * any later version.
  18. *
  19. * In addition, as a special exception, the copyright holders give permission
  20. * to link the code of portions of this program with the OpenSSL library under
  21. * certain conditions as described in each individual source file, and
  22. * distribute linked combinations including the two. You must obey the GNU
  23. * General Public License in all respects for all of the code used other than
  24. * OpenSSL. If you modify file(s) with this exception, you may extend this
  25. * exception to your version of the file(s), but you are not obligated to do
  26. * so. If you do not wish to do so, delete this exception statement from your
  27. * version. If you delete this exception statement from all source files in
  28. * the program, then also delete it here.
  29. *
  30. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  31. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  32. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  33. * details.
  34. *
  35. * You should have received a copy of the GNU General Public License along
  36. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  37. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  38. \*****************************************************************************/
  39. #include "sview.h"
  40. #define RESET_GRID -2
  41. #define TOPO_DEBUG 0
  42. List grid_button_list = NULL;
  43. List blinking_button_list = NULL;
  44. List multi_button_list = NULL;
  45. char *sview_colors[] = {"#0000FF", "#00FF00", "#00FFFF", "#FFFF00",
  46. "#FF0000", "#4D4DC6", "#F09A09", "#BDFA19",
  47. "#715627", "#6A8CA2", "#4C7127", "#25B9B9",
  48. "#A020F0", "#8293ED", "#FFA500", "#FFC0CB",
  49. "#8B6914", "#18A24E", "#F827FC", "#B8A40C"};
  50. char *blank_color = "#919191";
  51. char *white_color = "#FFFFFF";
  52. char *topo1_color = "honeydew"; //"seashell";DarkTurquoise
  53. char *topo2_color = "gray94";//honeydew";
  54. int sview_colors_cnt = 20;
  55. typedef struct {
  56. int node_inx_id;
  57. int color_inx_id;
  58. List button_list;
  59. } grid_foreach_t;
  60. typedef struct {
  61. List button_list;
  62. int *coord_x;
  63. int *coord_y;
  64. int default_y_offset;
  65. grid_button_t *grid_button;
  66. int *inx;
  67. GtkTable *table;
  68. int table_y;
  69. bool force_row_break;
  70. } button_processor_t;
  71. GStaticMutex blinking_mutex = G_STATIC_MUTEX_INIT;
  72. static gboolean _mouseover_node(GtkWidget *widget, GdkEventButton *event,
  73. grid_button_t *grid_button)
  74. {
  75. gboolean rc = true;
  76. grid_button->last_state = GTK_WIDGET_STATE(widget);
  77. #ifdef GTK2_USE_TOOLTIP
  78. gtk_widget_set_tooltip_text(grid_button->button,
  79. grid_button->node_name);
  80. #else
  81. if (!grid_button->tip)
  82. grid_button->tip = gtk_tooltips_new();
  83. gtk_tooltips_set_tip(grid_button->tip,
  84. grid_button->button,
  85. grid_button->node_name,
  86. "click for node stats");
  87. #endif
  88. //g_print("on at %s\n", grid_button->node_name);
  89. gtk_widget_set_state(grid_button->button, GTK_STATE_PRELIGHT);
  90. return rc;
  91. }
  92. static gboolean _mouseoff_node(GtkWidget *widget, GdkEventButton *event,
  93. grid_button_t *grid_button)
  94. {
  95. gboolean rc = false;
  96. if (grid_button->last_state == GTK_STATE_ACTIVE) {
  97. gtk_widget_set_state(grid_button->button, GTK_STATE_ACTIVE);
  98. rc = true;
  99. //g_print("off of %s\n", grid_button->node_name);
  100. }
  101. return rc;
  102. }
  103. static gboolean _open_node(GtkWidget *widget, GdkEventButton *event,
  104. grid_button_t *grid_button)
  105. {
  106. if (event->button == 1) {
  107. popup_all_node_name(grid_button->node_name, INFO_PAGE);
  108. } else if (event->button == 3) {
  109. /* right click */
  110. admin_menu_node_name(grid_button->node_name, event);
  111. }
  112. return false;
  113. }
  114. static void _open_block(GtkWidget *widget, GdkEventButton *event,
  115. grid_button_t *grid_button)
  116. {
  117. GError *error = NULL;
  118. char title[100];
  119. ListIterator itr = NULL;
  120. popup_info_t *popup_win = NULL;
  121. snprintf(title, 100,
  122. "Info about block containing %s", grid_button->node_name);
  123. itr = list_iterator_create(popup_list);
  124. while ((popup_win = list_next(itr))) {
  125. if (popup_win->spec_info)
  126. if (!strcmp(popup_win->spec_info->title, title)) {
  127. break;
  128. }
  129. }
  130. list_iterator_destroy(itr);
  131. if (!popup_win) {
  132. popup_win = create_popup_info(INFO_PAGE, BLOCK_PAGE, title);
  133. popup_win->spec_info->search_info->search_type =
  134. SEARCH_BLOCK_NODENAME;
  135. popup_win->spec_info->search_info->gchar_data =
  136. g_strdup(grid_button->node_name);
  137. if (!sview_thread_new((gpointer)popup_thr, popup_win,
  138. FALSE, &error)) {
  139. g_printerr ("Failed to create block "
  140. "grid popup thread: %s\n",
  141. error->message);
  142. return;
  143. }
  144. } else
  145. gtk_window_present(GTK_WINDOW(popup_win->popup));
  146. return;
  147. }
  148. /* static void _state_changed(GtkWidget *button, GtkStateType state, */
  149. /* grid_button_t *grid_button) */
  150. /* { */
  151. /* g_print("state of %s is now %d\n", grid_button->node_name, state); */
  152. /* } */
  153. static void _add_button_signals(grid_button_t *grid_button)
  154. {
  155. /* g_signal_connect(G_OBJECT(grid_button->button), */
  156. /* "state-changed", */
  157. /* G_CALLBACK(_state_changed), */
  158. /* grid_button); */
  159. g_signal_connect(G_OBJECT(grid_button->button),
  160. "button-press-event",
  161. G_CALLBACK(_open_node),
  162. grid_button);
  163. g_signal_connect(G_OBJECT(grid_button->button),
  164. "enter-notify-event",
  165. G_CALLBACK(_mouseover_node),
  166. grid_button);
  167. g_signal_connect(G_OBJECT(grid_button->button),
  168. "leave-notify-event",
  169. G_CALLBACK(_mouseoff_node),
  170. grid_button);
  171. }
  172. /*
  173. * Comparator used for sorting buttons
  174. *
  175. * returns: -1: button_a->inx > button_b->inx
  176. * 0: rec_a == rec_b
  177. * 1: rec_a < rec_b
  178. *
  179. */
  180. static int _sort_button_inx(grid_button_t *button_a, grid_button_t *button_b)
  181. {
  182. int inx_a = button_a->inx;
  183. int inx_b = button_b->inx;
  184. if (inx_a < inx_b)
  185. return -1;
  186. else if (inx_a > inx_b)
  187. return 1;
  188. return 0;
  189. }
  190. void _put_button_as_down(grid_button_t *grid_button, int state)
  191. {
  192. GtkWidget *image = NULL;
  193. /* GdkColor color; */
  194. if (GTK_IS_EVENT_BOX(grid_button->button)) {
  195. //gtk_widget_set_sensitive (grid_button->button, TRUE);
  196. return;
  197. }
  198. gtk_widget_destroy(grid_button->button);
  199. grid_button->color = NULL;
  200. grid_button->color_inx = MAKE_DOWN;
  201. grid_button->button = gtk_event_box_new();
  202. gtk_widget_set_size_request(grid_button->button,
  203. working_sview_config.button_size,
  204. working_sview_config.button_size);
  205. gtk_event_box_set_above_child(GTK_EVENT_BOX(grid_button->button),
  206. FALSE);
  207. _add_button_signals(grid_button);
  208. /* if (grid_button->frame) */
  209. /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */
  210. /* grid_button->button); */
  211. if (grid_button->table)
  212. gtk_table_attach(grid_button->table, grid_button->button,
  213. grid_button->table_x,
  214. (grid_button->table_x+1),
  215. grid_button->table_y,
  216. (grid_button->table_y+1),
  217. GTK_SHRINK, GTK_SHRINK,
  218. 1, 1);
  219. //gdk_color_parse("black", &color);
  220. //sview_widget_modify_bg(grid_button->button, GTK_STATE_NORMAL, color);
  221. //gdk_color_parse(white_color, &color);
  222. //sview_widget_modify_bg(grid_button->button, GTK_STATE_ACTIVE, color);
  223. if (state == NODE_STATE_DRAIN)
  224. image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR,
  225. GTK_ICON_SIZE_SMALL_TOOLBAR);
  226. else
  227. image = gtk_image_new_from_stock(GTK_STOCK_CANCEL,
  228. GTK_ICON_SIZE_SMALL_TOOLBAR);
  229. gtk_container_add(GTK_CONTAINER(grid_button->button), image);
  230. gtk_widget_show_all(grid_button->button);
  231. return;
  232. }
  233. void _put_button_as_up(grid_button_t *grid_button)
  234. {
  235. if (GTK_IS_BUTTON(grid_button->button)) {
  236. return;
  237. }
  238. gtk_widget_destroy(grid_button->button);
  239. grid_button->button = gtk_button_new();
  240. gtk_widget_set_size_request(grid_button->button,
  241. working_sview_config.button_size,
  242. working_sview_config.button_size);
  243. _add_button_signals(grid_button);
  244. /* if (grid_button->frame) */
  245. /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */
  246. /* grid_button->button); */
  247. if (grid_button->table)
  248. gtk_table_attach(grid_button->table, grid_button->button,
  249. grid_button->table_x,
  250. (grid_button->table_x+1),
  251. grid_button->table_y,
  252. (grid_button->table_y+1),
  253. GTK_SHRINK, GTK_SHRINK,
  254. 1, 1);
  255. gtk_widget_show_all(grid_button->button);
  256. return;
  257. }
  258. void _put_button_as_inactive(grid_button_t *grid_button)
  259. {
  260. if (GTK_IS_BUTTON(grid_button->button)) {
  261. //gtk_widget_set_sensitive (grid_button->button, FALSE);
  262. return;
  263. }
  264. gtk_widget_destroy(grid_button->button);
  265. grid_button->button = gtk_button_new();
  266. gtk_widget_set_size_request(grid_button->button,
  267. working_sview_config.button_size,
  268. working_sview_config.button_size);
  269. //gtk_widget_set_sensitive (grid_button->button, FALSE);
  270. _add_button_signals(grid_button);
  271. /* if (grid_button->frame) */
  272. /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */
  273. /* grid_button->button); */
  274. if (grid_button->table)
  275. gtk_table_attach(grid_button->table, grid_button->button,
  276. grid_button->table_x,
  277. (grid_button->table_x+1),
  278. grid_button->table_y,
  279. (grid_button->table_y+1),
  280. GTK_SHRINK, GTK_SHRINK,
  281. 1, 1);
  282. gtk_widget_show_all(grid_button->button);
  283. return;
  284. }
  285. static bool _change_button_color(grid_button_t *grid_button,
  286. int color_inx, char *new_col, GdkColor color,
  287. bool only_change_unused,
  288. enum node_states state_override)
  289. {
  290. enum node_states state;
  291. uint16_t node_base_state;
  292. bool changed = 0;
  293. xassert(grid_button);
  294. if (only_change_unused && grid_button->used)
  295. return 0;
  296. grid_button->used = true;
  297. if (color_inx == MAKE_BLACK) {
  298. if (grid_button->color_inx != color_inx) {
  299. _put_button_as_inactive(grid_button);
  300. grid_button->color = new_col;
  301. grid_button->color_inx = color_inx;
  302. sview_widget_modify_bg(grid_button->button,
  303. GTK_STATE_NORMAL, color);
  304. /* sview_widget_modify_bg(grid_button->button, */
  305. /* GTK_STATE_ACTIVE, */
  306. /* color); */
  307. changed = 1;
  308. }
  309. return changed;
  310. }
  311. if (state_override != NODE_STATE_UNKNOWN)
  312. state = state_override;
  313. else
  314. state = grid_button->state;
  315. node_base_state = state & NODE_STATE_BASE;
  316. if (node_base_state == NODE_STATE_DOWN) {
  317. _put_button_as_down(grid_button, NODE_STATE_DOWN);
  318. } else if ((state & NODE_STATE_DRAIN) ||
  319. (node_base_state == NODE_STATE_ERROR)) {
  320. _put_button_as_down(grid_button, NODE_STATE_DRAIN);
  321. } else if (grid_button->node_name &&
  322. !strcmp(grid_button->node_name, "EMPTY")) {
  323. grid_button->color_inx = MAKE_BLACK;
  324. // _put_button_as_up(grid_button);
  325. } else if (grid_button->color_inx != color_inx) {
  326. _put_button_as_up(grid_button);
  327. grid_button->color = new_col;
  328. grid_button->color_inx = color_inx;
  329. sview_widget_modify_bg(grid_button->button,
  330. GTK_STATE_NORMAL, color);
  331. /* sview_widget_modify_bg(grid_button->button, */
  332. /* GTK_STATE_ACTIVE, color); */
  333. changed = 1;
  334. }
  335. return changed;
  336. }
  337. static void _each_highlightd(GtkTreeModel *model,
  338. GtkTreePath *path,
  339. GtkTreeIter *iter,
  340. gpointer userdata)
  341. {
  342. ListIterator itr = NULL;
  343. grid_button_t *grid_button = NULL;
  344. int *node_inx = NULL;
  345. int color_inx;
  346. int j=0;
  347. GdkColor color;
  348. grid_foreach_t *grid_foreach = userdata;
  349. gtk_tree_model_get(model, iter, grid_foreach->node_inx_id,
  350. &node_inx, -1);
  351. gtk_tree_model_get(model, iter, grid_foreach->color_inx_id,
  352. &color_inx, -1);
  353. if (!node_inx)
  354. return;
  355. if (color_inx > sview_colors_cnt) {
  356. g_print("hey the color_inx from %d was set to %d > %d\n",
  357. grid_foreach->color_inx_id, color_inx,
  358. sview_colors_cnt);
  359. color_inx %= sview_colors_cnt;
  360. }
  361. gdk_color_parse(sview_colors[color_inx], &color);
  362. itr = list_iterator_create(grid_foreach->button_list);
  363. while ((grid_button = list_next(itr))) {
  364. /*For multiple selections, need to retain all selected.
  365. *(previously this assumed only one selected).
  366. */
  367. if ((node_inx[j] < 0)
  368. || (grid_button->inx < node_inx[j])
  369. || (grid_button->inx > node_inx[j+1]))
  370. continue;
  371. (void)_change_button_color(grid_button, color_inx,
  372. sview_colors[color_inx],
  373. color, 0, 0);
  374. if (GTK_WIDGET_STATE(grid_button->button) != GTK_STATE_NORMAL)
  375. gtk_widget_set_state(grid_button->button,
  376. GTK_STATE_NORMAL);
  377. if (grid_button->inx == node_inx[j+1])
  378. j+=2;
  379. }
  380. list_iterator_destroy(itr);
  381. return;
  382. }
  383. static void _each_highlight_selected(GtkTreeModel *model,
  384. GtkTreePath *path,
  385. GtkTreeIter *iter,
  386. gpointer userdata)
  387. {
  388. grid_button_t *grid_button = NULL;
  389. int node_inx = 0;
  390. bool speedup_break = TRUE;
  391. grid_foreach_t *grid_foreach = userdata;
  392. ListIterator itr = NULL;
  393. xassert(grid_foreach);
  394. if (working_sview_config.grid_topological)
  395. speedup_break = FALSE;
  396. gtk_tree_model_get(model, iter, grid_foreach->node_inx_id,
  397. &node_inx, -1);
  398. if (node_inx < 0 || !grid_foreach->button_list)
  399. return;
  400. itr = list_iterator_create(grid_foreach->button_list);
  401. while ((grid_button = list_next(itr))) {
  402. /* For multiple selections, need to retain all selected.
  403. * (previously this assumed only one selected). */
  404. if (grid_button->inx != node_inx)
  405. continue;
  406. else if (GTK_WIDGET_STATE(grid_button->button)
  407. != GTK_STATE_NORMAL) {
  408. gtk_widget_set_state(grid_button->button,
  409. GTK_STATE_NORMAL);
  410. change_grid_color(grid_button_list, grid_button->inx,
  411. grid_button->inx,
  412. grid_button->inx, true, 0);
  413. }
  414. if (speedup_break)
  415. break;
  416. speedup_break = TRUE; //allow for secondary grid button
  417. }
  418. list_iterator_destroy(itr);
  419. return;
  420. }
  421. static int _block_in_node(int *mp_inx, int inx)
  422. {
  423. int j=0;
  424. if (mp_inx[j] >= 0) {
  425. if ((mp_inx[j] == inx) && (mp_inx[j+1] == inx))
  426. return 1;
  427. }
  428. return 0;
  429. }
  430. /*
  431. * This is used to add an entry to the grid for a node which is not configured
  432. * in the system (e.g. there is a gap in the 3-D torus for a service or login
  433. * node.
  434. */
  435. static void _build_empty_node(int coord_x, int coord_y,
  436. button_processor_t *button_processor)
  437. {
  438. grid_button_t *grid_button = button_processor->grid_button;
  439. (*button_processor->coord_x) = coord_x;
  440. (*button_processor->coord_y) = coord_y;
  441. grid_button = xmalloc(sizeof(grid_button_t));
  442. grid_button->color_inx = MAKE_BLACK;
  443. grid_button->inx = (*button_processor->inx);
  444. grid_button->state = NODE_STATE_FUTURE;
  445. grid_button->table = button_processor->table;
  446. grid_button->table_x = (*button_processor->coord_x);
  447. grid_button->table_y = (*button_processor->coord_y);
  448. grid_button->button = gtk_button_new();
  449. grid_button->node_name = xstrdup("EMPTY"); /* Needed by popups */
  450. gtk_widget_set_state(grid_button->button, GTK_STATE_ACTIVE);
  451. list_append(button_processor->button_list, grid_button);
  452. gtk_table_attach(button_processor->table, grid_button->button,
  453. (*button_processor->coord_x),
  454. ((*button_processor->coord_x) + 1),
  455. (*button_processor->coord_y),
  456. ((*button_processor->coord_y) + 1),
  457. GTK_SHRINK, GTK_SHRINK, 1, 1);
  458. }
  459. static void _calc_coord_3d(int x, int y, int z, int default_y_offset,
  460. int *coord_x, int *coord_y, int *dim_size)
  461. {
  462. int y_offset;
  463. *coord_x = (x + (dim_size[2] - 1)) - z;
  464. y_offset = default_y_offset - (dim_size[2] * y);
  465. *coord_y = (y_offset - y) + z;
  466. }
  467. static void _calc_coord_4d(int a, int x, int y, int z, int default_y_offset,
  468. int *coord_x, int *coord_y, int* dim_size)
  469. {
  470. int x_offset, y_offset;
  471. x_offset = (dim_size[1] + dim_size[3]) * a;
  472. *coord_x = x_offset + (x + (dim_size[3] - 1)) - z;
  473. y_offset = default_y_offset - (dim_size[3] * y);
  474. *coord_y = (y_offset - y) + z;
  475. }
  476. static int *_get_cluster_dims(void)
  477. {
  478. int *my_dim_size = slurmdb_setup_cluster_dim_size();
  479. if ((cluster_flags & CLUSTER_FLAG_CRAYXT) && my_dim_size) {
  480. static int cray_dim_size[3] = {-1, -1, -1};
  481. /* For now, assume four nodes per coordinate all in
  482. * the same cage. Need to refine. */
  483. cray_dim_size[0] = my_dim_size[0];
  484. cray_dim_size[1] = my_dim_size[1];
  485. cray_dim_size[2] = my_dim_size[2];
  486. return cray_dim_size;
  487. }
  488. return my_dim_size;
  489. }
  490. /* Add a button for a given node. If node_ptr == NULL then fill in any gaps
  491. * in the grid just for a clean look. Always call with node_ptr == NULL for
  492. * the last call in the sequence. */
  493. static int _add_button_to_list(node_info_t *node_ptr,
  494. button_processor_t *button_processor)
  495. {
  496. static bool *node_exists = NULL;
  497. static int node_exists_cnt = 1;
  498. grid_button_t *grid_button = button_processor->grid_button;
  499. int *dim_size = NULL, i, coord_x = 0, coord_y = 0;
  500. int len = 0, len_a = 0;
  501. if (cluster_dims > 1) {
  502. dim_size = _get_cluster_dims();
  503. if (dim_size == NULL) {
  504. g_error("Could not read dim_size\n");
  505. return SLURM_ERROR;
  506. }
  507. if ((dim_size[0] < 1) || (cluster_dims < 1)) {
  508. g_error("Invalid dim_size %d or cluster_dims %d\n",
  509. dim_size[0], cluster_dims);
  510. return SLURM_ERROR;
  511. }
  512. /* Translate a 3D or 4D space into a 2D space to the extent
  513. * possible. */
  514. if (node_exists == NULL) {
  515. node_exists_cnt = 1;
  516. for (i = 0; i < cluster_dims; i++)
  517. node_exists_cnt *= dim_size[i];
  518. node_exists = xmalloc(sizeof(bool) * node_exists_cnt);
  519. }
  520. if (node_ptr) {
  521. len = strlen(node_ptr->name);
  522. if (len < cluster_dims) {
  523. g_error("bad node name %s\n", node_ptr->name);
  524. return SLURM_ERROR;
  525. }
  526. if (cluster_flags & CLUSTER_FLAG_CRAYXT) {
  527. len_a = strlen(node_ptr->node_addr);
  528. if (len_a < cluster_dims) {
  529. g_error("bad node addr %s\n",
  530. node_ptr->node_addr);
  531. return SLURM_ERROR;
  532. }
  533. }
  534. }
  535. }
  536. if (cluster_dims == 4) {
  537. int a, x, y, z;
  538. if (node_ptr) {
  539. a = select_char2coord(node_ptr->name[len-4]);
  540. x = select_char2coord(node_ptr->name[len-3]);
  541. y = select_char2coord(node_ptr->name[len-2]);
  542. z = select_char2coord(node_ptr->name[len-1]);
  543. /* Ignore "b" dimension for BlueGene/Q */
  544. i = ((a * dim_size[1] + x) * dim_size[2] + y) *
  545. dim_size[3] + z;
  546. node_exists[i] = true;
  547. _calc_coord_4d(a, x, y, z,
  548. button_processor->default_y_offset,
  549. &coord_x, &coord_y, dim_size);
  550. } else {
  551. for (i = -1, a = 0; a < dim_size[0]; a++) {
  552. for (x = 0; x < dim_size[1]; x++) {
  553. for (y = 0; y < dim_size[2]; y++) {
  554. for (z = 0; z < dim_size[3];
  555. z++) {
  556. i++;
  557. if (node_exists[i])
  558. continue;
  559. _calc_coord_4d(a,x,y,z,
  560. button_processor->
  561. default_y_offset,
  562. &coord_x,
  563. &coord_y,
  564. dim_size);
  565. _build_empty_node(
  566. coord_x,
  567. coord_y,
  568. button_processor);
  569. }
  570. }
  571. }
  572. }
  573. xfree(node_exists);
  574. return SLURM_SUCCESS;
  575. }
  576. } else if (cluster_dims == 3) {
  577. int x, y, z;
  578. if (node_ptr) {
  579. if (cluster_flags & CLUSTER_FLAG_CRAYXT) {
  580. x = select_char2coord(
  581. node_ptr->node_addr[len_a-3]);
  582. y = select_char2coord(
  583. node_ptr->node_addr[len_a-2]);
  584. z = select_char2coord(
  585. node_ptr->node_addr[len_a-1]);
  586. } else {
  587. x = select_char2coord(node_ptr->name[len-3]);
  588. y = select_char2coord(node_ptr->name[len-2]);
  589. z = select_char2coord(node_ptr->name[len-1]);
  590. }
  591. i = (x * dim_size[1] + y) * dim_size[2] + z;
  592. node_exists[i] = true;
  593. _calc_coord_3d(x, y, z,
  594. button_processor->default_y_offset,
  595. &coord_x, &coord_y, dim_size);
  596. } else {
  597. for (x = 0; x < dim_size[0]; x++) {
  598. for (y = 0; y < dim_size[1]; y++) {
  599. for (z = 0; z < dim_size[2]; z++) {
  600. i = (x * dim_size[1] + y) *
  601. dim_size[2] + z;
  602. if (node_exists[i])
  603. continue;
  604. _calc_coord_3d(x, y, z,
  605. button_processor->
  606. default_y_offset,
  607. &coord_x, &coord_y,
  608. dim_size);
  609. _build_empty_node(
  610. coord_x, coord_y,
  611. button_processor);
  612. }
  613. }
  614. }
  615. xfree(node_exists);
  616. return SLURM_SUCCESS;
  617. }
  618. }
  619. if (node_ptr == NULL)
  620. return SLURM_SUCCESS;
  621. if (cluster_dims > 1) {
  622. (*button_processor->coord_x) = coord_x;
  623. (*button_processor->coord_y) = coord_y;
  624. #if 0
  625. g_print("%s %d:%d\n", node_ptr->name, coord_x, coord_y);
  626. #endif
  627. }
  628. if (!grid_button) {
  629. grid_button = xmalloc(sizeof(grid_button_t));
  630. grid_button->color_inx = MAKE_INIT;
  631. grid_button->inx = (*button_processor->inx);
  632. grid_button->table = button_processor->table;
  633. grid_button->table_x = (*button_processor->coord_x);
  634. grid_button->table_y = (*button_processor->coord_y);
  635. grid_button->button = gtk_button_new();
  636. grid_button->node_name = xstrdup(node_ptr->name);
  637. gtk_widget_set_size_request(grid_button->button,
  638. working_sview_config.button_size,
  639. working_sview_config.button_size);
  640. _add_button_signals(grid_button);
  641. list_append(button_processor->button_list, grid_button);
  642. gtk_table_attach(button_processor->table, grid_button->button,
  643. (*button_processor->coord_x),
  644. ((*button_processor->coord_x)+1),
  645. (*button_processor->coord_y),
  646. ((*button_processor->coord_y)+1),
  647. GTK_SHRINK, GTK_SHRINK,
  648. 1, 1);
  649. } else {
  650. grid_button->table_x = (*button_processor->coord_x);
  651. grid_button->table_y = (*button_processor->coord_y);
  652. gtk_container_child_set(
  653. GTK_CONTAINER(button_processor->table),
  654. grid_button->button,
  655. "left-attach", (*button_processor->coord_x),
  656. "right-attach", ((*button_processor->coord_x)+1),
  657. "top-attach", (*button_processor->coord_y),
  658. "bottom-attach", ((*button_processor->coord_y)+1),
  659. NULL);
  660. }
  661. /* gtk_container_add(GTK_CONTAINER(grid_button->frame), */
  662. /* grid_button->button); */
  663. /* gtk_frame_set_shadow_type(GTK_FRAME(grid_button->frame), */
  664. /* GTK_SHADOW_ETCHED_OUT); */
  665. if (cluster_dims < 3) {
  666. /* On linear systems we just up the x_coord until we hit the
  667. * side of the table and then increment the coord_y. We add
  668. * space between each tenth row. */
  669. (*button_processor->coord_x)++;
  670. if (button_processor->force_row_break) {
  671. (*button_processor->coord_x) = 0;
  672. (*button_processor->coord_y)++;
  673. gtk_table_set_row_spacing(
  674. button_processor->table,
  675. (*button_processor->coord_y)-1,
  676. working_sview_config.gap_size);
  677. return SLURM_SUCCESS;
  678. }
  679. if ((*button_processor->coord_x)
  680. == working_sview_config.grid_x_width) {
  681. (*button_processor->coord_x) = 0;
  682. (*button_processor->coord_y)++;
  683. if (!((*button_processor->coord_y)
  684. % working_sview_config.grid_vert))
  685. gtk_table_set_row_spacing(
  686. button_processor->table,
  687. (*button_processor->coord_y)-1,
  688. working_sview_config.gap_size);
  689. }
  690. if ((*button_processor->coord_y) == button_processor->table_y)
  691. return SLURM_SUCCESS;
  692. if ((*button_processor->coord_x) &&
  693. !((*button_processor->coord_x)
  694. % working_sview_config.grid_hori))
  695. gtk_table_set_col_spacing(
  696. button_processor->table,
  697. (*button_processor->coord_x)-1,
  698. working_sview_config.gap_size);
  699. }
  700. return SLURM_SUCCESS;
  701. }
  702. static int _grid_table_by_switch(button_processor_t *button_processor,
  703. List node_list)
  704. {
  705. int rc = SLURM_SUCCESS;
  706. int inx = 0, ii = 0;
  707. switch_record_bitmaps_t *sw_nodes_bitmaps_ptr = g_switch_nodes_maps;
  708. #if TOPO_DEBUG
  709. /* engage if want original display below switched */
  710. ListIterator itr = list_iterator_create(node_list);
  711. sview_node_info_t *sview_node_info_ptr = NULL;
  712. #endif
  713. button_processor->inx = &inx;
  714. for (ii=0; ii<g_topo_info_msg_ptr->record_count;
  715. ii++, sw_nodes_bitmaps_ptr++) {
  716. int j = 0, first, last;
  717. if (g_topo_info_msg_ptr->topo_array[ii].level)
  718. continue;
  719. first = bit_ffs(sw_nodes_bitmaps_ptr->node_bitmap);
  720. if (first == -1)
  721. continue;
  722. last = bit_fls(sw_nodes_bitmaps_ptr->node_bitmap);
  723. button_processor->inx = &j;
  724. button_processor->force_row_break = FALSE;
  725. for (j = first; j <= last; j++) {
  726. if (TOPO_DEBUG)
  727. g_print("allocated node = %s button# %d\n",
  728. g_node_info_ptr->node_array[j].name,
  729. j);
  730. if (!bit_test(sw_nodes_bitmaps_ptr->node_bitmap, j))
  731. continue;
  732. /* if (!working_sview_config.show_hidden) { */
  733. /* if (!check_part_includes_node(j)) */
  734. /* continue; */
  735. /* } */
  736. if (j == last)
  737. button_processor->force_row_break = TRUE;
  738. if ((rc = _add_button_to_list(
  739. &g_node_info_ptr->node_array[j],
  740. button_processor)) != SLURM_SUCCESS)
  741. break;
  742. button_processor->force_row_break = FALSE;
  743. }
  744. rc = _add_button_to_list(NULL, button_processor);
  745. }
  746. #if TOPO_DEBUG
  747. /* engage this if want original display below
  748. * switched grid */
  749. button_processor->inx = &inx;
  750. while ((sview_node_info_ptr = list_next(itr))) {
  751. if ((rc = _add_button_to_list(
  752. sview_node_info_ptr->node_ptr,
  753. button_processor)) != SLURM_SUCCESS)
  754. break;
  755. inx++;
  756. }
  757. list_iterator_destroy(itr);
  758. #endif
  759. /* This is needed to get the correct width of the grid window.
  760. * If it is not given then we get a really narrow window. */
  761. gtk_table_set_row_spacing(button_processor->table,
  762. (*button_processor->coord_y)?
  763. ((*button_processor->coord_y)-1):0, 1);
  764. return rc;
  765. }
  766. static int _grid_table_by_list(button_processor_t *button_processor,
  767. List node_list)
  768. {
  769. sview_node_info_t *sview_node_info_ptr = NULL;
  770. int inx = 0, rc = SLURM_SUCCESS;
  771. ListIterator itr = list_iterator_create(node_list);
  772. button_processor->inx = &inx;
  773. while ((sview_node_info_ptr = list_next(itr))) {
  774. /* if (!working_sview_config.show_hidden) { */
  775. /* if (!check_part_includes_node(inx)) { */
  776. /* inx++; */
  777. /* continue; */
  778. /* } */
  779. /* } */
  780. if ((rc = _add_button_to_list(
  781. sview_node_info_ptr->node_ptr,
  782. button_processor)) != SLURM_SUCCESS)
  783. break;
  784. inx++;
  785. }
  786. list_iterator_destroy(itr);
  787. rc = _add_button_to_list(NULL, button_processor);
  788. /* This is needed to get the correct width of the grid window.
  789. * If it is not given then we get a really narrow window. */
  790. gtk_table_set_row_spacing(button_processor->table,
  791. (*button_processor->coord_y)?
  792. ((*button_processor->coord_y)-1):0, 1);
  793. return rc;
  794. }
  795. static int _init_button_processor(button_processor_t *button_processor,
  796. int node_count)
  797. {
  798. int *dim_size = NULL;
  799. if (node_count == 0) {
  800. g_print("_init_button_processor: no nodes selected\n");
  801. return SLURM_ERROR;
  802. }
  803. memset(button_processor, 0, sizeof(button_processor_t));
  804. if (cluster_dims > 1) {
  805. dim_size = _get_cluster_dims();
  806. if (dim_size == NULL) {
  807. g_error("could not read dim_size\n");
  808. return SLURM_ERROR;
  809. }
  810. }
  811. if (cluster_dims == 4) {
  812. button_processor->default_y_offset = (dim_size[3] * dim_size[2])
  813. + (dim_size[2] - dim_size[3]);
  814. working_sview_config.grid_x_width = (dim_size[1] + dim_size[3])
  815. * dim_size[0];
  816. button_processor->table_y = (dim_size[3] * dim_size[2])
  817. + dim_size[2];
  818. } else if (cluster_dims == 3) {
  819. button_processor->default_y_offset = (dim_size[2] * dim_size[1])
  820. + (dim_size[1] - dim_size[2]);
  821. working_sview_config.grid_x_width = dim_size[0] + dim_size[2];
  822. button_processor->table_y = (dim_size[2] * dim_size[1])
  823. + dim_size[1];
  824. } else {
  825. if (!working_sview_config.grid_x_width) {
  826. if (node_count < 50) {
  827. working_sview_config.grid_x_width = 1;
  828. } else if (node_count < 500) {
  829. working_sview_config.grid_x_width = 10;
  830. } else {
  831. working_sview_config.grid_x_width = 20;
  832. }
  833. }
  834. button_processor->table_y =
  835. (node_count / working_sview_config.grid_x_width) + 1;
  836. }
  837. button_processor->force_row_break = FALSE;
  838. return SLURM_SUCCESS;
  839. }
  840. /* static void _destroy_grid_foreach(void *arg) */
  841. /* { */
  842. /* grid_foreach_t *grid_foreach = (grid_foreach_t *)arg; */
  843. /* if (grid_foreach) { */
  844. /* xfree(grid_foreach); */
  845. /* } */
  846. /* } */
  847. extern void destroy_grid_button(void *arg)
  848. {
  849. grid_button_t *grid_button = (grid_button_t *)arg;
  850. if (grid_button) {
  851. if (grid_button->button) {
  852. gtk_widget_destroy(grid_button->button);
  853. grid_button->button = NULL;
  854. }
  855. xfree(grid_button->node_name);
  856. xfree(grid_button);
  857. }
  858. }
  859. /* we don't set the call back for the button here because sometimes we
  860. * need to get a different call back based on what we are doing with
  861. * the button, an example of this would be in
  862. * add_extra_bluegene_buttons were the small block buttons do
  863. * something different than they do regularly
  864. */
  865. extern grid_button_t *create_grid_button_from_another(
  866. grid_button_t *grid_button, char *name, int color_inx)
  867. {
  868. grid_button_t *send_grid_button = NULL;
  869. GdkColor color;
  870. uint16_t node_base_state;
  871. char *new_col = NULL;
  872. if (!grid_button || !name)
  873. return NULL;
  874. if (color_inx >= 0) {
  875. color_inx %= sview_colors_cnt;
  876. new_col = sview_colors[color_inx];
  877. } else if (color_inx == MAKE_BLACK)
  878. new_col = blank_color;
  879. else
  880. new_col = white_color;
  881. send_grid_button = xmalloc(sizeof(grid_button_t));
  882. memcpy(send_grid_button, grid_button, sizeof(grid_button_t));
  883. node_base_state = send_grid_button->state & NODE_STATE_BASE;
  884. send_grid_button->color_inx = color_inx;
  885. /* need to set the table to empty because we will want to fill
  886. this into the new table later */
  887. send_grid_button->table = NULL;
  888. if (color_inx == MAKE_BLACK) {
  889. send_grid_button->button = gtk_button_new();
  890. //gtk_widget_set_sensitive (send_grid_button->button, FALSE);
  891. gdk_color_parse(new_col, &color);
  892. send_grid_button->color = new_col;
  893. sview_widget_modify_bg(send_grid_button->button,
  894. GTK_STATE_NORMAL, color);
  895. /* sview_widget_modify_bg(send_grid_button->button, */
  896. /* GTK_STATE_ACTIVE, color); */
  897. } else if ((color_inx >= 0) && node_base_state == NODE_STATE_DOWN) {
  898. GtkWidget *image = gtk_image_new_from_stock(
  899. GTK_STOCK_CANCEL,
  900. GTK_ICON_SIZE_SMALL_TOOLBAR);
  901. send_grid_button->button = gtk_event_box_new();
  902. gtk_event_box_set_above_child(
  903. GTK_EVENT_BOX(send_grid_button->button),
  904. FALSE);
  905. gdk_color_parse("black", &color);
  906. sview_widget_modify_bg(send_grid_button->button,
  907. GTK_STATE_NORMAL, color);
  908. //gdk_color_parse("white", &color);
  909. /* sview_widget_modify_bg(send_grid_button->button, */
  910. /* GTK_STATE_ACTIVE, color); */
  911. gtk_container_add(
  912. GTK_CONTAINER(send_grid_button->button),
  913. image);
  914. } else if ((color_inx >= 0)
  915. && ((send_grid_button->state & NODE_STATE_DRAIN)
  916. || (node_base_state == NODE_STATE_ERROR))) {
  917. GtkWidget *image = gtk_image_new_from_stock(
  918. GTK_STOCK_DIALOG_ERROR,
  919. GTK_ICON_SIZE_SMALL_TOOLBAR);
  920. send_grid_button->button = gtk_event_box_new();
  921. gtk_event_box_set_above_child(
  922. GTK_EVENT_BOX(send_grid_button->button),
  923. FALSE);
  924. gdk_color_parse("black", &color);
  925. /* sview_widget_modify_bg(send_grid_button->button, */
  926. /* GTK_STATE_NORMAL, color); */
  927. //gdk_color_parse("white", &color);
  928. /* sview_widget_modify_bg(send_grid_button->button, */
  929. /* GTK_STATE_ACTIVE, color); */
  930. gtk_container_add(
  931. GTK_CONTAINER(send_grid_button->button),
  932. image);
  933. } else {
  934. send_grid_button->button = gtk_button_new();
  935. send_grid_button->color = new_col;
  936. gdk_color_parse(new_col, &color);
  937. sview_widget_modify_bg(send_grid_button->button,
  938. GTK_STATE_NORMAL, color);
  939. /* sview_widget_modify_bg(send_grid_button->button, */
  940. /* GTK_STATE_ACTIVE, color); */
  941. }
  942. gtk_widget_set_size_request(send_grid_button->button,
  943. working_sview_config.button_size,
  944. working_sview_config.button_size);
  945. send_grid_button->node_name = xstrdup(name);
  946. return send_grid_button;
  947. }
  948. /* start == -1 for all */
  949. extern char *change_grid_color(List button_list, int start, int end,
  950. int color_inx, bool only_change_unused,
  951. enum node_states state_override)
  952. {
  953. ListIterator itr = NULL;
  954. grid_button_t *grid_button = NULL;
  955. GdkColor color;
  956. char *new_col = NULL;
  957. if (!button_list)
  958. return NULL;
  959. if (color_inx >= 0) {
  960. color_inx %= sview_colors_cnt;
  961. new_col = sview_colors[color_inx];
  962. } else if (color_inx == MAKE_BLACK) {
  963. new_col = blank_color;
  964. } else if (color_inx == MAKE_TOPO_1) {
  965. new_col = topo1_color;
  966. } else if (color_inx == MAKE_TOPO_2) {
  967. new_col = topo2_color;
  968. } else
  969. new_col = white_color;
  970. gdk_color_parse(new_col, &color);
  971. itr = list_iterator_create(button_list);
  972. while ((grid_button = list_next(itr))) {
  973. if ((start != -1) &&
  974. ((grid_button->inx < start) || (grid_button->inx > end)))
  975. continue;
  976. _change_button_color(grid_button, color_inx, new_col,
  977. color, only_change_unused, state_override);
  978. }
  979. list_iterator_destroy(itr);
  980. return sview_colors[color_inx];
  981. }
  982. /* This variation of change_grid_color() is faster when changing many
  983. * button colors at the same time since we can issue a single call to
  984. * _change_button_color() and eliminate a nested loop. */
  985. extern void change_grid_color_array(List button_list, int array_len,
  986. int *color_inx, bool *color_set_flag,
  987. bool only_change_unused,
  988. enum node_states state_override)
  989. {
  990. ListIterator itr = NULL;
  991. grid_button_t *grid_button = NULL;
  992. GdkColor color;
  993. char *new_col = NULL;
  994. if (!button_list)
  995. return;
  996. itr = list_iterator_create(button_list);
  997. while ((grid_button = list_next(itr))) {
  998. if ((grid_button->inx < 0) || (grid_button->inx >= array_len))
  999. continue;
  1000. if (!color_set_flag[grid_button->inx])
  1001. continue;
  1002. if (color_inx[grid_button->inx] >= 0) {
  1003. color_inx[grid_button->inx] %= sview_colors_cnt;
  1004. new_col = sview_colors[color_inx[grid_button->inx]];
  1005. } else if (color_inx[grid_button->inx] == MAKE_BLACK) {
  1006. new_col = blank_color;
  1007. } else if (color_inx[grid_button->inx] == MAKE_TOPO_1) {
  1008. new_col = topo1_color;
  1009. } else if (color_inx[grid_button->inx] == MAKE_TOPO_2) {
  1010. new_col = topo2_color;
  1011. } else
  1012. new_col = white_color;
  1013. gdk_color_parse(new_col, &color);
  1014. _change_button_color(grid_button, color_inx[grid_button->inx],
  1015. new_col, color, only_change_unused,
  1016. state_override);
  1017. }
  1018. list_iterator_destroy(itr);
  1019. return;
  1020. }
  1021. extern void highlight_grid(GtkTreeView *tree_view,
  1022. int node_inx_id, int color_inx_id, List button_list)
  1023. {
  1024. ListIterator itr = NULL;
  1025. grid_button_t *grid_button = NULL;
  1026. grid_foreach_t grid_foreach;
  1027. if (!button_list || !tree_view)
  1028. return;
  1029. /*first clear all grid buttons*/
  1030. itr = list_iterator_create(button_list);
  1031. while ((grid_button = list_next(itr))) {
  1032. /* clear everyone */
  1033. if ((GTK_WIDGET_STATE(grid_button->button)
  1034. != GTK_STATE_ACTIVE)) {
  1035. gtk_widget_set_state(grid_button->button,
  1036. GTK_STATE_ACTIVE);
  1037. }
  1038. }
  1039. list_iterator_destroy(itr);
  1040. /* for each currently selected row,go back & ensure the
  1041. * corresponding grid button is highlighted */
  1042. memset(&grid_foreach, 0, sizeof(grid_foreach_t));
  1043. grid_foreach.node_inx_id = node_inx_id;
  1044. grid_foreach.color_inx_id = color_inx_id;
  1045. grid_foreach.button_list = button_list;
  1046. if (grid_foreach.color_inx_id != (int)NO_VAL)
  1047. gtk_tree_selection_selected_foreach(
  1048. gtk_tree_view_get_selection(tree_view),
  1049. _each_highlightd, &grid_foreach);
  1050. else
  1051. gtk_tree_selection_selected_foreach(
  1052. gtk_tree_view_get_selection(tree_view),
  1053. _each_highlight_selected, &grid_foreach);
  1054. return;
  1055. }
  1056. /* start == -1 for all */
  1057. extern void highlight_grid_range(int start, int end, List button_list)
  1058. {
  1059. ListIterator itr = NULL;
  1060. grid_button_t *grid_button = NULL;
  1061. if (!button_list)
  1062. return;
  1063. itr = list_iterator_create(button_list);
  1064. while ((grid_button = list_next(itr))) {
  1065. if (start != -1)
  1066. if ((grid_button->inx < start)
  1067. || (grid_button->inx > end)) {
  1068. /* clear everyone else */
  1069. if ((GTK_WIDGET_STATE(grid_button->button)
  1070. != GTK_STATE_ACTIVE))
  1071. gtk_widget_set_state(
  1072. grid_button->button,
  1073. GTK_STATE_ACTIVE);
  1074. continue;
  1075. }
  1076. /* highlight this one, if it is already hightlighted,
  1077. * put it back to normal */
  1078. //g_print("highlighting %d\n", grid_button->inx);
  1079. if ((GTK_WIDGET_STATE(grid_button->button)
  1080. != GTK_STATE_NORMAL))
  1081. gtk_widget_set_state(grid_button->button,
  1082. GTK_STATE_NORMAL);
  1083. }
  1084. list_iterator_destroy(itr);
  1085. return;
  1086. }
  1087. extern void set_grid_used(List button_list, int start, int end,
  1088. bool used, bool reset_highlight)
  1089. {
  1090. ListIterator itr = NULL;
  1091. grid_button_t *grid_button = NULL;
  1092. if (!button_list)
  1093. return;
  1094. itr = list_iterator_create(button_list);
  1095. while ((grid_button = list_next(itr))) {
  1096. if (start != -1)
  1097. if ((grid_button->inx < start)
  1098. || (grid_button->inx > end))
  1099. continue;
  1100. grid_button->used = used;
  1101. if (reset_highlight)
  1102. gtk_widget_set_state(grid_button->button,
  1103. GTK_STATE_NORMAL);
  1104. }
  1105. list_iterator_destroy(itr);
  1106. return;
  1107. }
  1108. extern void get_button_list_from_main(List *button_list, int start, int end,
  1109. int color_inx)
  1110. {
  1111. ListIterator itr = NULL;
  1112. ListIterator button_itr = NULL;
  1113. grid_button_t *grid_button = NULL;
  1114. grid_button_t *send_grid_button = NULL;
  1115. if (!*button_list)
  1116. *button_list = list_create(destroy_grid_button);
  1117. color_inx %= sview_colors_cnt;
  1118. itr = list_iterator_create(grid_button_list);
  1119. while ((grid_button = list_next(itr))) {
  1120. if ((grid_button->inx < start)
  1121. || (grid_button->inx > end))
  1122. continue;
  1123. button_itr = list_iterator_create(*button_list);
  1124. while ((send_grid_button = list_next(button_itr))) {
  1125. if (send_grid_button->inx == grid_button->inx)
  1126. break;
  1127. }
  1128. list_iterator_destroy(button_itr);
  1129. if (send_grid_button)
  1130. continue;
  1131. send_grid_button = create_grid_button_from_another(
  1132. grid_button, grid_button->node_name, color_inx);
  1133. if (send_grid_button) {
  1134. send_grid_button->button_list = *button_list;
  1135. _add_button_signals(send_grid_button);
  1136. list_append(*button_list, send_grid_button);
  1137. }
  1138. }
  1139. list_iterator_destroy(itr);
  1140. return;
  1141. }
  1142. extern List copy_main_button_list(int initial_color)
  1143. {
  1144. ListIterator itr = NULL;
  1145. grid_button_t *grid_button = NULL;
  1146. grid_button_t *send_grid_button = NULL;
  1147. List button_list = list_create(destroy_grid_button);
  1148. itr = list_iterator_create(grid_button_list);
  1149. while ((grid_button = list_next(itr))) {
  1150. send_grid_button = create_grid_button_from_another(
  1151. grid_button, grid_button->node_name, initial_color);
  1152. if (send_grid_button) {
  1153. send_grid_button->button_list = button_list;
  1154. _add_button_signals(send_grid_button);
  1155. send_grid_button->used = false;
  1156. list_append(button_list, send_grid_button);
  1157. }
  1158. }
  1159. list_iterator_destroy(itr);
  1160. return button_list;
  1161. }
  1162. extern void add_extra_bluegene_buttons(List *button_list, int inx,
  1163. int *color_inx)
  1164. {
  1165. block_info_msg_t *block_ptr = NULL;
  1166. block_info_t *bg_info_ptr = NULL;
  1167. int rc = SLURM_SUCCESS;
  1168. ListIterator itr = NULL;
  1169. grid_button_t *grid_button = NULL;
  1170. grid_button_t *send_grid_button = NULL;
  1171. int i=0;
  1172. char *mp_str = NULL;
  1173. char tmp_nodes[256];
  1174. int found = 0;
  1175. int coord_y=0;
  1176. uint16_t orig_state;
  1177. rc = get_new_info_block(&block_ptr, 0);
  1178. if ((rc != SLURM_SUCCESS) && (rc != SLURM_NO_CHANGE_IN_DATA)) {
  1179. return;
  1180. }
  1181. if (!*button_list)
  1182. *button_list = list_create(NULL);
  1183. *color_inx %= sview_colors_cnt;
  1184. itr = list_iterator_create(grid_button_list);
  1185. while ((grid_button = list_next(itr))) {
  1186. if (grid_button->inx == inx)
  1187. break;
  1188. }
  1189. list_iterator_destroy(itr);
  1190. if (!grid_button)
  1191. return;
  1192. orig_state = grid_button->state;
  1193. /* remove all (if any) buttons pointing to this node since we
  1194. will be creating all of them */
  1195. itr = list_iterator_create(*button_list);
  1196. while ((send_grid_button = list_next(itr))) {
  1197. if (send_grid_button->inx == grid_button->inx)
  1198. list_remove(itr);
  1199. }
  1200. list_iterator_destroy(itr);
  1201. for (i=0; i < block_ptr->record_count; i++) {
  1202. bg_info_ptr = &block_ptr->block_array[i];
  1203. if (!_block_in_node(bg_info_ptr->mp_inx, inx))
  1204. continue;
  1205. found = 1;
  1206. mp_str = bg_info_ptr->mp_str;
  1207. if (bg_info_ptr->ionode_str) {
  1208. sprintf(tmp_nodes, "%s[%s]", mp_str,
  1209. bg_info_ptr->ionode_str);
  1210. mp_str = tmp_nodes;
  1211. }
  1212. if (bg_info_ptr->state & BG_BLOCK_ERROR_FLAG)
  1213. grid_button->state = NODE_STATE_ERROR;
  1214. else if (list_count(bg_info_ptr->job_list))
  1215. grid_button->state = NODE_STATE_ALLOCATED;
  1216. else
  1217. grid_button->state = NODE_STATE_IDLE;
  1218. send_grid_button = create_grid_button_from_another(
  1219. grid_button, mp_str, *color_inx);
  1220. grid_button->state = orig_state;
  1221. if (send_grid_button) {
  1222. send_grid_button->button_list = *button_list;
  1223. send_grid_button->table_x = 0;
  1224. send_grid_button->table_y = coord_y++;
  1225. //_add_button_signals(send_grid_button);
  1226. /* this is a different signal than usual */
  1227. g_signal_connect(
  1228. G_OBJECT(send_grid_button->button),
  1229. "button-press-event",
  1230. G_CALLBACK(_open_block),
  1231. send_grid_button);
  1232. g_signal_connect(G_OBJECT(grid_button->button),
  1233. "enter-notify-event",
  1234. G_CALLBACK(_mouseover_node),
  1235. grid_button);
  1236. g_signal_connect(G_OBJECT(grid_button->button),
  1237. "leave-notify-event",
  1238. G_CALLBACK(_mouseoff_node),
  1239. grid_button);
  1240. list_append(*button_list, send_grid_button);
  1241. (*color_inx)++;
  1242. }
  1243. }
  1244. if (!found) {
  1245. send_grid_button = create_grid_button_from_another(
  1246. grid_button, grid_button->node_name, *color_inx);
  1247. if (send_grid_button) {
  1248. send_grid_button->button_list = *button_list;
  1249. send_grid_button->table_x = 0;
  1250. send_grid_button->table_y = coord_y++;
  1251. _add_button_signals(send_grid_button);
  1252. list_append(*button_list, send_grid_button);
  1253. (*color_inx)++;
  1254. }
  1255. }
  1256. }
  1257. extern void add_extra_cr_buttons(List *button_list, node_info_t *node_ptr)
  1258. {
  1259. /* FIXME: this is here for consumable resources "multi-core"
  1260. and what not to add buttons for each. This needs to be added
  1261. when HP is done with the multi-core code. */
  1262. return;
  1263. }
  1264. extern void put_buttons_in_table(GtkTable *table, List button_list)
  1265. {
  1266. int coord_x=0, coord_y=0;
  1267. button_processor_t button_processor;
  1268. grid_button_t *grid_button = NULL;
  1269. ListIterator itr = NULL;
  1270. list_sort(button_list, (ListCmpF) _sort_button_inx);
  1271. if (!button_list) {
  1272. g_print("put_buttons_in_table: no node_list given\n");
  1273. return;
  1274. }
  1275. if (_init_button_processor(&button_processor, list_count(button_list))
  1276. != SLURM_SUCCESS)
  1277. return;
  1278. button_processor.table = table;
  1279. button_processor.button_list = button_list;
  1280. button_processor.coord_x = &coord_x;
  1281. button_processor.coord_y = &coord_y;
  1282. gtk_table_resize(table, button_processor.table_y,
  1283. working_sview_config.grid_x_width);
  1284. itr = list_iterator_create(button_list);
  1285. while ((grid_button = list_next(itr))) {
  1286. if (cluster_dims == 4) {
  1287. grid_button->table = table;
  1288. gtk_table_attach(table, grid_button->button,
  1289. grid_button->table_x,
  1290. (grid_button->table_x+1),
  1291. grid_button->table_y,
  1292. (grid_button->table_y+1),
  1293. GTK_SHRINK, GTK_SHRINK,
  1294. 1, 1);
  1295. if (!grid_button->table_x) {
  1296. gtk_table_set_row_spacing(table,
  1297. grid_button->table_y,
  1298. working_sview_config.gap_size);
  1299. }
  1300. } else if (cluster_dims == 3) {
  1301. grid_button->table = table;
  1302. gtk_table_attach(table, grid_button->button,
  1303. grid_button->table_x,
  1304. (grid_button->table_x+1),
  1305. grid_button->table_y,
  1306. (grid_button->table_y+1),
  1307. GTK_SHRINK, GTK_SHRINK,
  1308. 1, 1);
  1309. if (!grid_button->table_x) {
  1310. gtk_table_set_row_spacing(table,
  1311. grid_button->table_y,
  1312. working_sview_config.gap_size);
  1313. }
  1314. } else {
  1315. grid_button->table = table;
  1316. grid_button->table_x = coord_x;
  1317. grid_button->table_y = coord_y;
  1318. gtk_table_attach(table, grid_button->button,
  1319. coord_x, (coord_x+1),
  1320. coord_y, (coord_y+1),
  1321. GTK_SHRINK, GTK_SHRINK,
  1322. 1, 1);
  1323. coord_x++;
  1324. if (coord_x == working_sview_config.grid_x_width) {
  1325. coord_x = 0;
  1326. coord_y++;
  1327. if (!(coord_y % working_sview_config.grid_vert))
  1328. gtk_table_set_row_spacing(
  1329. table, coord_y-1,
  1330. working_sview_config.gap_size);
  1331. }
  1332. if (coord_y == button_processor.table_y)
  1333. break;
  1334. if (coord_x
  1335. && !(coord_x % working_sview_config.grid_hori))
  1336. gtk_table_set_col_spacing(table, coord_x-1, 5);
  1337. }
  1338. }
  1339. list_iterator_destroy(itr);
  1340. if (cluster_dims == 0) {
  1341. /* This is needed to get the correct width of the grid window.
  1342. * If it is not given then we get a really narrow window. */
  1343. gtk_table_set_row_spacing(table, coord_y?(coord_y-1):0, 1);
  1344. }
  1345. gtk_widget_show_all(GTK_WIDGET(table));
  1346. }
  1347. extern int update_grid_table(GtkTable *table, List button_list, List node_list)
  1348. {
  1349. int rc = SLURM_SUCCESS;
  1350. int coord_x=0, coord_y=0, inx=0;
  1351. ListIterator itr = NULL, itr2 = NULL;
  1352. sview_node_info_t *sview_node_info_ptr = NULL;
  1353. button_processor_t button_processor;
  1354. if (!node_list) {
  1355. g_print("update_grid_table: no node_list given\n");
  1356. return SLURM_ERROR;
  1357. }
  1358. if (_init_button_processor(&button_processor, list_count(node_list))
  1359. != SLURM_SUCCESS)
  1360. return SLURM_ERROR;
  1361. button_processor.table = table;
  1362. button_processor.button_list = button_list;
  1363. button_processor.coord_x = &coord_x;
  1364. button_processor.coord_y = &coord_y;
  1365. button_processor.inx = &inx;
  1366. gtk_table_resize(table, button_processor.table_y,
  1367. working_sview_config.grid_x_width);
  1368. gtk_table_set_row_spacings(table, 0);
  1369. gtk_table_set_col_spacings(table, 0);
  1370. itr = list_iterator_create(node_list);
  1371. itr2 = list_iterator_create(button_list);
  1372. while ((sview_node_info_ptr = list_next(itr))) {
  1373. int found = 0;
  1374. /* if (!working_sview_config.show_hidden */
  1375. /* && !check_part_includes_node(inx)) { */
  1376. /* inx++; */
  1377. /* continue; */
  1378. /* } */
  1379. // again:
  1380. while ((button_processor.grid_button = list_next(itr2))) {
  1381. if (button_processor.grid_button->inx != inx) {
  1382. continue;
  1383. }
  1384. found = 1;
  1385. if ((rc = _add_button_to_list(
  1386. sview_node_info_ptr->node_ptr,
  1387. &button_processor)) != SLURM_SUCCESS)
  1388. goto end_it;
  1389. break;
  1390. }
  1391. if (!found) {
  1392. //list_iterator_reset(itr2);
  1393. //goto again;
  1394. return RESET_GRID;
  1395. }
  1396. inx++;
  1397. }
  1398. rc = _add_button_to_list(NULL, &button_processor);
  1399. /* This is needed to get the correct width of the grid window.
  1400. * If it is not given then we get a really narrow window. */
  1401. gtk_table_set_row_spacing(table, coord_y?(coord_y-1):0, 1);
  1402. end_it:
  1403. list_iterator_destroy(itr);
  1404. list_iterator_destroy(itr2);
  1405. return rc;
  1406. }
  1407. extern int get_system_stats(GtkTable *table)
  1408. {
  1409. int rc = SLURM_SUCCESS;
  1410. node_info_msg_t *node_info_ptr = NULL;
  1411. List node_list = NULL;
  1412. if ((rc = get_new_info_node(&node_info_ptr, force_refresh))
  1413. == SLURM_NO_CHANGE_IN_DATA) {
  1414. } else if (rc != SLURM_SUCCESS)
  1415. return SLURM_ERROR;
  1416. select_g_ba_init(node_info_ptr, 0);
  1417. node_list = create_node_info_list(node_info_ptr, FALSE);
  1418. if (grid_button_list) {
  1419. rc = update_grid_table(main_grid_table, grid_button_list,
  1420. node_list);
  1421. if (rc == RESET_GRID) {
  1422. list_destroy(grid_button_list);
  1423. grid_button_list = NULL;
  1424. grid_button_list = list_create(destroy_grid_button);
  1425. setup_grid_table(main_grid_table, grid_button_list,
  1426. node_list);
  1427. }
  1428. } else {
  1429. grid_button_list = list_create(destroy_grid_button);
  1430. setup_grid_table(main_grid_table, grid_button_list, node_list);
  1431. }
  1432. gtk_widget_show_all(GTK_WIDGET(main_grid_table));
  1433. return SLURM_SUCCESS;
  1434. }
  1435. extern int setup_grid_table(GtkTable *table, List button_list, List node_list)
  1436. {
  1437. int rc = SLURM_SUCCESS;
  1438. button_processor_t button_processor;
  1439. int coord_x=0, coord_y=0;
  1440. if (!node_list) {
  1441. g_print("setup_grid_table: no node_list given\n");
  1442. return SLURM_ERROR;
  1443. }
  1444. if (_init_button_processor(&button_processor, list_count(node_list))
  1445. != SLURM_SUCCESS)
  1446. return SLURM_ERROR;
  1447. button_processor.table = table;
  1448. button_processor.button_list = button_list;
  1449. button_processor.coord_x = &coord_x;
  1450. button_processor.coord_y = &coord_y;
  1451. gtk_table_resize(table, button_processor.table_y,
  1452. working_sview_config.grid_x_width);
  1453. if (default_sview_config.grid_topological && g_topo_info_msg_ptr)
  1454. rc = _grid_table_by_switch(&button_processor, node_list);
  1455. else
  1456. rc = _grid_table_by_list(&button_processor, node_list);
  1457. list_sort(button_list, (ListCmpF) _sort_button_inx);
  1458. return rc;
  1459. }
  1460. extern void sview_init_grid(bool reset_highlight)
  1461. {
  1462. static node_info_msg_t *node_info_ptr = NULL;
  1463. int rc = SLURM_SUCCESS;
  1464. node_info_t *node_ptr = NULL;
  1465. int i = 0;
  1466. ListIterator itr = NULL;
  1467. grid_button_t *grid_button = NULL;
  1468. rc = get_new_info_node(&node_info_ptr, force_refresh);
  1469. if (rc == SLURM_NO_CHANGE_IN_DATA) {
  1470. /* need to clear out old data */
  1471. set_grid_used(grid_button_list, -1, -1, false, reset_highlight);
  1472. return;
  1473. } else if (rc != SLURM_SUCCESS) {
  1474. return;
  1475. }
  1476. if (!grid_button_list) {
  1477. g_print("you need to run get_system_stats() first\n");
  1478. exit(0);
  1479. }
  1480. itr = list_iterator_create(grid_button_list);
  1481. for (i = 0; i < node_info_ptr->record_count; i++) {
  1482. int tried_again = 0;
  1483. node_ptr = &node_info_ptr->node_array[i];
  1484. try_again:
  1485. while ((grid_button = list_next(itr))) {
  1486. if (grid_button->inx != i)
  1487. continue;
  1488. grid_button->state = node_ptr->node_state;
  1489. gtk_widget_set_state(grid_button->button,
  1490. GTK_STATE_NORMAL);
  1491. grid_button->used = false;
  1492. break;
  1493. }
  1494. if (!grid_button && !tried_again) {
  1495. /* the order should never change but just to
  1496. * make sure we don't miss it */
  1497. list_iterator_reset(itr);
  1498. tried_again = 1;
  1499. goto try_again;
  1500. }
  1501. }
  1502. list_iterator_destroy(itr);
  1503. }
  1504. /* make grid if it doesn't exist and set the buttons to unused */
  1505. extern void setup_popup_grid_list(popup_info_t *popup_win)
  1506. {
  1507. int def_color = MAKE_BLACK;
  1508. if (popup_win->grid_button_list) {
  1509. set_grid_used(popup_win->grid_button_list,
  1510. -1, -1, false, false);
  1511. } else {
  1512. popup_win->grid_button_list =
  1513. copy_main_button_list(def_color);
  1514. put_buttons_in_table(popup_win->grid_table,
  1515. popup_win->grid_button_list);
  1516. popup_win->full_grid = 1;
  1517. }
  1518. }
  1519. /* clear extra buttons to N/A and if model then set those as white */
  1520. extern void post_setup_popup_grid_list(popup_info_t *popup_win)
  1521. {

Large files files are truncated, but you can click here to view the full file