PageRenderTime 49ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/sview/common.c

https://github.com/cfenoy/slurm
C | 2345 lines | 1856 code | 320 blank | 169 comment | 347 complexity | 79ff246b67495de887e4dfe8bb13dc6f 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. * common.c - common functions used by tabs in sview
  3. *****************************************************************************
  4. * Copyright (C) 2004-2007 The Regents of the University of California.
  5. * Copyright (C) 2008-2009 Lawrence Livermore National Security.
  6. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  7. * Written by Danny Auble <da@llnl.gov>
  8. *
  9. * CODE-OCEC-09-009. All rights reserved.
  10. *
  11. * This file is part of SLURM, a resource management program.
  12. * For details, see <http://www.schedmd.com/slurmdocs/>.
  13. * Please also read the included file: DISCLAIMER.
  14. *
  15. * SLURM is free software; you can redistribute it and/or modify it under
  16. * the terms of the GNU General Public License as published by the Free
  17. * Software Foundation; either version 2 of the License, or (at your option)
  18. * any later version.
  19. *
  20. * SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  21. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  22. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  23. * details.
  24. *
  25. * You should have received a copy of the GNU General Public License along
  26. * with SLURM; if not, write to the Free Software Foundation, Inc.,
  27. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  28. \*****************************************************************************/
  29. #include "src/sview/sview.h"
  30. #include "src/common/parse_time.h"
  31. #include <gdk/gdkkeysyms.h>
  32. #define TOPO_DEBUG 0
  33. #define _DEBUG 0
  34. static bool menu_right_pressed = false;
  35. typedef struct {
  36. display_data_t *display_data;
  37. void (*pfunc)(GtkTreeModel*, GtkTreeIter*, int);
  38. GtkTreeView *tree_view;
  39. } each_t;
  40. typedef struct {
  41. GtkTreeIter iter;
  42. GtkTreeModel *model;
  43. GtkTreeView *treeview;
  44. } treedata_t;
  45. static gboolean control_key_in_effect = FALSE;
  46. static gboolean enter_key_in_effect = FALSE;
  47. static int _find_node_inx (char *name)
  48. {
  49. int i;
  50. if ((name == NULL) || (name[0] == '\0')) {
  51. info("_find_node_inx passed NULL name");
  52. return -1;
  53. }
  54. for (i = 0; i < g_node_info_ptr->record_count; i++) {
  55. if (!strcmp (name, g_node_info_ptr->node_array[i].name)) {
  56. return i;
  57. }
  58. }
  59. return -1;
  60. }
  61. static void _display_topology(void)
  62. {
  63. int i, match = 0, match_cnt = 0;
  64. hostset_t hs;
  65. int one_liner = 1;
  66. if (TOPO_DEBUG)
  67. g_print("_display_topology, record_count = %d\n",
  68. g_topo_info_msg_ptr->record_count);
  69. for (i=0; i<g_topo_info_msg_ptr->record_count; i++) {
  70. if ((g_topo_info_msg_ptr->topo_array[i].nodes == NULL) ||
  71. (g_topo_info_msg_ptr->topo_array[i].nodes[0] == '\0'))
  72. continue;
  73. if (g_topo_info_msg_ptr->topo_array[i].level == 0) {
  74. hs = hostset_create(g_topo_info_msg_ptr->
  75. topo_array[i].nodes);
  76. if (hs == NULL)
  77. fatal("hostset_create: memory "
  78. "allocation failure");
  79. }
  80. hostset_destroy(hs);
  81. if (!match)
  82. continue;
  83. match_cnt++;
  84. slurm_print_topo_record(stdout,
  85. &g_topo_info_msg_ptr->topo_array[i],
  86. one_liner);
  87. if (match_cnt == 0) {
  88. g_print("Topology information contains no switch or "
  89. "node named %s",
  90. g_topo_info_msg_ptr->topo_array[i].nodes);
  91. }
  92. }
  93. }
  94. static void _foreach_popup_all(GtkTreeModel *model,
  95. GtkTreePath *path,
  96. GtkTreeIter *iter,
  97. gpointer userdata)
  98. {
  99. each_t *each = userdata;
  100. each->pfunc(model, iter, each->display_data->id);
  101. }
  102. static void _foreach_full_info(GtkTreeModel *model,
  103. GtkTreePath *path,
  104. GtkTreeIter *iter,
  105. gpointer userdata)
  106. {
  107. each_t *each = userdata;
  108. (each->display_data->set_menu)(each->tree_view, NULL, path,
  109. FULL_CLICKED);
  110. popup_pos.x = popup_pos.slider + popup_pos.cntr * 10;
  111. popup_pos.y = popup_pos.cntr * 22;
  112. popup_pos.cntr++;
  113. if (popup_pos.cntr > 10) {
  114. popup_pos.cntr = 1;
  115. popup_pos.slider += 100;
  116. }
  117. }
  118. /* These next 2 functions are here to make it so we don't magically
  119. * click on something before we really want to in a menu.
  120. */
  121. static gboolean _menu_button_pressed(GtkWidget *widget, GdkEventButton *event,
  122. gpointer extra)
  123. {
  124. if (event->button == 3) {
  125. menu_right_pressed = true;
  126. return true;
  127. }
  128. return false;
  129. }
  130. static gboolean _menu_button_released(GtkWidget *widget, GdkEventButton *event,
  131. gpointer extra)
  132. {
  133. if (event->button == 3 && !menu_right_pressed)
  134. return true;
  135. menu_right_pressed = false;
  136. return false;
  137. }
  138. static gboolean _frame_callback(GtkWindow *window,
  139. GdkEvent *event, gpointer data)
  140. {
  141. if (event->expose.send_event == 0) {
  142. default_sview_config.fi_popup_width = event->configure.width;
  143. default_sview_config.fi_popup_height = event->configure.height;
  144. working_sview_config.fi_popup_width = event->configure.width;
  145. working_sview_config.fi_popup_height = event->configure.height;
  146. ListIterator itr = list_iterator_create(popup_list);
  147. popup_info_t *popup_win = NULL;
  148. while ((popup_win = list_next(itr))) {
  149. gtk_window_resize(GTK_WINDOW(popup_win->popup),
  150. working_sview_config.fi_popup_width,
  151. working_sview_config.fi_popup_height);
  152. }
  153. list_iterator_destroy(itr);
  154. }
  155. return FALSE;
  156. }
  157. static void _handle_response(GtkDialog *dialog, gint response_id,
  158. popup_info_t *popup_win)
  159. {
  160. switch(response_id) {
  161. case GTK_RESPONSE_OK: //refresh
  162. (popup_win->display_data->refresh)(NULL, popup_win);
  163. break;
  164. case GTK_RESPONSE_DELETE_EVENT: // exit
  165. case GTK_RESPONSE_CLOSE: // close
  166. delete_popup(NULL, NULL, popup_win->spec_info->title);
  167. break;
  168. case GTK_RESPONSE_CANCEL: // cancel
  169. delete_popups();
  170. break;
  171. default:
  172. g_print("handle unknown response %d\n", response_id);
  173. break;
  174. }
  175. return;
  176. }
  177. static int _sort_iter_compare_func_char(GtkTreeModel *model,
  178. GtkTreeIter *a,
  179. GtkTreeIter *b,
  180. gpointer userdata)
  181. {
  182. int sortcol = GPOINTER_TO_INT(userdata);
  183. int ret = 0;
  184. int len1 = 0, len2 = 0;
  185. gchar *name1 = NULL, *name2 = NULL;
  186. gtk_tree_model_get(model, a, sortcol, &name1, -1);
  187. gtk_tree_model_get(model, b, sortcol, &name2, -1);
  188. if (!name1 && !name2)
  189. goto cleanup; /* both equal => ret = 0 */
  190. else if (!name1 || !name2) {
  191. ret = (name1 == NULL) ? -1 : 1;
  192. } else {
  193. /* sort like a human would
  194. meaning snowflake2 would be greater than
  195. snowflake12 */
  196. len1 = strlen(name1);
  197. len2 = strlen(name2);
  198. while ((ret < len1) && (!g_ascii_isdigit(name1[ret])))
  199. ret++;
  200. if (ret < len1) {
  201. if (!g_ascii_strncasecmp(name1, name2, ret)) {
  202. if (len1 > len2)
  203. ret = 1;
  204. else if (len1 < len2)
  205. ret = -1;
  206. else
  207. ret = g_ascii_strcasecmp(name1, name2);
  208. } else
  209. ret = g_ascii_strcasecmp(name1, name2);
  210. } else
  211. ret = g_ascii_strcasecmp(name1, name2);
  212. }
  213. cleanup:
  214. g_free(name1);
  215. g_free(name2);
  216. return ret;
  217. }
  218. static int _sort_iter_compare_func_int(GtkTreeModel *model,
  219. GtkTreeIter *a,
  220. GtkTreeIter *b,
  221. gpointer userdata)
  222. {
  223. int sortcol = GPOINTER_TO_INT(userdata);
  224. int ret = 0;
  225. gint int1, int2;
  226. gtk_tree_model_get(model, a, sortcol, &int1, -1);
  227. gtk_tree_model_get(model, b, sortcol, &int2, -1);
  228. if (int1 != int2)
  229. ret = (int1 > int2) ? 1 : -1;
  230. return ret;
  231. }
  232. static int _sort_iter_compare_func_nodes(GtkTreeModel *model,
  233. GtkTreeIter *a,
  234. GtkTreeIter *b,
  235. gpointer userdata)
  236. {
  237. int sortcol = GPOINTER_TO_INT(userdata);
  238. int ret = 0;
  239. gchar *name1 = NULL, *name2 = NULL;
  240. gtk_tree_model_get(model, a, sortcol, &name1, -1);
  241. gtk_tree_model_get(model, b, sortcol, &name2, -1);
  242. if (!name1 && !name2)
  243. goto cleanup; /* both equal => ret = 0 */
  244. else if (!name1 || !name2)
  245. ret = (name1 == NULL) ? -1 : 1;
  246. else {
  247. uint64_t int1=0, int2=0, tmp_int;
  248. int spot=0;
  249. /* If this is in a mixed state we need to get them all */
  250. while (name1[spot]) {
  251. while (name1[spot]
  252. && !g_ascii_isdigit(name1[spot])) {
  253. spot++;
  254. }
  255. if (!name1[spot])
  256. break;
  257. tmp_int = atoi(name1+spot);
  258. while (name1[spot] && g_ascii_isdigit(name1[spot])) {
  259. spot++;
  260. }
  261. if (!name1[spot]) {
  262. } else if (name1[spot] == 'K')
  263. tmp_int *= 1024;
  264. else if (name1[spot] == 'M')
  265. tmp_int *= 1048576;
  266. else if (name1[spot] == 'G')
  267. tmp_int *= 1073741824;
  268. int1 += tmp_int;
  269. }
  270. spot=0;
  271. while (name2[spot]) {
  272. while (name2[spot]
  273. && !g_ascii_isdigit(name2[spot])) {
  274. spot++;
  275. }
  276. if (!name2[spot])
  277. break;
  278. tmp_int = atoi(name2+spot);
  279. while (name2[spot] && g_ascii_isdigit(name2[spot])) {
  280. spot++;
  281. }
  282. if (!name2[spot]) {
  283. } else if (name2[spot] == 'K')
  284. tmp_int *= 1024;
  285. else if (name2[spot] == 'M')
  286. tmp_int *= 1048576;
  287. else if (name2[spot] == 'G')
  288. tmp_int *= 1073741824;
  289. int2 += tmp_int;
  290. }
  291. if (int1 != int2)
  292. ret = (int1 > int2) ? 1 : -1;
  293. }
  294. cleanup:
  295. g_free(name1);
  296. g_free(name2);
  297. return ret;
  298. }
  299. /* Translate a three-digit alpha-numeric value into it's
  300. * base 36 equivalent number */
  301. static int _xlate_mp_coord(const char *name)
  302. {
  303. int i, rc = 0;
  304. for (i=0; i<cluster_dims; i++) {
  305. rc *= 36;
  306. rc += select_char2coord(name[i]);
  307. }
  308. return rc;
  309. }
  310. /* Make a BlueGene node name into a numeric representation of
  311. * its location.
  312. * Value is (low_node_coordinate * io_val_max) + I/O node (io_val if none)
  313. * with use of base 36 for the node coordinate on an L/P:
  314. * (e.g. bg123[4] -> 1,371,004
  315. * bg[234x235] -> 2,704,999
  316. * bglZZZ -> 46,655,999
  317. */
  318. static int _mp_coordinate(const char *name)
  319. {
  320. int i, io_val, io_val_max, low_val = -1;
  321. /* Since io_val needs to handle all dimensions of the ionode
  322. field with Q the number could be much bigger that 999.
  323. This will have to be handled when a new system comes with
  324. more dims.
  325. */
  326. if (cluster_flags & CLUSTER_FLAG_BGQ) {
  327. io_val = 99999;
  328. io_val_max = 100000;
  329. } else {
  330. io_val = 999;
  331. io_val_max = 1000;
  332. }
  333. for (i=0; name[i]; i++) {
  334. if (name[i] == '[') {
  335. i++;
  336. if (low_val < 0)
  337. low_val = _xlate_mp_coord(name+i);
  338. else
  339. io_val = atoi(name+i);
  340. break;
  341. } else if ((low_val < 0) &&
  342. ((name[i] >= '0' && (name[i] <= '9')) ||
  343. (name[i] >= 'A' && (name[i] <= 'Z')))) {
  344. low_val = _xlate_mp_coord(name+i);
  345. i += 2;
  346. }
  347. }
  348. if (low_val < 0)
  349. return low_val;
  350. return ((low_val * io_val_max) + io_val);
  351. }
  352. static int _sort_iter_compare_func_mp_list(GtkTreeModel *model,
  353. GtkTreeIter *a,
  354. GtkTreeIter *b,
  355. gpointer userdata)
  356. {
  357. int sortcol = GPOINTER_TO_INT(userdata);
  358. int ret = 0;
  359. gchar *name1 = NULL, *name2 = NULL;
  360. gtk_tree_model_get(model, a, sortcol, &name1, -1);
  361. gtk_tree_model_get(model, b, sortcol, &name2, -1);
  362. if (!name1 && !name2)
  363. goto cleanup; /* both equal => ret = 0 */
  364. else if (!name1 || !name2)
  365. ret = (name1 == NULL) ? -1 : 1;
  366. else {
  367. /* Sort in numeric order based upon coordinates */
  368. ret = _mp_coordinate(name1) - _mp_coordinate(name2);
  369. }
  370. cleanup:
  371. g_free(name1);
  372. g_free(name2);
  373. return ret;
  374. }
  375. static void _editing_started(GtkCellRenderer *cell,
  376. GtkCellEditable *editable,
  377. const gchar *path,
  378. gpointer data)
  379. {
  380. gdk_threads_leave();
  381. g_static_mutex_lock(&sview_mutex);
  382. }
  383. static void _editing_canceled(GtkCellRenderer *cell,
  384. gpointer data)
  385. {
  386. g_static_mutex_unlock(&sview_mutex);
  387. }
  388. static void *_editing_thr(gpointer arg)
  389. {
  390. int msg_id = 0;
  391. sleep(5);
  392. gdk_threads_enter();
  393. msg_id = GPOINTER_TO_INT(arg);
  394. gtk_statusbar_remove(GTK_STATUSBAR(main_statusbar),
  395. STATUS_ADMIN_EDIT, msg_id);
  396. //gdk_flush();
  397. gdk_threads_leave();
  398. return NULL;
  399. }
  400. static void _cell_data_func(GtkTreeViewColumn *col,
  401. GtkCellRenderer *renderer,
  402. GtkTreeModel *model,
  403. GtkTreeIter *iter,
  404. gpointer data)
  405. {
  406. GdkPixbuf *pixbuf = NULL;
  407. char *color_char, *color_char2;
  408. uint32_t color;
  409. g_object_get(renderer, "pixbuf", &pixbuf, NULL);
  410. if (!pixbuf)
  411. return;
  412. gtk_tree_model_get(model, iter,
  413. GPOINTER_TO_INT(g_object_get_data(G_OBJECT(renderer),
  414. "column")),
  415. &color_char, -1);
  416. if (!color_char)
  417. return;
  418. color_char2 = color_char+1;
  419. color = strtoul(color_char2, (char **)&color_char2, 16);
  420. g_free(color_char);
  421. /* we need to shift over 2 spots for the alpha */
  422. gdk_pixbuf_fill(pixbuf, color << 8);
  423. /* This only has to be done once, but I can't find any way to
  424. * set something to only make it happen once. It only takes
  425. * 3-5 usecs to do it so I didn't worry about it doing it
  426. * multiple times. If you can figure out how to make this
  427. * happen only once please fix, but the pointers for the col,
  428. * renderer, and pixbuf are all the same. You could put in
  429. * some think in the tree_model, but that seemed a bit more
  430. * cumbersome. - da
  431. */
  432. }
  433. static void _add_col_to_treeview(GtkTreeView *tree_view,
  434. display_data_t *display_data, int color_column)
  435. {
  436. GtkTreeViewColumn *col;
  437. GtkListStore *model;
  438. GtkCellRenderer *renderer = NULL;
  439. /* Since some systems have different default columns (some
  440. * which aren't displayed on all types of clusters only add a
  441. * column if there is a name for it. */
  442. if (!display_data->name && (display_data->extra != EDIT_COLOR))
  443. return;
  444. col = gtk_tree_view_column_new();
  445. model = (display_data->create_model)(display_data->id);
  446. if (model && display_data->extra != EDIT_NONE) {
  447. renderer = gtk_cell_renderer_combo_new();
  448. g_object_set(renderer,
  449. "model", model,
  450. "text-column", 0,
  451. "has-entry", 1,
  452. "editable", TRUE,
  453. NULL);
  454. } else if (display_data->extra == EDIT_TEXTBOX) {
  455. renderer = gtk_cell_renderer_text_new();
  456. g_object_set(renderer,
  457. "editable", TRUE,
  458. NULL);
  459. } else if (display_data->extra == EDIT_COLOR) {
  460. GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, false,
  461. 8, 10, 20);
  462. renderer = gtk_cell_renderer_pixbuf_new();
  463. g_object_set(renderer, "pixbuf", pixbuf, NULL);
  464. g_object_unref(pixbuf);
  465. } else
  466. renderer = gtk_cell_renderer_text_new();
  467. gtk_tree_view_column_pack_start(col, renderer, TRUE);
  468. g_object_set_data(G_OBJECT(renderer), "column",
  469. GINT_TO_POINTER(display_data->id));
  470. if (display_data->extra == EDIT_COLOR) {
  471. gtk_tree_view_column_set_cell_data_func(
  472. col, renderer, _cell_data_func,
  473. NULL, NULL);
  474. } else {
  475. g_signal_connect(renderer, "editing-started",
  476. G_CALLBACK(_editing_started), NULL);
  477. g_signal_connect(renderer, "editing-canceled",
  478. G_CALLBACK(_editing_canceled), NULL);
  479. g_signal_connect(renderer, "edited",
  480. G_CALLBACK(display_data->admin_edit),
  481. gtk_tree_view_get_model(tree_view));
  482. gtk_tree_view_column_add_attribute(col, renderer,
  483. "text", display_data->id);
  484. gtk_tree_view_column_set_expand(col, true);
  485. gtk_tree_view_column_set_reorderable(col, true);
  486. gtk_tree_view_column_set_resizable(col, true);
  487. gtk_tree_view_column_set_sort_column_id(col, display_data->id);
  488. gtk_tree_view_column_set_title(col, display_data->name);
  489. }
  490. gtk_tree_view_append_column(tree_view, col);
  491. }
  492. static void _toggle_state_changed(GtkCheckMenuItem *menuitem,
  493. display_data_t *display_data)
  494. {
  495. if (display_data->show)
  496. display_data->show = FALSE;
  497. else
  498. display_data->show = TRUE;
  499. toggled = TRUE;
  500. refresh_main(NULL, NULL);
  501. }
  502. static void _popup_state_changed(GtkCheckMenuItem *menuitem,
  503. display_data_t *display_data)
  504. {
  505. popup_info_t *popup_win = (popup_info_t *) display_data->user_data;
  506. if (display_data->show)
  507. display_data->show = FALSE;
  508. else
  509. display_data->show = TRUE;
  510. popup_win->toggled = 1;
  511. (display_data->refresh)(NULL, display_data->user_data);
  512. }
  513. static void _selected_page(GtkMenuItem *menuitem, display_data_t *display_data)
  514. {
  515. treedata_t *treedata = (treedata_t *)display_data->user_data;
  516. each_t each;
  517. memset(&each, 0, sizeof(each_t));
  518. each.tree_view = treedata->treeview;
  519. each.display_data = display_data;
  520. global_row_count = gtk_tree_selection_count_selected_rows(
  521. gtk_tree_view_get_selection(treedata->treeview));
  522. switch(display_data->extra & EXTRA_BASE) {
  523. case PART_PAGE:
  524. each.pfunc = &popup_all_part;
  525. break;
  526. case JOB_PAGE:
  527. each.pfunc = &popup_all_job;
  528. break;
  529. case NODE_PAGE:
  530. each.pfunc = &popup_all_node;
  531. break;
  532. case BLOCK_PAGE:
  533. each.pfunc = &popup_all_block;
  534. break;
  535. case RESV_PAGE:
  536. each.pfunc = &popup_all_resv;
  537. break;
  538. case FRONT_END_PAGE:
  539. each.pfunc = &popup_all_front_end;
  540. break;
  541. case ADMIN_PAGE:
  542. switch(display_data->id) {
  543. case JOB_PAGE:
  544. admin_job(treedata->model, &treedata->iter,
  545. display_data->name,treedata->treeview);
  546. break;
  547. case PART_PAGE:
  548. select_admin_partitions(treedata->model,
  549. &treedata->iter,
  550. display_data,
  551. treedata->treeview);
  552. break;
  553. case BLOCK_PAGE:
  554. select_admin_block(treedata->model, &treedata->iter,
  555. display_data, treedata->treeview);
  556. break;
  557. case FRONT_END_PAGE:
  558. select_admin_front_end(treedata->model,
  559. &treedata->iter,
  560. display_data,
  561. treedata->treeview);
  562. break;
  563. case RESV_PAGE:
  564. select_admin_resv(treedata->model, &treedata->iter,
  565. display_data, treedata->treeview);
  566. break;
  567. case NODE_PAGE:
  568. select_admin_nodes(treedata->model, &treedata->iter,
  569. display_data, NO_VAL,
  570. treedata->treeview);
  571. break;
  572. default:
  573. g_print("common admin got %d %d\n",
  574. display_data->extra,
  575. display_data->id);
  576. }
  577. break;
  578. default:
  579. g_print("common got %d %d\n", display_data->extra,
  580. display_data->id);
  581. }
  582. if (each.pfunc)
  583. gtk_tree_selection_selected_foreach(
  584. gtk_tree_view_get_selection(treedata->treeview),
  585. _foreach_popup_all, &each);
  586. xfree(treedata);
  587. }
  588. extern char * replspace (char *str)
  589. {
  590. int pntr = 0;
  591. while (str[pntr]) {
  592. if (str[pntr] == ' ')
  593. str[pntr] = '_';
  594. pntr++;
  595. }
  596. return str;
  597. }
  598. extern char * replus (char *str)
  599. {
  600. int pntr = 0;
  601. while (str[pntr]) {
  602. if (str[pntr] == '_')
  603. str[pntr] = ' ';
  604. pntr++;
  605. }
  606. return str;
  607. }
  608. extern char *delstr(char *str, char *orig)
  609. {
  610. static char buffer[150];
  611. char *p;
  612. if (!(p = strstr(str, orig)))
  613. return NULL;
  614. strncpy(buffer, str, p-str);
  615. strncpy(buffer+(p-str-1), p+strlen(orig), strlen(str)-(p-str));
  616. buffer[strlen(str) - strlen(orig)] = '\0';
  617. if (_DEBUG)
  618. g_print("delstr: new string <%s>\n", buffer);
  619. return buffer;
  620. }
  621. extern void free_switch_nodes_maps(
  622. switch_record_bitmaps_t *sw_nodes_bitmaps_ptr)
  623. {
  624. while (sw_nodes_bitmaps_ptr++) {
  625. if (!sw_nodes_bitmaps_ptr->node_bitmap)
  626. break;
  627. bit_free(sw_nodes_bitmaps_ptr->node_bitmap);
  628. if (sw_nodes_bitmaps_ptr->node_bitmap)
  629. xfree(sw_nodes_bitmaps_ptr->nodes);
  630. }
  631. g_switch_nodes_maps = NULL;
  632. }
  633. extern int build_nodes_bitmap(char *node_names, bitstr_t **bitmap)
  634. {
  635. char *this_node_name;
  636. bitstr_t *my_bitmap;
  637. hostlist_t host_list;
  638. int node_inx = -1;
  639. if (TOPO_DEBUG)
  640. g_print("...............build_nodes_bitmap............%s\n",
  641. node_names);
  642. my_bitmap = (bitstr_t *) bit_alloc(g_node_info_ptr->record_count);
  643. if (!my_bitmap) {
  644. fatal("bit_alloc malloc failure");
  645. }
  646. *bitmap = my_bitmap;
  647. if (!node_names) {
  648. error("build_nodes_bitmap: node_names is NULL");
  649. return EINVAL;
  650. }
  651. if (!(host_list = hostlist_create(node_names))) {
  652. error("build_nodes_bitmap: hostlist_create(%s) error",
  653. node_names);
  654. return EINVAL;
  655. }
  656. /*spin hostlist and map nodes into a bitmap*/
  657. while ((this_node_name = hostlist_shift(host_list))) {
  658. node_inx = _find_node_inx(this_node_name);
  659. free(this_node_name);
  660. if (node_inx == -1)
  661. continue;
  662. bit_set(my_bitmap, (bitoff_t)node_inx);
  663. }
  664. hostlist_destroy(host_list);
  665. return SLURM_SUCCESS;
  666. }
  667. extern int get_topo_conf(void)
  668. {
  669. int i;
  670. switch_record_bitmaps_t sw_nodes_bitmaps;
  671. switch_record_bitmaps_t *sw_nodes_bitmaps_ptr;
  672. if (TOPO_DEBUG)
  673. g_print("get_topo_conf\n");
  674. if (!g_topo_info_msg_ptr && slurm_load_topo(&g_topo_info_msg_ptr)) {
  675. slurm_perror ("slurm_load_topo error");
  676. if (TOPO_DEBUG)
  677. g_print("get_topo_conf error !!\n");
  678. return SLURM_ERROR;
  679. }
  680. if (g_topo_info_msg_ptr->record_count == 0) {
  681. slurm_free_topo_info_msg(g_topo_info_msg_ptr);
  682. g_topo_info_msg_ptr = NULL;
  683. return SLURM_ERROR;
  684. }
  685. if (g_switch_nodes_maps)
  686. free_switch_nodes_maps(g_switch_nodes_maps);
  687. g_switch_nodes_maps = xmalloc(sizeof(sw_nodes_bitmaps)
  688. * g_topo_info_msg_ptr->record_count);
  689. sw_nodes_bitmaps_ptr = g_switch_nodes_maps;
  690. if (TOPO_DEBUG)
  691. g_print("_display_topology, record_count = %d\n",
  692. g_topo_info_msg_ptr->record_count);
  693. for (i = 0; i < g_topo_info_msg_ptr->record_count;
  694. i++, sw_nodes_bitmaps_ptr++) {
  695. if (!g_topo_info_msg_ptr->topo_array[i].nodes)
  696. continue;
  697. if (TOPO_DEBUG) {
  698. g_print("ptr->nodes = %s \n",
  699. g_topo_info_msg_ptr->topo_array[i].nodes);
  700. }
  701. if (build_nodes_bitmap(
  702. g_topo_info_msg_ptr->topo_array[i].nodes,
  703. &sw_nodes_bitmaps_ptr->node_bitmap)) {
  704. g_print("Invalid node name (%s) in switch %s\n",
  705. g_topo_info_msg_ptr->topo_array[i].nodes,
  706. g_topo_info_msg_ptr->topo_array[i].name);
  707. }
  708. }
  709. if (TOPO_DEBUG)
  710. _display_topology();
  711. return SLURM_SUCCESS;
  712. }
  713. extern int get_row_number(GtkTreeView *tree_view, GtkTreePath *path)
  714. {
  715. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  716. GtkTreeIter iter;
  717. int line = 0;
  718. if (!model) {
  719. g_error("error getting the model from the tree_view");
  720. return -1;
  721. }
  722. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  723. g_error("get row, error getting iter from model");
  724. return -1;
  725. }
  726. gtk_tree_model_get(model, &iter, POS_LOC, &line, -1);
  727. return line;
  728. }
  729. extern int find_col(display_data_t *display_data, int type)
  730. {
  731. int i = 0;
  732. while (display_data++) {
  733. if (display_data->id == -1)
  734. break;
  735. if (display_data->id == type)
  736. return i;
  737. i++;
  738. }
  739. return -1;
  740. }
  741. extern const char *find_col_name(display_data_t *display_data, int type)
  742. {
  743. while (display_data++) {
  744. if (display_data->id == -1)
  745. break;
  746. if (display_data->id == type)
  747. return display_data->name;
  748. }
  749. return NULL;
  750. }
  751. extern void *get_pointer(GtkTreeView *tree_view, GtkTreePath *path, int loc)
  752. {
  753. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  754. GtkTreeIter iter;
  755. void *ptr = NULL;
  756. if (!model) {
  757. g_error("error getting the model from the tree_view");
  758. return ptr;
  759. }
  760. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  761. g_error("get pointer, error getting iter from model");
  762. return ptr;
  763. }
  764. gtk_tree_model_get(model, &iter, loc, &ptr, -1);
  765. return ptr;
  766. }
  767. extern void make_fields_menu(popup_info_t *popup_win, GtkMenu *menu,
  768. display_data_t *display_data, int count)
  769. {
  770. GtkWidget *menuitem = NULL;
  771. display_data_t *first_display_data = display_data;
  772. int i = 0;
  773. /* we don't want to display anything on the full info page */
  774. if (popup_win && popup_win->spec_info->type == INFO_PAGE)
  775. return;
  776. g_signal_connect(G_OBJECT(menu), "button-press-event",
  777. G_CALLBACK(_menu_button_pressed),
  778. NULL);
  779. g_signal_connect(G_OBJECT(menu), "button-release-event",
  780. G_CALLBACK(_menu_button_released),
  781. NULL);
  782. for(i=0; i<count; i++) {
  783. while (display_data++) {
  784. if (display_data->id == -1)
  785. break;
  786. if (!display_data->name)
  787. continue;
  788. if (display_data->id != i)
  789. continue;
  790. menuitem = gtk_check_menu_item_new_with_label(
  791. display_data->name);
  792. gtk_check_menu_item_set_active(
  793. GTK_CHECK_MENU_ITEM(menuitem),
  794. display_data->show);
  795. if (popup_win) {
  796. display_data->user_data = popup_win;
  797. g_signal_connect(
  798. menuitem, "toggled",
  799. G_CALLBACK(_popup_state_changed),
  800. display_data);
  801. } else {
  802. g_signal_connect(
  803. menuitem, "toggled",
  804. G_CALLBACK(_toggle_state_changed),
  805. display_data);
  806. }
  807. gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
  808. break;
  809. }
  810. display_data = first_display_data;
  811. }
  812. }
  813. extern void set_page_opts(int page, display_data_t *display_data,
  814. int count, char* initial_opts)
  815. {
  816. page_opts_t *page_opts;
  817. ListIterator itr = NULL;
  818. char *col_name = NULL;
  819. xassert(page < PAGE_CNT);
  820. page_opts = &working_sview_config.page_opts[page];
  821. if (!page_opts->col_list) {
  822. page_opts->def_col_list = 1;
  823. page_opts->col_list = list_create(slurm_destroy_char);
  824. slurm_addto_char_list(page_opts->col_list, initial_opts);
  825. }
  826. page_opts->display_data = display_data;
  827. itr = list_iterator_create(page_opts->col_list);
  828. while ((col_name = list_next(itr))) {
  829. replus(col_name);
  830. if (strstr(col_name, "list")) {
  831. char *orig_ptr = col_name;
  832. xstrsubstitute(col_name, "bp ", "midplane");
  833. if (cluster_flags & CLUSTER_FLAG_BG)
  834. xstrsubstitute(col_name, "node", "midplane");
  835. else
  836. xstrsubstitute(col_name, "midplane", "node");
  837. /* Make sure we have the correct pointer here
  838. since xstrsubstitute() could of changed it
  839. on us.
  840. */
  841. if (col_name != orig_ptr) {
  842. list_insert(itr, col_name);
  843. /* Don't use list_delete_item().
  844. xstrsubstitute() has already
  845. deleted it for us.
  846. */
  847. list_remove(itr);
  848. }
  849. }
  850. while (display_data++) {
  851. if (display_data->id == -1)
  852. break;
  853. if (!display_data->name)
  854. continue;
  855. if (!strncasecmp(col_name, display_data->name,
  856. strlen(col_name))) {
  857. display_data->show = TRUE;
  858. break;
  859. }
  860. }
  861. display_data = page_opts->display_data;
  862. }
  863. list_iterator_destroy(itr);
  864. }
  865. extern void make_options_menu(GtkTreeView *tree_view, GtkTreePath *path,
  866. GtkMenu *menu, display_data_t *display_data)
  867. {
  868. GtkWidget *menuitem = NULL;
  869. treedata_t *treedata = xmalloc(sizeof(treedata_t));
  870. treedata->model = gtk_tree_view_get_model(tree_view);
  871. treedata->treeview = tree_view;
  872. g_signal_connect(G_OBJECT(menu), "button-press-event",
  873. G_CALLBACK(_menu_button_pressed),
  874. NULL);
  875. g_signal_connect(G_OBJECT(menu), "button-release-event",
  876. G_CALLBACK(_menu_button_released),
  877. NULL);
  878. if (!gtk_tree_model_get_iter(treedata->model, &treedata->iter, path)) {
  879. g_error("make menus error getting iter from model\n");
  880. return;
  881. }
  882. /* check selection list */
  883. global_row_count = gtk_tree_selection_count_selected_rows(
  884. gtk_tree_view_get_selection(tree_view));
  885. if (display_data->user_data)
  886. xfree(display_data->user_data);
  887. while (display_data++) {
  888. if (display_data->id == -1) {
  889. break;
  890. }
  891. if (!display_data->name)
  892. continue;
  893. display_data->user_data = treedata;
  894. menuitem = gtk_menu_item_new_with_label(display_data->name);
  895. g_signal_connect(menuitem, "activate",
  896. G_CALLBACK(_selected_page),
  897. display_data);
  898. gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
  899. }
  900. }
  901. extern GtkScrolledWindow *create_scrolled_window(void)
  902. {
  903. GtkScrolledWindow *scrolled_window = NULL;
  904. GtkWidget *table = NULL;
  905. table = gtk_table_new(1, 1, FALSE);
  906. gtk_container_set_border_width(GTK_CONTAINER(table), 10);
  907. scrolled_window = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(
  908. NULL, NULL));
  909. gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 10);
  910. gtk_scrolled_window_set_policy(scrolled_window,
  911. GTK_POLICY_AUTOMATIC,
  912. GTK_POLICY_AUTOMATIC);
  913. gtk_scrolled_window_add_with_viewport(scrolled_window, table);
  914. return scrolled_window;
  915. }
  916. extern GtkWidget *create_entry(void)
  917. {
  918. GtkWidget *entry = gtk_entry_new();
  919. gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
  920. return entry;
  921. }
  922. extern void create_page(GtkNotebook *notebook, display_data_t *display_data)
  923. {
  924. GtkScrolledWindow *scrolled_window = create_scrolled_window();
  925. GtkWidget *event_box = gtk_event_box_new();
  926. GtkWidget *label = gtk_label_new(display_data->name);
  927. GtkWidget *close_button = gtk_event_box_new();
  928. GtkWidget *table = gtk_table_new(1, 3, FALSE);
  929. GtkWidget *image = NULL;
  930. int err;
  931. if (display_data->id == TAB_PAGE) {
  932. table = gtk_table_new(PAGE_CNT, 3, FALSE);
  933. image = gtk_image_new_from_stock(
  934. GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR);
  935. } else {
  936. table = gtk_table_new(1, 3, FALSE);
  937. image = gtk_image_new_from_stock(
  938. GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_SMALL_TOOLBAR);
  939. g_signal_connect(G_OBJECT(close_button), "button-press-event",
  940. G_CALLBACK(close_tab),
  941. display_data);
  942. }
  943. gtk_container_add(GTK_CONTAINER(close_button), image);
  944. gtk_widget_set_size_request(close_button, 10, 10);
  945. //gtk_event_box_set_above_child(GTK_EVENT_BOX(close_button), FALSE);
  946. gtk_container_add(GTK_CONTAINER(event_box), label);
  947. gtk_event_box_set_above_child(GTK_EVENT_BOX(event_box), FALSE);
  948. g_signal_connect(G_OBJECT(event_box), "button-press-event",
  949. G_CALLBACK(tab_pressed),
  950. display_data);
  951. gtk_table_set_homogeneous(GTK_TABLE(table), FALSE);
  952. gtk_table_set_col_spacings(GTK_TABLE(table), 5);
  953. gtk_container_set_border_width(GTK_CONTAINER(table), 1);
  954. gtk_table_attach_defaults(GTK_TABLE(table), event_box, 0, 1, 0, 1);
  955. gtk_table_attach_defaults(GTK_TABLE(table), close_button, 2, 3, 0, 1);
  956. gtk_container_set_focus_child(GTK_CONTAINER(table), label);
  957. gtk_widget_show_all(table);
  958. //(display_data->set_fields)(GTK_MENU(menu));
  959. if ((err = gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
  960. GTK_WIDGET(scrolled_window),
  961. table)) == -1) {
  962. g_error("Couldn't add page to notebook\n");
  963. }
  964. display_data->extra = err;
  965. }
  966. extern GtkTreeView *create_treeview(display_data_t *local, List *button_list)
  967. {
  968. signal_params_t *signal_params = xmalloc(sizeof(signal_params_t));
  969. GtkTreeView *tree_view = GTK_TREE_VIEW(gtk_tree_view_new());
  970. local->user_data = NULL;
  971. signal_params->display_data = local;
  972. signal_params->button_list = button_list;
  973. if (working_sview_config.ruled_treeview)
  974. gtk_tree_view_set_rules_hint (tree_view, true);
  975. g_signal_connect(G_OBJECT(tree_view), "button-press-event",
  976. G_CALLBACK(row_clicked),
  977. signal_params);
  978. g_signal_connect(G_OBJECT(tree_view), "key_release_event",
  979. G_CALLBACK(key_released),
  980. signal_params);
  981. g_signal_connect(G_OBJECT(tree_view), "key_press_event",
  982. G_CALLBACK(key_pressed),
  983. signal_params);
  984. g_signal_connect(G_OBJECT(tree_view), "row-activated",
  985. G_CALLBACK(row_activated),
  986. signal_params);
  987. gtk_widget_show(GTK_WIDGET(tree_view));
  988. list_push(signal_params_list, signal_params);
  989. return tree_view;
  990. }
  991. extern GtkTreeView *create_treeview_2cols_attach_to_table(GtkTable *table)
  992. {
  993. GtkTreeView *tree_view = GTK_TREE_VIEW(gtk_tree_view_new());
  994. GtkTreeStore *treestore =
  995. gtk_tree_store_new(3, GTK_TYPE_STRING,
  996. GTK_TYPE_STRING, GTK_TYPE_STRING);
  997. GtkTreeViewColumn *col = gtk_tree_view_column_new();
  998. GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
  999. if (working_sview_config.ruled_treeview)
  1000. gtk_tree_view_set_rules_hint (tree_view, true);
  1001. gtk_table_attach_defaults(table,
  1002. GTK_WIDGET(tree_view),
  1003. 0, 1, 0, 1);
  1004. gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(treestore));
  1005. gtk_tree_view_column_pack_start(col, renderer, TRUE);
  1006. gtk_tree_view_column_add_attribute(col, renderer,
  1007. "text", DISPLAY_NAME);
  1008. gtk_tree_view_column_add_attribute(col, renderer,
  1009. "font", DISPLAY_FONT);
  1010. gtk_tree_view_column_set_title(col, "Name");
  1011. gtk_tree_view_column_set_resizable(col, true);
  1012. gtk_tree_view_column_set_expand(col, true);
  1013. gtk_tree_view_append_column(tree_view, col);
  1014. col = gtk_tree_view_column_new();
  1015. renderer = gtk_cell_renderer_text_new();
  1016. gtk_tree_view_column_pack_start(col, renderer, TRUE);
  1017. gtk_tree_view_column_add_attribute(col, renderer,
  1018. "text", DISPLAY_VALUE);
  1019. gtk_tree_view_column_add_attribute(col, renderer,
  1020. "font", DISPLAY_FONT);
  1021. gtk_tree_view_column_set_title(col, "Value");
  1022. gtk_tree_view_column_set_resizable(col, true);
  1023. gtk_tree_view_column_set_expand(col, true);
  1024. gtk_tree_view_append_column(tree_view, col);
  1025. col = gtk_tree_view_column_new();
  1026. renderer = gtk_cell_renderer_text_new();
  1027. gtk_tree_view_column_pack_start(col, renderer, TRUE);
  1028. gtk_tree_view_column_set_visible(col, false);
  1029. gtk_tree_view_column_add_attribute(col, renderer,
  1030. "text", DISPLAY_FONT);
  1031. gtk_tree_view_append_column(tree_view, col);
  1032. g_object_unref(treestore);
  1033. return tree_view;
  1034. }
  1035. extern GtkTreeStore *create_treestore(GtkTreeView *tree_view,
  1036. display_data_t *display_data,
  1037. int count, int sort_column,
  1038. int color_column)
  1039. {
  1040. GtkTreeStore *treestore = NULL;
  1041. GType types[count];
  1042. int i=0;
  1043. /*set up the types defined in the display_data_t */
  1044. for(i=0; i<count; i++) {
  1045. types[display_data[i].id] = display_data[i].type;
  1046. }
  1047. treestore = gtk_tree_store_newv(count, types);
  1048. if (!treestore) {
  1049. g_print("Can't create treestore.\n");
  1050. return NULL;
  1051. }
  1052. gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL(treestore));
  1053. for(i=1; i<count; i++) {
  1054. if (!display_data[i].show)
  1055. continue;
  1056. _add_col_to_treeview(tree_view, &display_data[i], color_column);
  1057. if (!display_data[i].name)
  1058. continue;
  1059. switch(display_data[i].type) {
  1060. case G_TYPE_INT:
  1061. gtk_tree_sortable_set_sort_func(
  1062. GTK_TREE_SORTABLE(treestore),
  1063. display_data[i].id,
  1064. _sort_iter_compare_func_int,
  1065. GINT_TO_POINTER(display_data[i].id),
  1066. NULL);
  1067. break;
  1068. case G_TYPE_STRING:
  1069. if (!strcasecmp(display_data[i].name, "Node Count")
  1070. || !strcasecmp(display_data[i].name, "CPU Count")
  1071. || !strcasecmp(display_data[i].name, "Real Memory")
  1072. || !strcasecmp(display_data[i].name, "Tmp Disk")) {
  1073. gtk_tree_sortable_set_sort_func(
  1074. GTK_TREE_SORTABLE(treestore),
  1075. display_data[i].id,
  1076. _sort_iter_compare_func_nodes,
  1077. GINT_TO_POINTER(display_data[i].id),
  1078. NULL);
  1079. break;
  1080. } else if (!strcasecmp(display_data[i].name,
  1081. "MidplaneList")) {
  1082. gtk_tree_sortable_set_sort_func(
  1083. GTK_TREE_SORTABLE(treestore),
  1084. display_data[i].id,
  1085. _sort_iter_compare_func_mp_list,
  1086. GINT_TO_POINTER(display_data[i].id),
  1087. NULL);
  1088. break;
  1089. } else {
  1090. gtk_tree_sortable_set_sort_func(
  1091. GTK_TREE_SORTABLE(treestore),
  1092. display_data[i].id,
  1093. _sort_iter_compare_func_char,
  1094. GINT_TO_POINTER(display_data[i].id),
  1095. NULL);
  1096. break;
  1097. }
  1098. default:
  1099. g_print("unknown type %d",
  1100. (int)display_data[i].type);
  1101. }
  1102. }
  1103. if (sort_column >= 0) {
  1104. gtk_tree_sortable_set_sort_column_id(
  1105. GTK_TREE_SORTABLE(treestore),
  1106. sort_column,
  1107. GTK_SORT_ASCENDING);
  1108. }
  1109. g_object_unref(treestore);
  1110. return treestore;
  1111. }
  1112. extern gboolean right_button_pressed(GtkTreeView *tree_view,
  1113. GtkTreePath *path,
  1114. GdkEventButton *event,
  1115. const signal_params_t *signal_params,
  1116. int type)
  1117. {
  1118. GtkMenu *menu = GTK_MENU(gtk_menu_new());
  1119. display_data_t *display_data = signal_params->display_data;
  1120. if (type == ROW_CLICKED) {
  1121. if (_DEBUG)
  1122. g_print("right_button_pressed:global_row_count : %d\n",
  1123. global_row_count);
  1124. /* These next 2 functions are there to keep the keyboard in
  1125. sync */
  1126. if (!(event->state & GDK_CONTROL_MASK)
  1127. && (!(global_row_count > 0)))
  1128. gtk_tree_view_set_cursor(tree_view, path, NULL, false);
  1129. gtk_widget_grab_focus(GTK_WIDGET(tree_view));
  1130. /* highlight the nodes from this row */
  1131. (display_data->set_menu)(tree_view, *signal_params->button_list,
  1132. path, ROW_LEFT_CLICKED);
  1133. }
  1134. (display_data->set_menu)(tree_view, menu, path, type);
  1135. gtk_widget_show_all(GTK_WIDGET(menu));
  1136. gtk_menu_popup(menu, NULL, NULL, NULL, NULL,
  1137. event ? event->button : 0,
  1138. gdk_event_get_time((GdkEvent*)event));
  1139. return true;
  1140. }
  1141. extern gboolean left_button_pressed(GtkTreeView *tree_view,
  1142. GtkTreePath *path,
  1143. const signal_params_t *signal_params,
  1144. GdkEventButton *event)
  1145. {
  1146. static time_t last_time = 0;
  1147. time_t now = time(NULL);
  1148. gboolean rc = false;
  1149. GtkTreeIter iter;
  1150. GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  1151. display_data_t *display_data = signal_params->display_data;
  1152. static gpointer *last_user_data = NULL;
  1153. /* These next 2 functions are there to keep the keyboard in
  1154. sync */
  1155. if (!((event->state & GDK_CONTROL_MASK)
  1156. || (event->state & GDK_SHIFT_MASK)))
  1157. gtk_tree_view_set_cursor(tree_view, path, NULL, false);
  1158. gtk_widget_grab_focus(GTK_WIDGET(tree_view)); /*give keyboard focus*/
  1159. if (signal_params->button_list) {
  1160. (display_data->set_menu)(tree_view, *signal_params->button_list,
  1161. path, ROW_LEFT_CLICKED);
  1162. } else
  1163. (display_data->set_menu)(tree_view, NULL, path, FULL_CLICKED);
  1164. /* make sure it was a double click */
  1165. if (!gtk_tree_model_get_iter(model, &iter, path)) {
  1166. g_error("left pressed, error getting iter from model\n");
  1167. return rc;
  1168. }
  1169. if (!(now-last_time)
  1170. && (!last_user_data || (iter.user_data == last_user_data))) {
  1171. /* double click */
  1172. (display_data->set_menu)(tree_view, NULL, path, FULL_CLICKED);
  1173. }
  1174. last_user_data = iter.user_data;
  1175. if (!working_sview_config.admin_mode)
  1176. rc = true;
  1177. last_time = now;
  1178. return rc;
  1179. }
  1180. extern gboolean row_activated(GtkTreeView *tree_view, GtkTreePath *path,
  1181. GtkTreeViewColumn *column,
  1182. const signal_params_t *signal_params)
  1183. {
  1184. display_data_t *display_data = signal_params->display_data;
  1185. /* highlight the nodes from this row */
  1186. (display_data->set_menu)(tree_view, *signal_params->button_list,
  1187. path, ROW_LEFT_CLICKED);
  1188. /* display the full info */
  1189. if (!enter_key_in_effect)
  1190. (display_data->set_menu)(tree_view, NULL, path, FULL_CLICKED);
  1191. enter_key_in_effect = FALSE;
  1192. return false;
  1193. }
  1194. extern gboolean key_pressed(GtkTreeView *tree_view,
  1195. GdkEventKey *event,
  1196. const signal_params_t *signal_params)
  1197. {
  1198. GtkTreePath *path = NULL;
  1199. GtkTreeViewColumn *column;
  1200. control_key_in_effect = FALSE;
  1201. enter_key_in_effect = FALSE;
  1202. if ((event->keyval == GDK_Control_L) ||
  1203. (event->keyval == GDK_Control_R))
  1204. control_key_in_effect = TRUE;
  1205. else if (event->keyval == GDK_Return) {
  1206. each_t each;
  1207. GtkTreeSelection *selection = NULL;
  1208. gtk_tree_view_get_cursor(GTK_TREE_VIEW(tree_view),
  1209. &path, &column);
  1210. selection = gtk_tree_view_get_selection(tree_view);
  1211. memset(&each, 0, sizeof(each_t));
  1212. each.tree_view = tree_view;
  1213. each.display_data = signal_params->display_data;
  1214. global_row_count =
  1215. gtk_tree_selection_count_selected_rows(selection);
  1216. popup_pos.x = 10;
  1217. popup_pos.x = 10;
  1218. popup_pos.cntr = 1;
  1219. popup_pos.slider = 0;
  1220. gtk_tree_selection_selected_foreach(
  1221. selection, _foreach_full_info, &each);
  1222. /*prevent row_activation from
  1223. * performing a redundant 'full info'*/
  1224. enter_key_in_effect = TRUE;
  1225. }
  1226. return FALSE;
  1227. }/*key_pressed ^^^*/
  1228. extern gboolean key_released(GtkTreeView *tree_view,
  1229. GdkEventKey *event,
  1230. const signal_params_t *signal_params)
  1231. {
  1232. GtkTreePath *path = NULL;
  1233. GtkTreeViewColumn *column;
  1234. GtkTreeSelection *selection = NULL;
  1235. if ((event->keyval != GDK_Up) &&
  1236. (event->keyval != GDK_Down) &&
  1237. (event->keyval != GDK_Return))
  1238. return TRUE;
  1239. gtk_tree_view_get_cursor(GTK_TREE_VIEW(tree_view), &path, &column);
  1240. if (path) {
  1241. selection = gtk_tree_view_get_selection(tree_view);
  1242. gtk_tree_selection_select_path(selection, path);
  1243. gtk_tree_path_free(path);
  1244. }
  1245. return TRUE;
  1246. }/*key_released ^^^*/
  1247. extern gboolean row_clicked(GtkTreeView *tree_view, GdkEventButton *event,
  1248. const signal_params_t *signal_params)
  1249. {
  1250. GtkTreePath *path = NULL;
  1251. GtkTreePath *last_path = NULL;
  1252. GtkTreeSelection *selection = NULL;
  1253. gboolean did_something = FALSE;
  1254. gboolean selected_in_current_mix = FALSE;
  1255. if (!gtk_tree_view_get_path_at_pos(tree_view,
  1256. (gint) event->x,
  1257. (gint) event->y,
  1258. &path, NULL, NULL, NULL)) {
  1259. selection = gtk_tree_view_get_selection(tree_view);
  1260. /* If there is a selection AND we are not under
  1261. * multi-selection processing via the ctrl key clear
  1262. * it up by doing a refresh. If there wasn't a
  1263. * selection before OR we are stacking selections via
  1264. * the ctrl key do nothing here. */
  1265. if (gtk_tree_selection_count_selected_rows(selection)){
  1266. if (!(event->state & GDK_CONTROL_MASK))
  1267. gtk_tree_selection_unselect_all(selection);
  1268. refresh_main(NULL, NULL);
  1269. return TRUE;
  1270. }
  1271. return FALSE;
  1272. }
  1273. /* make the selection (highlight) here */
  1274. selection = gtk_tree_view_get_selection(tree_view);
  1275. global_row_count =
  1276. gtk_tree_selection_count_selected_rows(selection);
  1277. /*flag this for rightclick to unselect on*/
  1278. selected_in_current_mix =
  1279. gtk_tree_selection_path_is_selected(selection, path);
  1280. if (event->button != 3) {
  1281. /*if Lshift is down then pull a range out*/
  1282. if ((event->state & GDK_SHIFT_MASK)) {
  1283. if (last_event_x != 0) {
  1284. if (gtk_tree_view_get_path_at_pos(
  1285. tree_view,
  1286. (gint) last_event_x,
  1287. (gint) last_event_y,
  1288. &last_path, NULL, NULL, NULL)) {
  1289. if (last_path) {
  1290. gtk_tree_selection_select_range(
  1291. selection, last_path,
  1292. path);
  1293. gtk_tree_path_free(last_path);
  1294. }
  1295. }
  1296. } else if (path) {
  1297. /*ignore shift and pull single row anyway*/
  1298. gtk_tree_selection_select_path(selection,
  1299. path);
  1300. }
  1301. } /*shift down^^*/
  1302. }
  1303. last_event_x = event->x; /*save THIS x*/
  1304. last_event_y = event->y; /*save THIS y*/
  1305. if (event->x <= 20) {
  1306. /* When you try to resize a column this event happens
  1307. for some reason. Resizing always happens in the
  1308. first 2 of x so if that happens just return and
  1309. continue. Also if we want to expand/collapse a
  1310. column, that happens in the first 20 so just skip
  1311. that also. */
  1312. did_something = FALSE;
  1313. } else if (event->button == 1) {
  1314. /* left click */
  1315. if (!(event->state & GDK_CONTROL_MASK)
  1316. && !(event->state & GDK_SHIFT_MASK)) {
  1317. /* unselect current on naked left clicks..*/
  1318. gtk_tree_selection_unselect_all(selection);
  1319. }
  1320. did_something = left_button_pressed(
  1321. tree_view, path, signal_params, event);
  1322. } else if (event->button == 3) {
  1323. /* right click */
  1324. if (!selected_in_current_mix) {
  1325. if (!(event->state & GDK_CONTROL_MASK)){
  1326. gtk_tree_selection_unselect_all(selection);
  1327. } else if (path)
  1328. gtk_tree_selection_select_path(selection, path);
  1329. }
  1330. global_row_count =
  1331. gtk_tree_selection_count_selected_rows(selection);
  1332. if (_DEBUG)
  1333. g_print("row_clicked:global_row_count2 : %d \n",
  1334. global_row_count);
  1335. /*prevent rc processing if under contol/shift*/
  1336. if (!(event->state & GDK_CONTROL_MASK)
  1337. && !(event->state & GDK_SHIFT_MASK))
  1338. right_button_pressed(tree_view, path, event,
  1339. signal_params, ROW_CLICKED);
  1340. did_something = TRUE;
  1341. } else if (!working_sview_config.admin_mode)
  1342. did_something = TRUE;
  1343. gtk_tree_path_free(path);
  1344. /* If control key held refresh main (which does the grid and
  1345. exit with false to reset the treeview. This has to happen
  1346. after left_button_pressed to get other things correct. */
  1347. if (event->state & GDK_CONTROL_MASK) {
  1348. refresh_main(NULL, NULL);
  1349. return FALSE; /*propagate event*/
  1350. }
  1351. return did_something;
  1352. }
  1353. extern popup_info_t *create_popup_info(int type, int dest_type, char *title)
  1354. {
  1355. GtkScrolledWindow *window = NULL;
  1356. GtkBin *bin = NULL;
  1357. GtkViewport *view = NULL;
  1358. GtkWidget *label = NULL;
  1359. GtkWidget *table = NULL;
  1360. GtkWidget *close_btn = NULL;
  1361. popup_info_t *popup_win = xmalloc(sizeof(popup_info_t));
  1362. // int i=0;
  1363. list_push(popup_list, popup_win);
  1364. popup_win->spec_info = xmalloc(sizeof(specific_info_t));
  1365. popup_win->spec_info->search_info =
  1366. xmalloc(sizeof(sview_search_info_t));
  1367. popup_win->spec_info->search_info->search_type = 0;
  1368. popup_win->spec_info->search_info->gchar_data = NULL;
  1369. popup_win->spec_info->search_info->int_data = NO_VAL;
  1370. popup_win->spec_info->search_info->int_data2 = NO_VAL;
  1371. popup_win->spec_info->type = type;
  1372. popup_win->spec_info->title = xstrdup(title);
  1373. popup_win->popup = gtk_dialog_new_with_buttons(
  1374. title,
  1375. GTK_WINDOW(main_window),
  1376. GTK_DIALOG_DESTROY_WITH_PARENT,
  1377. GTK_STOCK_REFRESH,
  1378. GTK_RESPONSE_OK,
  1379. NULL);
  1380. close_btn = gtk_dialog_add_button(GTK_DIALOG(popup_win->popup),
  1381. GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
  1382. gtk_window_set_focus(GTK_WINDOW(popup_win->popup), close_btn);
  1383. gtk_dialog_add_button(GTK_DIALOG(popup_win->popup),
  1384. "Close All Popups", GTK_RESPONSE_CANCEL);
  1385. popup_win->show_grid = 1;
  1386. popup_win->toggled = 0;
  1387. popup_win->force_refresh = 0;
  1388. popup_win->type = dest_type;
  1389. popup_win->not_found = false;
  1390. /*
  1391. for(i=0;; i++) {
  1392. if (main_popup_positioner[i].width == -1)
  1393. break;
  1394. if (strstr(title,main_popup_positioner[i].name)) {
  1395. width = main_popup_positioner[i].width;
  1396. height = main_popup_positioner[i].height;
  1397. break;
  1398. }
  1399. }
  1400. */
  1401. gtk_window_set_default_size(GTK_WINDOW(popup_win->popup),
  1402. working_sview_config.fi_popup_width,
  1403. working_sview_config.fi_popup_height);
  1404. gtk_window_set_transient_for(GTK_WINDOW(popup_win->popup), NULL);
  1405. popup_win->event_box = gtk_event_box_new();
  1406. label = gtk_label_new(popup_win->spec_info->title);
  1407. gtk_container_add(GTK_CONTAINER(popup_win->event_box), label);
  1408. g_signal_connect(G_OBJECT(popup_win->event_box),
  1409. "button-press-event",
  1410. G_CALLBACK(redo_popup),
  1411. popup_win);
  1412. gtk_event_box_set_above_child(
  1413. GTK_EVENT_BOX(popup_win->event_box),
  1414. FALSE);
  1415. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup_win->popup)->vbox),
  1416. popup_win->event_box, FALSE, FALSE, 0);
  1417. window = create_scrolled_window();
  1418. gtk_scrolled_window_set_policy(window,
  1419. GTK_POLICY_NEVER,
  1420. GTK_POLICY_AUTOMATIC);
  1421. bin = GTK_BIN(&window->container);
  1422. view = GTK_VIEWPORT(bin->child);
  1423. bin = GTK_BIN(&view->bin);
  1424. popup_win->grid_table = GTK_TABLE(bin->child);
  1425. popup_win->grid_button_list = NULL;
  1426. table = gtk_table_new(1, 2, FALSE);
  1427. gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(window), 0, 1, 0, 1,
  1428. GTK_SHRINK, GTK_EXPAND | GTK_FILL,
  1429. 0, 0);
  1430. window = create_scrolled_window();
  1431. bin = GTK_BIN(&window->container);
  1432. view = GTK_VIEWPORT(bin->child);
  1433. bin = GTK_BIN(&view->bin);
  1434. popup_win->table = GTK_TABLE(bin->child);
  1435. gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(window),
  1436. 1, 2, 0, 1);
  1437. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(popup_win->popup)->vbox),
  1438. table, TRUE, TRUE, 0);
  1439. g_signal_connect(G_OBJECT(popup_win->popup), "delete_event",
  1440. G_CALLBACK(delete_popup),
  1441. popup_win->spec_info->title);
  1442. g_signal_connect(G_OBJECT(popup_win->popup), "response",
  1443. G_CALLBACK(_handle_response),
  1444. popup_win);
  1445. g_signal_connect(G_OBJECT(popup_win->popup), "configure-event",
  1446. G_CALLBACK(_frame_callback),
  1447. popup_win);
  1448. gtk_window_move(GTK_WINDOW(popup_win->popup),
  1449. popup_pos.x, popup_pos.y);
  1450. gtk_widget_show_all(popup_win->popup);
  1451. return popup_win;
  1452. }
  1453. extern void setup_popup_info(popup_info_t *popup_win,
  1454. display_data_t *display_data,
  1455. int cnt)
  1456. {
  1457. int i = 0;
  1458. popup_win->display_data = xmalloc(sizeof(display_data_t)*(cnt+2));
  1459. for(i=0; i<cnt+1; i++) {
  1460. memcpy(&popup_win->display_data[i],
  1461. &display_data[i],
  1462. sizeof(display_data_t));
  1463. }
  1464. }
  1465. extern void redo_popup(GtkWidget *widget, GdkEventButton *event,
  1466. popup_info_t *popup_win)
  1467. {
  1468. if (event->button == 3) {
  1469. GtkMenu *menu = GTK_MENU(gtk_menu_new());
  1470. (popup_win->display_data->set_menu)(popup_win, menu,
  1471. NULL,
  1472. POPUP_CLICKED);
  1473. gtk_widget_show_all(GTK_WIDGET(menu));
  1474. gtk_menu_popup(menu, NULL, NULL, NULL, NULL,
  1475. event ? event->button : 0,
  1476. gdk_event_get_time((GdkEvent*)event));
  1477. }
  1478. }
  1479. extern void destroy_search_info(void *arg)
  1480. {
  1481. sview_search_info_t *search_info = (sview_search_info_t *)arg;
  1482. if (search_info) {
  1483. if (search_info->gchar_data)
  1484. g_free(search_info->gchar_data);
  1485. search_info->gchar_data = NULL;
  1486. xfree(search_info);
  1487. search_info = NULL;
  1488. }
  1489. }
  1490. extern void destroy_specific_info(void *arg)
  1491. {
  1492. specific_info_t *spec_info = (specific_info_t *)arg;
  1493. if (spec_info) {
  1494. xfree(spec_info->title);
  1495. destroy_search_info(spec_info->search_info);
  1496. if (spec_info->display_widget) {
  1497. gtk_widget_destroy(spec_info->display_widget);
  1498. spec_info->display_widget = NULL;
  1499. }
  1500. xfree(spec_info);
  1501. }
  1502. }
  1503. extern void destroy_popup_info(void *arg)
  1504. {
  1505. popup_info_t *popup_win = (popup_info_t *)arg;
  1506. if (popup_win) {
  1507. *popup_win->running = 0;
  1508. g_static_mutex_lock(&sview_mutex);
  1509. /* these are all childern of each other so must
  1510. be freed in this order */
  1511. if (popup_win->grid_button_list) {
  1512. list_destroy(popup_win->grid_button_list);
  1513. popup_win->grid_button_list = NULL;
  1514. }
  1515. if (popup_win->table) {
  1516. gtk_widget_destroy(GTK_WIDGET(popup_win->table));
  1517. popup_win->table = NULL;
  1518. }
  1519. if (popup_win->grid_table) {
  1520. gtk_widget_destroy(GTK_WIDGET(popup_win->grid_table));
  1521. popup_win->grid_table = NULL;
  1522. }
  1523. if (popup_win->event_box) {
  1524. gtk_widget_destroy(popup_win->event_box);
  1525. popup_win->event_box = NULL;
  1526. }
  1527. if (popup_win->popup) {
  1528. gtk_widget_destroy(popup_win->popup);
  1529. popup_win->popup = NULL;
  1530. }
  1531. destroy_specific_info(popup_win->spec_info);
  1532. xfree(popup_win->display_data);
  1533. xfree(popup_win);
  1534. g_static_mutex_unlock(&sview_mutex);
  1535. }
  1536. }
  1537. extern void destroy_signal_params(void *arg)
  1538. {
  1539. signal_params_t *signal_params = (signal_params_t *)arg;
  1540. if (signal_params) {
  1541. xfree(signal_params);
  1542. }
  1543. }
  1544. extern gboolean delete_popup(GtkWidget *widget, GtkWidget *event, char *title)
  1545. {
  1546. ListIterator itr = list_iterator_create(popup_list);
  1547. popup_info_t *popup_win = NULL;
  1548. while ((popup_win = list_next(itr))) {
  1549. if (popup_win->spec_info) {
  1550. if (!strcmp(popup_win->spec_info->title, title)) {
  1551. //g_print("removing %s\n", title);
  1552. list_remove(itr);
  1553. destroy_popup_info(popup_win);
  1554. break;
  1555. }
  1556. }
  1557. }
  1558. list_iterator_destroy(itr);
  1559. return FALSE;
  1560. }
  1561. extern gboolean delete_popups(void)
  1562. {
  1563. ListIterator itr = list_iterator_create(popup_list);
  1564. popup_info_t *popup_win = NULL;
  1565. while ((popup_win = list_next(itr))) {
  1566. list_remove(itr);
  1567. destroy_popup_info(popup_win);
  1568. }
  1569. list_iterator_destroy(itr);
  1570. return FALSE;
  1571. }
  1572. extern void *popup_thr(popup_info_t *popup_win)
  1573. {
  1574. void (*specifc_info) (popup_info_t *popup_win) = NULL;
  1575. int running = 1;
  1576. if (_DEBUG)
  1577. g_print("popup_thr:global_row_count = %d \n",
  1578. global_row_count);
  1579. switch(popup_win->type) {
  1580. case PART_PAGE:
  1581. specifc_info = specific_info_part;
  1582. break;
  1583. case JOB_PAGE:
  1584. specifc_info = specific_info_job;
  1585. break;
  1586. case NODE_PAGE:
  1587. specifc_info = specific_info_node;
  1588. break;
  1589. case BLOCK_PAGE:
  1590. specifc_info = specific_info_block;
  1591. break;
  1592. case RESV_PAGE:
  1593. specifc_info = specific_info_resv;
  1594. break;
  1595. case FRONT_END_PAGE:
  1596. specifc_info = specific_info_front_end;
  1597. break;
  1598. case SUBMIT_PAGE:
  1599. default:
  1600. g_print("thread got unknown type %d\n", popup_win->type);
  1601. return NULL;
  1602. }
  1603. /* this will switch to 0 when popup is closed. */
  1604. popup_win->running = &running;
  1605. /* wh…

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