soc/intel/skl: Add AML IccMax and remove unused info
[coreboot.git] / util / kconfig / gconf.c
blobfaa1c59b8e5bd0652e041146a3f5a28ba124f02a
1 /* Hey EMACS -*- linux-c -*- */
2 /*
4 * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
5 * Released under the terms of the GNU GPL v2.0.
7 */
9 #ifdef HAVE_CONFIG_H
10 # include <config.h>
11 #endif
13 #include <stdlib.h>
14 #include "lkc.h"
15 #include "images.c"
17 #include <glade/glade.h>
18 #include <gtk/gtk.h>
19 #include <glib.h>
20 #include <gdk/gdkkeysyms.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <time.h>
27 //#define DEBUG
29 int kconfig_warnings = 0;
31 enum {
32 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
35 enum {
36 OPT_NORMAL, OPT_ALL, OPT_PROMPT
39 static gint view_mode = FULL_VIEW;
40 static gboolean show_name = TRUE;
41 static gboolean show_range = TRUE;
42 static gboolean show_value = TRUE;
43 static gboolean resizeable = FALSE;
44 static int opt_mode = OPT_NORMAL;
46 GtkWidget *main_wnd = NULL;
47 GtkWidget *tree1_w = NULL; // left frame
48 GtkWidget *tree2_w = NULL; // right frame
49 GtkWidget *text_w = NULL;
50 GtkWidget *hpaned = NULL;
51 GtkWidget *vpaned = NULL;
52 GtkWidget *back_btn = NULL;
53 GtkWidget *save_btn = NULL;
54 GtkWidget *save_menu_item = NULL;
56 GtkTextTag *tag1, *tag2;
57 GdkColor color;
59 GtkTreeStore *tree1, *tree2, *tree;
60 GtkTreeModel *model1, *model2;
61 static GtkTreeIter *parents[256];
62 static gint indent;
64 static struct menu *current; // current node for SINGLE view
65 static struct menu *browsed; // browsed node for SPLIT view
67 enum {
68 COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
69 COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
70 COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
71 COL_NUMBER
74 static void display_list(void);
75 static void display_tree(struct menu *menu);
76 static void display_tree_part(void);
77 static void update_tree(struct menu *src, GtkTreeIter * dst);
78 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
79 static gchar **fill_row(struct menu *menu);
80 static void conf_changed(void);
82 /* Helping/Debugging Functions */
84 const char *dbg_sym_flags(int val)
86 static char buf[256];
88 bzero(buf, 256);
90 if (val & SYMBOL_CONST)
91 strcat(buf, "const/");
92 if (val & SYMBOL_CHECK)
93 strcat(buf, "check/");
94 if (val & SYMBOL_CHOICE)
95 strcat(buf, "choice/");
96 if (val & SYMBOL_CHOICEVAL)
97 strcat(buf, "choiceval/");
98 if (val & SYMBOL_VALID)
99 strcat(buf, "valid/");
100 if (val & SYMBOL_OPTIONAL)
101 strcat(buf, "optional/");
102 if (val & SYMBOL_WRITE)
103 strcat(buf, "write/");
104 if (val & SYMBOL_CHANGED)
105 strcat(buf, "changed/");
106 if (val & SYMBOL_AUTO)
107 strcat(buf, "auto/");
109 buf[strlen(buf) - 1] = '\0';
111 return buf;
114 void replace_button_icon(GladeXML * xml, GdkDrawable * window,
115 GtkStyle * style, gchar * btn_name, gchar ** xpm)
117 GdkPixmap *pixmap;
118 GdkBitmap *mask;
119 GtkToolButton *button;
120 GtkWidget *image;
122 pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
123 &style->bg[GTK_STATE_NORMAL],
124 xpm);
126 button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
127 image = gtk_image_new_from_pixmap(pixmap, mask);
128 gtk_widget_show(image);
129 gtk_tool_button_set_icon_widget(button, image);
132 /* Main Window Initialization */
133 void init_main_window(const gchar * glade_file)
135 GladeXML *xml;
136 GtkWidget *widget;
137 GtkTextBuffer *txtbuf;
138 GtkStyle *style;
140 xml = glade_xml_new(glade_file, "window1", NULL);
141 if (!xml)
142 g_error(_("GUI loading failed !\n"));
143 glade_xml_signal_autoconnect(xml);
145 main_wnd = glade_xml_get_widget(xml, "window1");
146 hpaned = glade_xml_get_widget(xml, "hpaned1");
147 vpaned = glade_xml_get_widget(xml, "vpaned1");
148 tree1_w = glade_xml_get_widget(xml, "treeview1");
149 tree2_w = glade_xml_get_widget(xml, "treeview2");
150 text_w = glade_xml_get_widget(xml, "textview3");
152 back_btn = glade_xml_get_widget(xml, "button1");
153 gtk_widget_set_sensitive(back_btn, FALSE);
155 widget = glade_xml_get_widget(xml, "show_name1");
156 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
157 show_name);
159 widget = glade_xml_get_widget(xml, "show_range1");
160 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
161 show_range);
163 widget = glade_xml_get_widget(xml, "show_data1");
164 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
165 show_value);
167 save_btn = glade_xml_get_widget(xml, "button3");
168 save_menu_item = glade_xml_get_widget(xml, "save1");
169 conf_set_changed_callback(conf_changed);
171 style = gtk_widget_get_style(main_wnd);
172 widget = glade_xml_get_widget(xml, "toolbar1");
174 #if 0 /* Use stock Gtk icons instead */
175 replace_button_icon(xml, main_wnd->window, style,
176 "button1", (gchar **) xpm_back);
177 replace_button_icon(xml, main_wnd->window, style,
178 "button2", (gchar **) xpm_load);
179 replace_button_icon(xml, main_wnd->window, style,
180 "button3", (gchar **) xpm_save);
181 #endif
182 replace_button_icon(xml, main_wnd->window, style,
183 "button4", (gchar **) xpm_single_view);
184 replace_button_icon(xml, main_wnd->window, style,
185 "button5", (gchar **) xpm_split_view);
186 replace_button_icon(xml, main_wnd->window, style,
187 "button6", (gchar **) xpm_tree_view);
189 #if 0
190 switch (view_mode) {
191 case SINGLE_VIEW:
192 widget = glade_xml_get_widget(xml, "button4");
193 g_signal_emit_by_name(widget, "clicked");
194 break;
195 case SPLIT_VIEW:
196 widget = glade_xml_get_widget(xml, "button5");
197 g_signal_emit_by_name(widget, "clicked");
198 break;
199 case FULL_VIEW:
200 widget = glade_xml_get_widget(xml, "button6");
201 g_signal_emit_by_name(widget, "clicked");
202 break;
204 #endif
205 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
206 tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
207 "foreground", "red",
208 "weight", PANGO_WEIGHT_BOLD,
209 NULL);
210 tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
211 /*"style", PANGO_STYLE_OBLIQUE, */
212 NULL);
214 gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
216 gtk_widget_show(main_wnd);
219 void init_tree_model(void)
221 gint i;
223 tree = tree2 = gtk_tree_store_new(COL_NUMBER,
224 G_TYPE_STRING, G_TYPE_STRING,
225 G_TYPE_STRING, G_TYPE_STRING,
226 G_TYPE_STRING, G_TYPE_STRING,
227 G_TYPE_POINTER, GDK_TYPE_COLOR,
228 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
229 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
230 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
231 G_TYPE_BOOLEAN);
232 model2 = GTK_TREE_MODEL(tree2);
234 for (parents[0] = NULL, i = 1; i < 256; i++)
235 parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
237 tree1 = gtk_tree_store_new(COL_NUMBER,
238 G_TYPE_STRING, G_TYPE_STRING,
239 G_TYPE_STRING, G_TYPE_STRING,
240 G_TYPE_STRING, G_TYPE_STRING,
241 G_TYPE_POINTER, GDK_TYPE_COLOR,
242 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
243 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
244 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
245 G_TYPE_BOOLEAN);
246 model1 = GTK_TREE_MODEL(tree1);
249 void init_left_tree(void)
251 GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
252 GtkCellRenderer *renderer;
253 GtkTreeSelection *sel;
254 GtkTreeViewColumn *column;
256 gtk_tree_view_set_model(view, model1);
257 gtk_tree_view_set_headers_visible(view, TRUE);
258 gtk_tree_view_set_rules_hint(view, TRUE);
260 column = gtk_tree_view_column_new();
261 gtk_tree_view_append_column(view, column);
262 gtk_tree_view_column_set_title(column, _("Options"));
264 renderer = gtk_cell_renderer_toggle_new();
265 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
266 renderer, FALSE);
267 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
268 renderer,
269 "active", COL_BTNACT,
270 "inconsistent", COL_BTNINC,
271 "visible", COL_BTNVIS,
272 "radio", COL_BTNRAD, NULL);
273 renderer = gtk_cell_renderer_text_new();
274 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
275 renderer, FALSE);
276 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
277 renderer,
278 "text", COL_OPTION,
279 "foreground-gdk",
280 COL_COLOR, NULL);
282 sel = gtk_tree_view_get_selection(view);
283 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
284 gtk_widget_realize(tree1_w);
287 static void renderer_edited(GtkCellRendererText * cell,
288 const gchar * path_string,
289 const gchar * new_text, gpointer user_data);
291 void init_right_tree(void)
293 GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
294 GtkCellRenderer *renderer;
295 GtkTreeSelection *sel;
296 GtkTreeViewColumn *column;
297 gint i;
299 gtk_tree_view_set_model(view, model2);
300 gtk_tree_view_set_headers_visible(view, TRUE);
301 gtk_tree_view_set_rules_hint(view, TRUE);
303 column = gtk_tree_view_column_new();
304 gtk_tree_view_append_column(view, column);
305 gtk_tree_view_column_set_title(column, _("Options"));
307 renderer = gtk_cell_renderer_pixbuf_new();
308 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
309 renderer, FALSE);
310 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
311 renderer,
312 "pixbuf", COL_PIXBUF,
313 "visible", COL_PIXVIS, NULL);
314 renderer = gtk_cell_renderer_toggle_new();
315 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
316 renderer, FALSE);
317 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
318 renderer,
319 "active", COL_BTNACT,
320 "inconsistent", COL_BTNINC,
321 "visible", COL_BTNVIS,
322 "radio", COL_BTNRAD, NULL);
323 renderer = gtk_cell_renderer_text_new();
324 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
325 renderer, FALSE);
326 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
327 renderer,
328 "text", COL_OPTION,
329 "foreground-gdk",
330 COL_COLOR, NULL);
332 renderer = gtk_cell_renderer_text_new();
333 gtk_tree_view_insert_column_with_attributes(view, -1,
334 _("Name"), renderer,
335 "text", COL_NAME,
336 "foreground-gdk",
337 COL_COLOR, NULL);
338 renderer = gtk_cell_renderer_text_new();
339 gtk_tree_view_insert_column_with_attributes(view, -1,
340 "N", renderer,
341 "text", COL_NO,
342 "foreground-gdk",
343 COL_COLOR, NULL);
344 renderer = gtk_cell_renderer_text_new();
345 gtk_tree_view_insert_column_with_attributes(view, -1,
346 "M", renderer,
347 "text", COL_MOD,
348 "foreground-gdk",
349 COL_COLOR, NULL);
350 renderer = gtk_cell_renderer_text_new();
351 gtk_tree_view_insert_column_with_attributes(view, -1,
352 "Y", renderer,
353 "text", COL_YES,
354 "foreground-gdk",
355 COL_COLOR, NULL);
356 renderer = gtk_cell_renderer_text_new();
357 gtk_tree_view_insert_column_with_attributes(view, -1,
358 _("Value"), renderer,
359 "text", COL_VALUE,
360 "editable",
361 COL_EDIT,
362 "foreground-gdk",
363 COL_COLOR, NULL);
364 g_signal_connect(G_OBJECT(renderer), "edited",
365 G_CALLBACK(renderer_edited), NULL);
367 column = gtk_tree_view_get_column(view, COL_NAME);
368 gtk_tree_view_column_set_visible(column, show_name);
369 column = gtk_tree_view_get_column(view, COL_NO);
370 gtk_tree_view_column_set_visible(column, show_range);
371 column = gtk_tree_view_get_column(view, COL_MOD);
372 gtk_tree_view_column_set_visible(column, show_range);
373 column = gtk_tree_view_get_column(view, COL_YES);
374 gtk_tree_view_column_set_visible(column, show_range);
375 column = gtk_tree_view_get_column(view, COL_VALUE);
376 gtk_tree_view_column_set_visible(column, show_value);
378 if (resizeable) {
379 for (i = 0; i < COL_VALUE; i++) {
380 column = gtk_tree_view_get_column(view, i);
381 gtk_tree_view_column_set_resizable(column, TRUE);
385 sel = gtk_tree_view_get_selection(view);
386 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
390 /* Utility Functions */
393 static void text_insert_help(struct menu *menu)
395 GtkTextBuffer *buffer;
396 GtkTextIter start, end;
397 const char *prompt = _(menu_get_prompt(menu));
398 struct gstr help = str_new();
400 menu_get_ext_help(menu, &help);
402 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
403 gtk_text_buffer_get_bounds(buffer, &start, &end);
404 gtk_text_buffer_delete(buffer, &start, &end);
405 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
407 gtk_text_buffer_get_end_iter(buffer, &end);
408 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
409 NULL);
410 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
411 gtk_text_buffer_get_end_iter(buffer, &end);
412 gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
413 NULL);
414 str_free(&help);
418 static void text_insert_msg(const char *title, const char *message)
420 GtkTextBuffer *buffer;
421 GtkTextIter start, end;
422 const char *msg = message;
424 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
425 gtk_text_buffer_get_bounds(buffer, &start, &end);
426 gtk_text_buffer_delete(buffer, &start, &end);
427 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
429 gtk_text_buffer_get_end_iter(buffer, &end);
430 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
431 NULL);
432 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
433 gtk_text_buffer_get_end_iter(buffer, &end);
434 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
435 NULL);
439 /* Main Windows Callbacks */
441 void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
442 gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
443 gpointer user_data)
445 GtkWidget *dialog, *label;
446 gint result;
448 if (!conf_get_changed())
449 return FALSE;
451 dialog = gtk_dialog_new_with_buttons(_("Warning !"),
452 GTK_WINDOW(main_wnd),
453 (GtkDialogFlags)
454 (GTK_DIALOG_MODAL |
455 GTK_DIALOG_DESTROY_WITH_PARENT),
456 GTK_STOCK_OK,
457 GTK_RESPONSE_YES,
458 GTK_STOCK_NO,
459 GTK_RESPONSE_NO,
460 GTK_STOCK_CANCEL,
461 GTK_RESPONSE_CANCEL, NULL);
462 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
463 GTK_RESPONSE_CANCEL);
465 label = gtk_label_new(_("\nSave configuration ?\n"));
466 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
467 gtk_widget_show(label);
469 result = gtk_dialog_run(GTK_DIALOG(dialog));
470 switch (result) {
471 case GTK_RESPONSE_YES:
472 on_save_activate(NULL, NULL);
473 return FALSE;
474 case GTK_RESPONSE_NO:
475 return FALSE;
476 case GTK_RESPONSE_CANCEL:
477 case GTK_RESPONSE_DELETE_EVENT:
478 default:
479 gtk_widget_destroy(dialog);
480 return TRUE;
483 return FALSE;
487 void on_window1_destroy(GtkObject * object, gpointer user_data)
489 gtk_main_quit();
493 void
494 on_window1_size_request(GtkWidget * widget,
495 GtkRequisition * requisition, gpointer user_data)
497 static gint old_h;
498 gint w, h;
500 if (widget->window == NULL)
501 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
502 else
503 gdk_window_get_size(widget->window, &w, &h);
505 if (h == old_h)
506 return;
507 old_h = h;
509 gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
513 /* Menu & Toolbar Callbacks */
516 static void
517 load_filename(GtkFileSelection * file_selector, gpointer user_data)
519 const gchar *fn;
521 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
522 (user_data));
524 if (conf_read(fn))
525 text_insert_msg(_("Error"), _("Unable to load configuration !"));
526 else
527 display_tree(&rootmenu);
530 void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
532 GtkWidget *fs;
534 fs = gtk_file_selection_new(_("Load file..."));
535 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
536 "clicked",
537 G_CALLBACK(load_filename), (gpointer) fs);
538 g_signal_connect_swapped(GTK_OBJECT
539 (GTK_FILE_SELECTION(fs)->ok_button),
540 "clicked", G_CALLBACK(gtk_widget_destroy),
541 (gpointer) fs);
542 g_signal_connect_swapped(GTK_OBJECT
543 (GTK_FILE_SELECTION(fs)->cancel_button),
544 "clicked", G_CALLBACK(gtk_widget_destroy),
545 (gpointer) fs);
546 gtk_widget_show(fs);
550 void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
552 if (conf_write(NULL))
553 text_insert_msg(_("Error"), _("Unable to save configuration !"));
557 static void
558 store_filename(GtkFileSelection * file_selector, gpointer user_data)
560 const gchar *fn;
562 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
563 (user_data));
565 if (conf_write(fn))
566 text_insert_msg(_("Error"), _("Unable to save configuration !"));
568 gtk_widget_destroy(GTK_WIDGET(user_data));
571 void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
573 GtkWidget *fs;
575 fs = gtk_file_selection_new(_("Save file as..."));
576 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
577 "clicked",
578 G_CALLBACK(store_filename), (gpointer) fs);
579 g_signal_connect_swapped(GTK_OBJECT
580 (GTK_FILE_SELECTION(fs)->ok_button),
581 "clicked", G_CALLBACK(gtk_widget_destroy),
582 (gpointer) fs);
583 g_signal_connect_swapped(GTK_OBJECT
584 (GTK_FILE_SELECTION(fs)->cancel_button),
585 "clicked", G_CALLBACK(gtk_widget_destroy),
586 (gpointer) fs);
587 gtk_widget_show(fs);
591 void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
593 if (!on_window1_delete_event(NULL, NULL, NULL))
594 gtk_widget_destroy(GTK_WIDGET(main_wnd));
598 void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
600 GtkTreeViewColumn *col;
602 show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
603 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
604 if (col)
605 gtk_tree_view_column_set_visible(col, show_name);
609 void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
611 GtkTreeViewColumn *col;
613 show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
614 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
615 if (col)
616 gtk_tree_view_column_set_visible(col, show_range);
617 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
618 if (col)
619 gtk_tree_view_column_set_visible(col, show_range);
620 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
621 if (col)
622 gtk_tree_view_column_set_visible(col, show_range);
627 void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
629 GtkTreeViewColumn *col;
631 show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
632 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
633 if (col)
634 gtk_tree_view_column_set_visible(col, show_value);
638 void
639 on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
641 opt_mode = OPT_NORMAL;
642 gtk_tree_store_clear(tree2);
643 display_tree(&rootmenu); /* instead of update_tree to speed-up */
647 void
648 on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
650 opt_mode = OPT_ALL;
651 gtk_tree_store_clear(tree2);
652 display_tree(&rootmenu); /* instead of update_tree to speed-up */
656 void
657 on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
659 opt_mode = OPT_PROMPT;
660 gtk_tree_store_clear(tree2);
661 display_tree(&rootmenu); /* instead of update_tree to speed-up */
665 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
667 GtkWidget *dialog;
668 const gchar *intro_text = _(
669 "Welcome to gkc, the GTK+ graphical configuration tool\n"
670 "For each option, a blank box indicates the feature is disabled, a\n"
671 "check indicates it is enabled, and a dot indicates that it is to\n"
672 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
673 "\n"
674 "If you do not see an option (e.g., a device driver) that you\n"
675 "believe should be present, try turning on Show All Options\n"
676 "under the Options menu.\n"
677 "Although there is no cross reference yet to help you figure out\n"
678 "what other options must be enabled to support the option you\n"
679 "are interested in, you can still view the help of a grayed-out\n"
680 "option.\n"
681 "\n"
682 "Toggling Show Debug Info under the Options menu will show \n"
683 "the dependencies, which you can then match by examining other options.");
685 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
686 GTK_DIALOG_DESTROY_WITH_PARENT,
687 GTK_MESSAGE_INFO,
688 GTK_BUTTONS_CLOSE, "%s", intro_text);
689 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
690 G_CALLBACK(gtk_widget_destroy),
691 GTK_OBJECT(dialog));
692 gtk_widget_show_all(dialog);
696 void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
698 GtkWidget *dialog;
699 const gchar *about_text =
700 _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
701 "Based on the source code from Roman Zippel.\n");
703 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
704 GTK_DIALOG_DESTROY_WITH_PARENT,
705 GTK_MESSAGE_INFO,
706 GTK_BUTTONS_CLOSE, "%s", about_text);
707 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
708 G_CALLBACK(gtk_widget_destroy),
709 GTK_OBJECT(dialog));
710 gtk_widget_show_all(dialog);
714 void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
716 GtkWidget *dialog;
717 const gchar *license_text =
718 _("gkc is released under the terms of the GNU GPL v2.\n"
719 "For more information, please see the source code or\n"
720 "visit http://www.fsf.org/licenses/licenses.html\n");
722 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
723 GTK_DIALOG_DESTROY_WITH_PARENT,
724 GTK_MESSAGE_INFO,
725 GTK_BUTTONS_CLOSE, "%s", license_text);
726 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
727 G_CALLBACK(gtk_widget_destroy),
728 GTK_OBJECT(dialog));
729 gtk_widget_show_all(dialog);
733 void on_back_clicked(GtkButton * button, gpointer user_data)
735 enum prop_type ptype;
737 current = current->parent;
738 ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
739 if (ptype != P_MENU)
740 current = current->parent;
741 display_tree_part();
743 if (current == &rootmenu)
744 gtk_widget_set_sensitive(back_btn, FALSE);
748 void on_load_clicked(GtkButton * button, gpointer user_data)
750 on_load1_activate(NULL, user_data);
754 void on_single_clicked(GtkButton * button, gpointer user_data)
756 view_mode = SINGLE_VIEW;
757 gtk_widget_hide(tree1_w);
758 current = &rootmenu;
759 display_tree_part();
763 void on_split_clicked(GtkButton * button, gpointer user_data)
765 gint w, h;
766 view_mode = SPLIT_VIEW;
767 gtk_widget_show(tree1_w);
768 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
769 gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
770 if (tree2)
771 gtk_tree_store_clear(tree2);
772 display_list();
774 /* Disable back btn, like in full mode. */
775 gtk_widget_set_sensitive(back_btn, FALSE);
779 void on_full_clicked(GtkButton * button, gpointer user_data)
781 view_mode = FULL_VIEW;
782 gtk_widget_hide(tree1_w);
783 if (tree2)
784 gtk_tree_store_clear(tree2);
785 display_tree(&rootmenu);
786 gtk_widget_set_sensitive(back_btn, FALSE);
790 void on_collapse_clicked(GtkButton * button, gpointer user_data)
792 gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
796 void on_expand_clicked(GtkButton * button, gpointer user_data)
798 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
802 /* CTree Callbacks */
804 /* Change hex/int/string value in the cell */
805 static void renderer_edited(GtkCellRendererText * cell,
806 const gchar * path_string,
807 const gchar * new_text, gpointer user_data)
809 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
810 GtkTreeIter iter;
811 const char *old_def, *new_def;
812 struct menu *menu;
813 struct symbol *sym;
815 if (!gtk_tree_model_get_iter(model2, &iter, path))
816 return;
818 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
819 sym = menu->sym;
821 gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
822 new_def = new_text;
824 sym_set_string_value(sym, new_def);
826 update_tree(&rootmenu, NULL);
828 gtk_tree_path_free(path);
831 /* Change the value of a symbol and update the tree */
832 static void change_sym_value(struct menu *menu, gint col)
834 struct symbol *sym = menu->sym;
835 tristate newval;
837 if (!sym)
838 return;
840 if (col == COL_NO)
841 newval = no;
842 else if (col == COL_MOD)
843 newval = mod;
844 else if (col == COL_YES)
845 newval = yes;
846 else
847 return;
849 switch (sym_get_type(sym)) {
850 case S_BOOLEAN:
851 case S_TRISTATE:
852 if (!sym_tristate_within_range(sym, newval))
853 newval = yes;
854 sym_set_tristate_value(sym, newval);
855 if (view_mode == FULL_VIEW)
856 update_tree(&rootmenu, NULL);
857 else if (view_mode == SPLIT_VIEW) {
858 update_tree(browsed, NULL);
859 display_list();
861 else if (view_mode == SINGLE_VIEW)
862 display_tree_part(); //fixme: keep exp/coll
863 break;
864 case S_INT:
865 case S_HEX:
866 case S_STRING:
867 default:
868 break;
872 static void toggle_sym_value(struct menu *menu)
874 if (!menu->sym)
875 return;
877 sym_toggle_tristate_value(menu->sym);
878 if (view_mode == FULL_VIEW)
879 update_tree(&rootmenu, NULL);
880 else if (view_mode == SPLIT_VIEW) {
881 update_tree(browsed, NULL);
882 display_list();
884 else if (view_mode == SINGLE_VIEW)
885 display_tree_part(); //fixme: keep exp/coll
888 static gint column2index(GtkTreeViewColumn * column)
890 gint i;
892 for (i = 0; i < COL_NUMBER; i++) {
893 GtkTreeViewColumn *col;
895 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
896 if (col == column)
897 return i;
900 return -1;
904 /* User click: update choice (full) or goes down (single) */
905 gboolean
906 on_treeview2_button_press_event(GtkWidget * widget,
907 GdkEventButton * event, gpointer user_data)
909 GtkTreeView *view = GTK_TREE_VIEW(widget);
910 GtkTreePath *path;
911 GtkTreeViewColumn *column;
912 GtkTreeIter iter;
913 struct menu *menu;
914 gint col;
916 #if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
917 gint tx = (gint) event->x;
918 gint ty = (gint) event->y;
919 gint cx, cy;
921 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
922 &cy);
923 #else
924 gtk_tree_view_get_cursor(view, &path, &column);
925 #endif
926 if (path == NULL)
927 return FALSE;
929 if (!gtk_tree_model_get_iter(model2, &iter, path))
930 return FALSE;
931 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
933 col = column2index(column);
934 if (event->type == GDK_2BUTTON_PRESS) {
935 enum prop_type ptype;
936 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
938 if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
939 // goes down into menu
940 current = menu;
941 display_tree_part();
942 gtk_widget_set_sensitive(back_btn, TRUE);
943 } else if ((col == COL_OPTION)) {
944 toggle_sym_value(menu);
945 gtk_tree_view_expand_row(view, path, TRUE);
947 } else {
948 if (col == COL_VALUE) {
949 toggle_sym_value(menu);
950 gtk_tree_view_expand_row(view, path, TRUE);
951 } else if (col == COL_NO || col == COL_MOD
952 || col == COL_YES) {
953 change_sym_value(menu, col);
954 gtk_tree_view_expand_row(view, path, TRUE);
958 return FALSE;
961 /* Key pressed: update choice */
962 gboolean
963 on_treeview2_key_press_event(GtkWidget * widget,
964 GdkEventKey * event, gpointer user_data)
966 GtkTreeView *view = GTK_TREE_VIEW(widget);
967 GtkTreePath *path;
968 GtkTreeViewColumn *column;
969 GtkTreeIter iter;
970 struct menu *menu;
971 gint col;
973 gtk_tree_view_get_cursor(view, &path, &column);
974 if (path == NULL)
975 return FALSE;
977 if (event->keyval == GDK_space) {
978 if (gtk_tree_view_row_expanded(view, path))
979 gtk_tree_view_collapse_row(view, path);
980 else
981 gtk_tree_view_expand_row(view, path, FALSE);
982 return TRUE;
984 if (event->keyval == GDK_KP_Enter) {
986 if (widget == tree1_w)
987 return FALSE;
989 gtk_tree_model_get_iter(model2, &iter, path);
990 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
992 if (!strcasecmp(event->string, "n"))
993 col = COL_NO;
994 else if (!strcasecmp(event->string, "m"))
995 col = COL_MOD;
996 else if (!strcasecmp(event->string, "y"))
997 col = COL_YES;
998 else
999 col = -1;
1000 change_sym_value(menu, col);
1002 return FALSE;
1006 /* Row selection changed: update help */
1007 void
1008 on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1010 GtkTreeSelection *selection;
1011 GtkTreeIter iter;
1012 struct menu *menu;
1014 selection = gtk_tree_view_get_selection(treeview);
1015 if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1016 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1017 text_insert_help(menu);
1022 /* User click: display sub-tree in the right frame. */
1023 gboolean
1024 on_treeview1_button_press_event(GtkWidget * widget,
1025 GdkEventButton * event, gpointer user_data)
1027 GtkTreeView *view = GTK_TREE_VIEW(widget);
1028 GtkTreePath *path;
1029 GtkTreeViewColumn *column;
1030 GtkTreeIter iter;
1031 struct menu *menu;
1033 gint tx = (gint) event->x;
1034 gint ty = (gint) event->y;
1035 gint cx, cy;
1037 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1038 &cy);
1039 if (path == NULL)
1040 return FALSE;
1042 gtk_tree_model_get_iter(model1, &iter, path);
1043 gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1045 if (event->type == GDK_2BUTTON_PRESS) {
1046 toggle_sym_value(menu);
1047 current = menu;
1048 display_tree_part();
1049 } else {
1050 browsed = menu;
1051 display_tree_part();
1054 gtk_widget_realize(tree2_w);
1055 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1056 gtk_widget_grab_focus(tree2_w);
1058 return FALSE;
1062 /* Fill a row of strings */
1063 static gchar **fill_row(struct menu *menu)
1065 static gchar *row[COL_NUMBER];
1066 struct symbol *sym = menu->sym;
1067 const char *def;
1068 int stype;
1069 tristate val;
1070 enum prop_type ptype;
1071 int i;
1073 for (i = COL_OPTION; i <= COL_COLOR; i++)
1074 g_free(row[i]);
1075 bzero(row, sizeof(row));
1077 row[COL_OPTION] =
1078 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1079 sym && !sym_has_value(sym) ? "(NEW)" : "");
1081 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1082 row[COL_COLOR] = g_strdup("DarkGray");
1083 else if (opt_mode == OPT_PROMPT &&
1084 menu_has_prompt(menu) && !menu_is_visible(menu))
1085 row[COL_COLOR] = g_strdup("DarkGray");
1086 else
1087 row[COL_COLOR] = g_strdup("Black");
1089 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1090 switch (ptype) {
1091 case P_MENU:
1092 row[COL_PIXBUF] = (gchar *) xpm_menu;
1093 if (view_mode == SINGLE_VIEW)
1094 row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1095 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1096 break;
1097 case P_COMMENT:
1098 row[COL_PIXBUF] = (gchar *) xpm_void;
1099 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1100 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1101 break;
1102 default:
1103 row[COL_PIXBUF] = (gchar *) xpm_void;
1104 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1105 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1106 break;
1109 if (!sym)
1110 return row;
1111 row[COL_NAME] = g_strdup(sym->name);
1113 sym_calc_value(sym);
1114 sym->flags &= ~SYMBOL_CHANGED;
1116 if (sym_is_choice(sym)) { // parse childs for getting final value
1117 struct menu *child;
1118 struct symbol *def_sym = sym_get_choice_value(sym);
1119 struct menu *def_menu = NULL;
1121 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1123 for (child = menu->list; child; child = child->next) {
1124 if (menu_is_visible(child)
1125 && child->sym == def_sym)
1126 def_menu = child;
1129 if (def_menu)
1130 row[COL_VALUE] =
1131 g_strdup(_(menu_get_prompt(def_menu)));
1133 if (sym->flags & SYMBOL_CHOICEVAL)
1134 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1136 stype = sym_get_type(sym);
1137 switch (stype) {
1138 case S_BOOLEAN:
1139 if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
1140 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1141 if (sym_is_choice(sym))
1142 break;
1143 /* fall through */
1144 case S_TRISTATE:
1145 val = sym_get_tristate_value(sym);
1146 switch (val) {
1147 case no:
1148 row[COL_NO] = g_strdup("N");
1149 row[COL_VALUE] = g_strdup("N");
1150 row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1151 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1152 break;
1153 case mod:
1154 row[COL_MOD] = g_strdup("M");
1155 row[COL_VALUE] = g_strdup("M");
1156 row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1157 break;
1158 case yes:
1159 row[COL_YES] = g_strdup("Y");
1160 row[COL_VALUE] = g_strdup("Y");
1161 row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1162 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1163 break;
1166 if (val != no && sym_tristate_within_range(sym, no))
1167 row[COL_NO] = g_strdup("_");
1168 if (val != mod && sym_tristate_within_range(sym, mod))
1169 row[COL_MOD] = g_strdup("_");
1170 if (val != yes && sym_tristate_within_range(sym, yes))
1171 row[COL_YES] = g_strdup("_");
1172 break;
1173 case S_INT:
1174 case S_HEX:
1175 case S_STRING:
1176 def = sym_get_string_value(sym);
1177 row[COL_VALUE] = g_strdup(def);
1178 row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1179 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1180 break;
1183 return row;
1187 /* Set the node content with a row of strings */
1188 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1190 GdkColor color;
1191 gboolean success;
1192 GdkPixbuf *pix;
1194 pix = gdk_pixbuf_new_from_xpm_data((const char **)
1195 row[COL_PIXBUF]);
1197 gdk_color_parse(row[COL_COLOR], &color);
1198 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1199 FALSE, FALSE, &success);
1201 gtk_tree_store_set(tree, node,
1202 COL_OPTION, row[COL_OPTION],
1203 COL_NAME, row[COL_NAME],
1204 COL_NO, row[COL_NO],
1205 COL_MOD, row[COL_MOD],
1206 COL_YES, row[COL_YES],
1207 COL_VALUE, row[COL_VALUE],
1208 COL_MENU, (gpointer) menu,
1209 COL_COLOR, &color,
1210 COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1211 COL_PIXBUF, pix,
1212 COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1213 COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1214 COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1215 COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1216 COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1217 -1);
1219 g_object_unref(pix);
1223 /* Add a node to the tree */
1224 static void place_node(struct menu *menu, char **row)
1226 GtkTreeIter *parent = parents[indent - 1];
1227 GtkTreeIter *node = parents[indent];
1229 gtk_tree_store_append(tree, node, parent);
1230 set_node(node, menu, row);
1234 /* Find a node in the GTK+ tree */
1235 static GtkTreeIter found;
1238 * Find a menu in the GtkTree starting at parent.
1240 GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1241 struct menu *tofind)
1243 GtkTreeIter iter;
1244 GtkTreeIter *child = &iter;
1245 gboolean valid;
1246 GtkTreeIter *ret;
1248 valid = gtk_tree_model_iter_children(model2, child, parent);
1249 while (valid) {
1250 struct menu *menu;
1252 gtk_tree_model_get(model2, child, 6, &menu, -1);
1254 if (menu == tofind) {
1255 memcpy(&found, child, sizeof(GtkTreeIter));
1256 return &found;
1259 ret = gtktree_iter_find_node(child, tofind);
1260 if (ret)
1261 return ret;
1263 valid = gtk_tree_model_iter_next(model2, child);
1266 return NULL;
1271 * Update the tree by adding/removing entries
1272 * Does not change other nodes
1274 static void update_tree(struct menu *src, GtkTreeIter * dst)
1276 struct menu *child1;
1277 GtkTreeIter iter, tmp;
1278 GtkTreeIter *child2 = &iter;
1279 gboolean valid;
1280 GtkTreeIter *sibling;
1281 struct symbol *sym;
1282 struct menu *menu1, *menu2;
1284 if (src == &rootmenu)
1285 indent = 1;
1287 valid = gtk_tree_model_iter_children(model2, child2, dst);
1288 for (child1 = src->list; child1; child1 = child1->next) {
1290 sym = child1->sym;
1292 reparse:
1293 menu1 = child1;
1294 if (valid)
1295 gtk_tree_model_get(model2, child2, COL_MENU,
1296 &menu2, -1);
1297 else
1298 menu2 = NULL; // force adding of a first child
1300 #ifdef DEBUG
1301 printf("%*c%s | %s\n", indent, ' ',
1302 menu1 ? menu_get_prompt(menu1) : "nil",
1303 menu2 ? menu_get_prompt(menu2) : "nil");
1304 #endif
1306 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1307 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1308 (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
1310 /* remove node */
1311 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1312 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1313 valid = gtk_tree_model_iter_next(model2,
1314 child2);
1315 gtk_tree_store_remove(tree2, &tmp);
1316 if (!valid)
1317 return; /* next parent */
1318 else
1319 goto reparse; /* next child */
1320 } else
1321 continue;
1324 if (menu1 != menu2) {
1325 if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
1326 if (!valid && !menu2)
1327 sibling = NULL;
1328 else
1329 sibling = child2;
1330 gtk_tree_store_insert_before(tree2,
1331 child2,
1332 dst, sibling);
1333 set_node(child2, menu1, fill_row(menu1));
1334 if (menu2 == NULL)
1335 valid = TRUE;
1336 } else { // remove node
1337 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1338 valid = gtk_tree_model_iter_next(model2,
1339 child2);
1340 gtk_tree_store_remove(tree2, &tmp);
1341 if (!valid)
1342 return; // next parent
1343 else
1344 goto reparse; // next child
1346 } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1347 set_node(child2, menu1, fill_row(menu1));
1350 indent++;
1351 update_tree(child1, child2);
1352 indent--;
1354 valid = gtk_tree_model_iter_next(model2, child2);
1359 /* Display the whole tree (single/split/full view) */
1360 static void display_tree(struct menu *menu)
1362 struct symbol *sym;
1363 struct property *prop;
1364 struct menu *child;
1365 enum prop_type ptype;
1367 if (menu == &rootmenu) {
1368 indent = 1;
1369 current = &rootmenu;
1372 for (child = menu->list; child; child = child->next) {
1373 prop = child->prompt;
1374 sym = child->sym;
1375 ptype = prop ? prop->type : P_UNKNOWN;
1377 if (sym)
1378 sym->flags &= ~SYMBOL_CHANGED;
1380 if ((view_mode == SPLIT_VIEW)
1381 && !(child->flags & MENU_ROOT) && (tree == tree1))
1382 continue;
1384 if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT)
1385 && (tree == tree2))
1386 continue;
1388 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1389 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1390 (opt_mode == OPT_ALL && menu_get_prompt(child)))
1391 place_node(child, fill_row(child));
1392 #ifdef DEBUG
1393 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1394 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1395 printf("%s", prop_get_type_name(ptype));
1396 printf(" | ");
1397 if (sym) {
1398 printf("%s", sym_type_name(sym->type));
1399 printf(" | ");
1400 printf("%s", dbg_sym_flags(sym->flags));
1401 printf("\n");
1402 } else
1403 printf("\n");
1404 #endif
1405 if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1406 && (tree == tree2))
1407 continue;
1409 if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
1410 || (view_mode == FULL_VIEW)
1411 || (view_mode == SPLIT_VIEW))*/
1413 /* Change paned position if the view is not in 'split mode' */
1414 if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) {
1415 gtk_paned_set_position(GTK_PANED(hpaned), 0);
1418 if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
1419 || (view_mode == FULL_VIEW)
1420 || (view_mode == SPLIT_VIEW)) {
1421 indent++;
1422 display_tree(child);
1423 indent--;
1428 /* Display a part of the tree starting at current node (single/split view) */
1429 static void display_tree_part(void)
1431 if (tree2)
1432 gtk_tree_store_clear(tree2);
1433 if (view_mode == SINGLE_VIEW)
1434 display_tree(current);
1435 else if (view_mode == SPLIT_VIEW)
1436 display_tree(browsed);
1437 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1440 /* Display the list in the left frame (split view) */
1441 static void display_list(void)
1443 if (tree1)
1444 gtk_tree_store_clear(tree1);
1446 tree = tree1;
1447 display_tree(&rootmenu);
1448 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1449 tree = tree2;
1452 void fixup_rootmenu(struct menu *menu)
1454 struct menu *child;
1455 static int menu_cnt = 0;
1457 menu->flags |= MENU_ROOT;
1458 for (child = menu->list; child; child = child->next) {
1459 if (child->prompt && child->prompt->type == P_MENU) {
1460 menu_cnt++;
1461 fixup_rootmenu(child);
1462 menu_cnt--;
1463 } else if (!menu_cnt)
1464 fixup_rootmenu(child);
1469 /* Main */
1470 int main(int ac, char *av[])
1472 const char *name;
1473 char *env;
1474 gchar *glade_file;
1476 bindtextdomain(PACKAGE, LOCALEDIR);
1477 bind_textdomain_codeset(PACKAGE, "UTF-8");
1478 textdomain(PACKAGE);
1480 /* GTK stuffs */
1481 gtk_set_locale();
1482 gtk_init(&ac, &av);
1483 glade_init();
1485 //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1486 //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1488 /* Determine GUI path */
1489 env = getenv(SRCTREE);
1490 if (env)
1491 glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
1492 else if (av[0][0] == '/')
1493 glade_file = g_strconcat(av[0], ".glade", NULL);
1494 else
1495 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1497 /* Conf stuffs */
1498 if (ac > 1 && av[1][0] == '-') {
1499 switch (av[1][1]) {
1500 case 'a':
1501 //showAll = 1;
1502 break;
1503 case 'h':
1504 case '?':
1505 printf("%s <config>\n", av[0]);
1506 exit(0);
1508 name = av[2];
1509 } else
1510 name = av[1];
1512 conf_parse(name);
1513 fixup_rootmenu(&rootmenu);
1514 conf_read(NULL);
1516 /* Load the interface and connect signals */
1517 init_main_window(glade_file);
1518 init_tree_model();
1519 init_left_tree();
1520 init_right_tree();
1522 switch (view_mode) {
1523 case SINGLE_VIEW:
1524 display_tree_part();
1525 break;
1526 case SPLIT_VIEW:
1527 display_list();
1528 break;
1529 case FULL_VIEW:
1530 display_tree(&rootmenu);
1531 break;
1534 gtk_main();
1536 return 0;
1539 static void conf_changed(void)
1541 bool changed = conf_get_changed();
1542 gtk_widget_set_sensitive(save_btn, changed);
1543 gtk_widget_set_sensitive(save_menu_item, changed);