GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / scripts / kconfig / gconf.c
blob81ce2f8c486de03e4df3f9c805db2348f211eae2
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 "lkc.h"
14 #include "images.c"
16 #include <glade/glade.h>
17 #include <gtk/gtk.h>
18 #include <glib.h>
19 #include <gdk/gdkkeysyms.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <time.h>
25 #include <stdlib.h>
27 //#define DEBUG
29 enum {
30 SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
33 enum {
34 OPT_NORMAL, OPT_ALL, OPT_PROMPT
37 static gint view_mode = FULL_VIEW;
38 static gboolean show_name = TRUE;
39 static gboolean show_range = TRUE;
40 static gboolean show_value = TRUE;
41 static gboolean resizeable = FALSE;
42 static int opt_mode = OPT_NORMAL;
44 GtkWidget *main_wnd = NULL;
45 GtkWidget *tree1_w = NULL; // left frame
46 GtkWidget *tree2_w = NULL; // right frame
47 GtkWidget *text_w = NULL;
48 GtkWidget *hpaned = NULL;
49 GtkWidget *vpaned = NULL;
50 GtkWidget *back_btn = NULL;
51 GtkWidget *save_btn = NULL;
52 GtkWidget *save_menu_item = NULL;
54 GtkTextTag *tag1, *tag2;
55 GdkColor color;
57 GtkTreeStore *tree1, *tree2, *tree;
58 GtkTreeModel *model1, *model2;
59 static GtkTreeIter *parents[256];
60 static gint indent;
62 static struct menu *current; // current node for SINGLE view
63 static struct menu *browsed; // browsed node for SPLIT view
65 enum {
66 COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
67 COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
68 COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
69 COL_NUMBER
72 static void display_list(void);
73 static void display_tree(struct menu *menu);
74 static void display_tree_part(void);
75 static void update_tree(struct menu *src, GtkTreeIter * dst);
76 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
77 static gchar **fill_row(struct menu *menu);
78 static void conf_changed(void);
80 /* Helping/Debugging Functions */
82 const char *dbg_sym_flags(int val)
84 static char buf[256];
86 bzero(buf, 256);
88 if (val & SYMBOL_CONST)
89 strcat(buf, "const/");
90 if (val & SYMBOL_CHECK)
91 strcat(buf, "check/");
92 if (val & SYMBOL_CHOICE)
93 strcat(buf, "choice/");
94 if (val & SYMBOL_CHOICEVAL)
95 strcat(buf, "choiceval/");
96 if (val & SYMBOL_VALID)
97 strcat(buf, "valid/");
98 if (val & SYMBOL_OPTIONAL)
99 strcat(buf, "optional/");
100 if (val & SYMBOL_WRITE)
101 strcat(buf, "write/");
102 if (val & SYMBOL_CHANGED)
103 strcat(buf, "changed/");
104 if (val & SYMBOL_AUTO)
105 strcat(buf, "auto/");
107 buf[strlen(buf) - 1] = '\0';
109 return buf;
112 void replace_button_icon(GladeXML * xml, GdkDrawable * window,
113 GtkStyle * style, gchar * btn_name, gchar ** xpm)
115 GdkPixmap *pixmap;
116 GdkBitmap *mask;
117 GtkToolButton *button;
118 GtkWidget *image;
120 pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
121 &style->bg[GTK_STATE_NORMAL],
122 xpm);
124 button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
125 image = gtk_image_new_from_pixmap(pixmap, mask);
126 gtk_widget_show(image);
127 gtk_tool_button_set_icon_widget(button, image);
130 /* Main Window Initialization */
131 void init_main_window(const gchar * glade_file)
133 GladeXML *xml;
134 GtkWidget *widget;
135 GtkTextBuffer *txtbuf;
136 char title[256];
137 GtkStyle *style;
139 xml = glade_xml_new(glade_file, "window1", NULL);
140 if (!xml)
141 g_error(_("GUI loading failed !\n"));
142 glade_xml_signal_autoconnect(xml);
144 main_wnd = glade_xml_get_widget(xml, "window1");
145 hpaned = glade_xml_get_widget(xml, "hpaned1");
146 vpaned = glade_xml_get_widget(xml, "vpaned1");
147 tree1_w = glade_xml_get_widget(xml, "treeview1");
148 tree2_w = glade_xml_get_widget(xml, "treeview2");
149 text_w = glade_xml_get_widget(xml, "textview3");
151 back_btn = glade_xml_get_widget(xml, "button1");
152 gtk_widget_set_sensitive(back_btn, FALSE);
154 widget = glade_xml_get_widget(xml, "show_name1");
155 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
156 show_name);
158 widget = glade_xml_get_widget(xml, "show_range1");
159 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
160 show_range);
162 widget = glade_xml_get_widget(xml, "show_data1");
163 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
164 show_value);
166 save_btn = glade_xml_get_widget(xml, "button3");
167 save_menu_item = glade_xml_get_widget(xml, "save1");
168 conf_set_changed_callback(conf_changed);
170 style = gtk_widget_get_style(main_wnd);
171 widget = glade_xml_get_widget(xml, "toolbar1");
173 replace_button_icon(xml, main_wnd->window, style,
174 "button4", (gchar **) xpm_single_view);
175 replace_button_icon(xml, main_wnd->window, style,
176 "button5", (gchar **) xpm_split_view);
177 replace_button_icon(xml, main_wnd->window, style,
178 "button6", (gchar **) xpm_tree_view);
180 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
181 tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
182 "foreground", "red",
183 "weight", PANGO_WEIGHT_BOLD,
184 NULL);
185 tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
186 /*"style", PANGO_STYLE_OBLIQUE, */
187 NULL);
189 sprintf(title, _("Linux Kernel v%s Configuration"),
190 getenv("KERNELVERSION"));
191 gtk_window_set_title(GTK_WINDOW(main_wnd), title);
193 gtk_widget_show(main_wnd);
196 void init_tree_model(void)
198 gint i;
200 tree = tree2 = gtk_tree_store_new(COL_NUMBER,
201 G_TYPE_STRING, G_TYPE_STRING,
202 G_TYPE_STRING, G_TYPE_STRING,
203 G_TYPE_STRING, G_TYPE_STRING,
204 G_TYPE_POINTER, GDK_TYPE_COLOR,
205 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
206 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
207 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
208 G_TYPE_BOOLEAN);
209 model2 = GTK_TREE_MODEL(tree2);
211 for (parents[0] = NULL, i = 1; i < 256; i++)
212 parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
214 tree1 = gtk_tree_store_new(COL_NUMBER,
215 G_TYPE_STRING, G_TYPE_STRING,
216 G_TYPE_STRING, G_TYPE_STRING,
217 G_TYPE_STRING, G_TYPE_STRING,
218 G_TYPE_POINTER, GDK_TYPE_COLOR,
219 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
220 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
221 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
222 G_TYPE_BOOLEAN);
223 model1 = GTK_TREE_MODEL(tree1);
226 void init_left_tree(void)
228 GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
229 GtkCellRenderer *renderer;
230 GtkTreeSelection *sel;
231 GtkTreeViewColumn *column;
233 gtk_tree_view_set_model(view, model1);
234 gtk_tree_view_set_headers_visible(view, TRUE);
235 gtk_tree_view_set_rules_hint(view, FALSE);
237 column = gtk_tree_view_column_new();
238 gtk_tree_view_append_column(view, column);
239 gtk_tree_view_column_set_title(column, _("Options"));
241 renderer = gtk_cell_renderer_toggle_new();
242 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
243 renderer, FALSE);
244 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
245 renderer,
246 "active", COL_BTNACT,
247 "inconsistent", COL_BTNINC,
248 "visible", COL_BTNVIS,
249 "radio", COL_BTNRAD, NULL);
250 renderer = gtk_cell_renderer_text_new();
251 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
252 renderer, FALSE);
253 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
254 renderer,
255 "text", COL_OPTION,
256 "foreground-gdk",
257 COL_COLOR, NULL);
259 sel = gtk_tree_view_get_selection(view);
260 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
261 gtk_widget_realize(tree1_w);
264 static void renderer_edited(GtkCellRendererText * cell,
265 const gchar * path_string,
266 const gchar * new_text, gpointer user_data);
267 static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
268 gchar * arg1, gpointer user_data);
270 void init_right_tree(void)
272 GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
273 GtkCellRenderer *renderer;
274 GtkTreeSelection *sel;
275 GtkTreeViewColumn *column;
276 gint i;
278 gtk_tree_view_set_model(view, model2);
279 gtk_tree_view_set_headers_visible(view, TRUE);
280 gtk_tree_view_set_rules_hint(view, FALSE);
282 column = gtk_tree_view_column_new();
283 gtk_tree_view_append_column(view, column);
284 gtk_tree_view_column_set_title(column, _("Options"));
286 renderer = gtk_cell_renderer_pixbuf_new();
287 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
288 renderer, FALSE);
289 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
290 renderer,
291 "pixbuf", COL_PIXBUF,
292 "visible", COL_PIXVIS, NULL);
293 renderer = gtk_cell_renderer_toggle_new();
294 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
295 renderer, FALSE);
296 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
297 renderer,
298 "active", COL_BTNACT,
299 "inconsistent", COL_BTNINC,
300 "visible", COL_BTNVIS,
301 "radio", COL_BTNRAD, NULL);
302 /*g_signal_connect(G_OBJECT(renderer), "toggled",
303 G_CALLBACK(renderer_toggled), NULL); */
304 renderer = gtk_cell_renderer_text_new();
305 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
306 renderer, FALSE);
307 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
308 renderer,
309 "text", COL_OPTION,
310 "foreground-gdk",
311 COL_COLOR, NULL);
313 renderer = gtk_cell_renderer_text_new();
314 gtk_tree_view_insert_column_with_attributes(view, -1,
315 _("Name"), renderer,
316 "text", COL_NAME,
317 "foreground-gdk",
318 COL_COLOR, NULL);
319 renderer = gtk_cell_renderer_text_new();
320 gtk_tree_view_insert_column_with_attributes(view, -1,
321 "N", renderer,
322 "text", COL_NO,
323 "foreground-gdk",
324 COL_COLOR, NULL);
325 renderer = gtk_cell_renderer_text_new();
326 gtk_tree_view_insert_column_with_attributes(view, -1,
327 "M", renderer,
328 "text", COL_MOD,
329 "foreground-gdk",
330 COL_COLOR, NULL);
331 renderer = gtk_cell_renderer_text_new();
332 gtk_tree_view_insert_column_with_attributes(view, -1,
333 "Y", renderer,
334 "text", COL_YES,
335 "foreground-gdk",
336 COL_COLOR, NULL);
337 renderer = gtk_cell_renderer_text_new();
338 gtk_tree_view_insert_column_with_attributes(view, -1,
339 _("Value"), renderer,
340 "text", COL_VALUE,
341 "editable",
342 COL_EDIT,
343 "foreground-gdk",
344 COL_COLOR, NULL);
345 g_signal_connect(G_OBJECT(renderer), "edited",
346 G_CALLBACK(renderer_edited), NULL);
348 column = gtk_tree_view_get_column(view, COL_NAME);
349 gtk_tree_view_column_set_visible(column, show_name);
350 column = gtk_tree_view_get_column(view, COL_NO);
351 gtk_tree_view_column_set_visible(column, show_range);
352 column = gtk_tree_view_get_column(view, COL_MOD);
353 gtk_tree_view_column_set_visible(column, show_range);
354 column = gtk_tree_view_get_column(view, COL_YES);
355 gtk_tree_view_column_set_visible(column, show_range);
356 column = gtk_tree_view_get_column(view, COL_VALUE);
357 gtk_tree_view_column_set_visible(column, show_value);
359 if (resizeable) {
360 for (i = 0; i < COL_VALUE; i++) {
361 column = gtk_tree_view_get_column(view, i);
362 gtk_tree_view_column_set_resizable(column, TRUE);
366 sel = gtk_tree_view_get_selection(view);
367 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
371 /* Utility Functions */
374 static void text_insert_help(struct menu *menu)
376 GtkTextBuffer *buffer;
377 GtkTextIter start, end;
378 const char *prompt = _(menu_get_prompt(menu));
379 struct gstr help = str_new();
381 menu_get_ext_help(menu, &help);
383 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
384 gtk_text_buffer_get_bounds(buffer, &start, &end);
385 gtk_text_buffer_delete(buffer, &start, &end);
386 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
388 gtk_text_buffer_get_end_iter(buffer, &end);
389 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
390 NULL);
391 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
392 gtk_text_buffer_get_end_iter(buffer, &end);
393 gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
394 NULL);
395 str_free(&help);
399 static void text_insert_msg(const char *title, const char *message)
401 GtkTextBuffer *buffer;
402 GtkTextIter start, end;
403 const char *msg = message;
405 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
406 gtk_text_buffer_get_bounds(buffer, &start, &end);
407 gtk_text_buffer_delete(buffer, &start, &end);
408 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
410 gtk_text_buffer_get_end_iter(buffer, &end);
411 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
412 NULL);
413 gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
414 gtk_text_buffer_get_end_iter(buffer, &end);
415 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
416 NULL);
420 /* Main Windows Callbacks */
422 void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
423 gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
424 gpointer user_data)
426 GtkWidget *dialog, *label;
427 gint result;
429 if (!conf_get_changed())
430 return FALSE;
432 dialog = gtk_dialog_new_with_buttons(_("Warning !"),
433 GTK_WINDOW(main_wnd),
434 (GtkDialogFlags)
435 (GTK_DIALOG_MODAL |
436 GTK_DIALOG_DESTROY_WITH_PARENT),
437 GTK_STOCK_OK,
438 GTK_RESPONSE_YES,
439 GTK_STOCK_NO,
440 GTK_RESPONSE_NO,
441 GTK_STOCK_CANCEL,
442 GTK_RESPONSE_CANCEL, NULL);
443 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
444 GTK_RESPONSE_CANCEL);
446 label = gtk_label_new(_("\nSave configuration ?\n"));
447 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
448 gtk_widget_show(label);
450 result = gtk_dialog_run(GTK_DIALOG(dialog));
451 switch (result) {
452 case GTK_RESPONSE_YES:
453 on_save_activate(NULL, NULL);
454 return FALSE;
455 case GTK_RESPONSE_NO:
456 return FALSE;
457 case GTK_RESPONSE_CANCEL:
458 case GTK_RESPONSE_DELETE_EVENT:
459 default:
460 gtk_widget_destroy(dialog);
461 return TRUE;
464 return FALSE;
468 void on_window1_destroy(GtkObject * object, gpointer user_data)
470 gtk_main_quit();
474 void
475 on_window1_size_request(GtkWidget * widget,
476 GtkRequisition * requisition, gpointer user_data)
478 static gint old_h;
479 gint w, h;
481 if (widget->window == NULL)
482 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
483 else
484 gdk_window_get_size(widget->window, &w, &h);
486 if (h == old_h)
487 return;
488 old_h = h;
490 gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
494 /* Menu & Toolbar Callbacks */
497 static void
498 load_filename(GtkFileSelection * file_selector, gpointer user_data)
500 const gchar *fn;
502 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
503 (user_data));
505 if (conf_read(fn))
506 text_insert_msg(_("Error"), _("Unable to load configuration !"));
507 else
508 display_tree(&rootmenu);
511 void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
513 GtkWidget *fs;
515 fs = gtk_file_selection_new(_("Load file..."));
516 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
517 "clicked",
518 G_CALLBACK(load_filename), (gpointer) fs);
519 g_signal_connect_swapped(GTK_OBJECT
520 (GTK_FILE_SELECTION(fs)->ok_button),
521 "clicked", G_CALLBACK(gtk_widget_destroy),
522 (gpointer) fs);
523 g_signal_connect_swapped(GTK_OBJECT
524 (GTK_FILE_SELECTION(fs)->cancel_button),
525 "clicked", G_CALLBACK(gtk_widget_destroy),
526 (gpointer) fs);
527 gtk_widget_show(fs);
531 void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
533 if (conf_write(NULL))
534 text_insert_msg(_("Error"), _("Unable to save configuration !"));
538 static void
539 store_filename(GtkFileSelection * file_selector, gpointer user_data)
541 const gchar *fn;
543 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
544 (user_data));
546 if (conf_write(fn))
547 text_insert_msg(_("Error"), _("Unable to save configuration !"));
549 gtk_widget_destroy(GTK_WIDGET(user_data));
552 void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
554 GtkWidget *fs;
556 fs = gtk_file_selection_new(_("Save file as..."));
557 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
558 "clicked",
559 G_CALLBACK(store_filename), (gpointer) fs);
560 g_signal_connect_swapped(GTK_OBJECT
561 (GTK_FILE_SELECTION(fs)->ok_button),
562 "clicked", G_CALLBACK(gtk_widget_destroy),
563 (gpointer) fs);
564 g_signal_connect_swapped(GTK_OBJECT
565 (GTK_FILE_SELECTION(fs)->cancel_button),
566 "clicked", G_CALLBACK(gtk_widget_destroy),
567 (gpointer) fs);
568 gtk_widget_show(fs);
572 void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
574 if (!on_window1_delete_event(NULL, NULL, NULL))
575 gtk_widget_destroy(GTK_WIDGET(main_wnd));
579 void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
581 GtkTreeViewColumn *col;
583 show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
584 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
585 if (col)
586 gtk_tree_view_column_set_visible(col, show_name);
590 void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
592 GtkTreeViewColumn *col;
594 show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
595 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
596 if (col)
597 gtk_tree_view_column_set_visible(col, show_range);
598 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
599 if (col)
600 gtk_tree_view_column_set_visible(col, show_range);
601 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
602 if (col)
603 gtk_tree_view_column_set_visible(col, show_range);
608 void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
610 GtkTreeViewColumn *col;
612 show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
613 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
614 if (col)
615 gtk_tree_view_column_set_visible(col, show_value);
619 void
620 on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
622 opt_mode = OPT_NORMAL;
623 gtk_tree_store_clear(tree2);
624 display_tree(&rootmenu); /* instead of update_tree to speed-up */
628 void
629 on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
631 opt_mode = OPT_ALL;
632 gtk_tree_store_clear(tree2);
633 display_tree(&rootmenu); /* instead of update_tree to speed-up */
637 void
638 on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
640 opt_mode = OPT_PROMPT;
641 gtk_tree_store_clear(tree2);
642 display_tree(&rootmenu); /* instead of update_tree to speed-up */
646 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
648 GtkWidget *dialog;
649 const gchar *intro_text = _(
650 "Welcome to gkc, the GTK+ graphical kernel configuration tool\n"
651 "for Linux.\n"
652 "For each option, a blank box indicates the feature is disabled, a\n"
653 "check indicates it is enabled, and a dot indicates that it is to\n"
654 "be compiled as a module. Clicking on the box will cycle through the three states.\n"
655 "\n"
656 "If you do not see an option (e.g., a device driver) that you\n"
657 "believe should be present, try turning on Show All Options\n"
658 "under the Options menu.\n"
659 "Although there is no cross reference yet to help you figure out\n"
660 "what other options must be enabled to support the option you\n"
661 "are interested in, you can still view the help of a grayed-out\n"
662 "option.\n"
663 "\n"
664 "Toggling Show Debug Info under the Options menu will show \n"
665 "the dependencies, which you can then match by examining other options.");
667 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
668 GTK_DIALOG_DESTROY_WITH_PARENT,
669 GTK_MESSAGE_INFO,
670 GTK_BUTTONS_CLOSE, intro_text);
671 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
672 G_CALLBACK(gtk_widget_destroy),
673 GTK_OBJECT(dialog));
674 gtk_widget_show_all(dialog);
678 void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
680 GtkWidget *dialog;
681 const gchar *about_text =
682 _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
683 "Based on the source code from Roman Zippel.\n");
685 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
686 GTK_DIALOG_DESTROY_WITH_PARENT,
687 GTK_MESSAGE_INFO,
688 GTK_BUTTONS_CLOSE, about_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_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
698 GtkWidget *dialog;
699 const gchar *license_text =
700 _("gkc is released under the terms of the GNU GPL v2.\n"
701 "For more information, please see the source code or\n"
702 "visit http://www.fsf.org/licenses/licenses.html\n");
704 dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
705 GTK_DIALOG_DESTROY_WITH_PARENT,
706 GTK_MESSAGE_INFO,
707 GTK_BUTTONS_CLOSE, license_text);
708 g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
709 G_CALLBACK(gtk_widget_destroy),
710 GTK_OBJECT(dialog));
711 gtk_widget_show_all(dialog);
715 void on_back_clicked(GtkButton * button, gpointer user_data)
717 enum prop_type ptype;
719 current = current->parent;
720 ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
721 if (ptype != P_MENU)
722 current = current->parent;
723 display_tree_part();
725 if (current == &rootmenu)
726 gtk_widget_set_sensitive(back_btn, FALSE);
730 void on_load_clicked(GtkButton * button, gpointer user_data)
732 on_load1_activate(NULL, user_data);
736 void on_single_clicked(GtkButton * button, gpointer user_data)
738 view_mode = SINGLE_VIEW;
739 gtk_paned_set_position(GTK_PANED(hpaned), 0);
740 gtk_widget_hide(tree1_w);
741 current = &rootmenu;
742 display_tree_part();
746 void on_split_clicked(GtkButton * button, gpointer user_data)
748 gint w, h;
749 view_mode = SPLIT_VIEW;
750 gtk_widget_show(tree1_w);
751 gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
752 gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
753 if (tree2)
754 gtk_tree_store_clear(tree2);
755 display_list();
757 /* Disable back btn, like in full mode. */
758 gtk_widget_set_sensitive(back_btn, FALSE);
762 void on_full_clicked(GtkButton * button, gpointer user_data)
764 view_mode = FULL_VIEW;
765 gtk_paned_set_position(GTK_PANED(hpaned), 0);
766 gtk_widget_hide(tree1_w);
767 if (tree2)
768 gtk_tree_store_clear(tree2);
769 display_tree(&rootmenu);
770 gtk_widget_set_sensitive(back_btn, FALSE);
774 void on_collapse_clicked(GtkButton * button, gpointer user_data)
776 gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
780 void on_expand_clicked(GtkButton * button, gpointer user_data)
782 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
786 /* CTree Callbacks */
788 /* Change hex/int/string value in the cell */
789 static void renderer_edited(GtkCellRendererText * cell,
790 const gchar * path_string,
791 const gchar * new_text, gpointer user_data)
793 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
794 GtkTreeIter iter;
795 const char *old_def, *new_def;
796 struct menu *menu;
797 struct symbol *sym;
799 if (!gtk_tree_model_get_iter(model2, &iter, path))
800 return;
802 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
803 sym = menu->sym;
805 gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
806 new_def = new_text;
808 sym_set_string_value(sym, new_def);
810 update_tree(&rootmenu, NULL);
812 gtk_tree_path_free(path);
815 /* Change the value of a symbol and update the tree */
816 static void change_sym_value(struct menu *menu, gint col)
818 struct symbol *sym = menu->sym;
819 tristate oldval, newval;
821 if (!sym)
822 return;
824 if (col == COL_NO)
825 newval = no;
826 else if (col == COL_MOD)
827 newval = mod;
828 else if (col == COL_YES)
829 newval = yes;
830 else
831 return;
833 switch (sym_get_type(sym)) {
834 case S_BOOLEAN:
835 case S_TRISTATE:
836 oldval = sym_get_tristate_value(sym);
837 if (!sym_tristate_within_range(sym, newval))
838 newval = yes;
839 sym_set_tristate_value(sym, newval);
840 if (view_mode == FULL_VIEW)
841 update_tree(&rootmenu, NULL);
842 else if (view_mode == SPLIT_VIEW) {
843 update_tree(browsed, NULL);
844 display_list();
846 else if (view_mode == SINGLE_VIEW)
847 display_tree_part();
848 break;
849 case S_INT:
850 case S_HEX:
851 case S_STRING:
852 default:
853 break;
857 static void toggle_sym_value(struct menu *menu)
859 if (!menu->sym)
860 return;
862 sym_toggle_tristate_value(menu->sym);
863 if (view_mode == FULL_VIEW)
864 update_tree(&rootmenu, NULL);
865 else if (view_mode == SPLIT_VIEW) {
866 update_tree(browsed, NULL);
867 display_list();
869 else if (view_mode == SINGLE_VIEW)
870 display_tree_part();
873 static void renderer_toggled(GtkCellRendererToggle * cell,
874 gchar * path_string, gpointer user_data)
876 GtkTreePath *path, *sel_path = NULL;
877 GtkTreeIter iter, sel_iter;
878 GtkTreeSelection *sel;
879 struct menu *menu;
881 path = gtk_tree_path_new_from_string(path_string);
882 if (!gtk_tree_model_get_iter(model2, &iter, path))
883 return;
885 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree2_w));
886 if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
887 sel_path = gtk_tree_model_get_path(model2, &sel_iter);
888 if (!sel_path)
889 goto out1;
890 if (gtk_tree_path_compare(path, sel_path))
891 goto out2;
893 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
894 toggle_sym_value(menu);
896 out2:
897 gtk_tree_path_free(sel_path);
898 out1:
899 gtk_tree_path_free(path);
902 static gint column2index(GtkTreeViewColumn * column)
904 gint i;
906 for (i = 0; i < COL_NUMBER; i++) {
907 GtkTreeViewColumn *col;
909 col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
910 if (col == column)
911 return i;
914 return -1;
918 /* User click: update choice (full) or goes down (single) */
919 gboolean
920 on_treeview2_button_press_event(GtkWidget * widget,
921 GdkEventButton * event, gpointer user_data)
923 GtkTreeView *view = GTK_TREE_VIEW(widget);
924 GtkTreePath *path;
925 GtkTreeViewColumn *column;
926 GtkTreeIter iter;
927 struct menu *menu;
928 gint col;
930 #if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
931 gint tx = (gint) event->x;
932 gint ty = (gint) event->y;
933 gint cx, cy;
935 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
936 &cy);
937 #else
938 gtk_tree_view_get_cursor(view, &path, &column);
939 #endif
940 if (path == NULL)
941 return FALSE;
943 if (!gtk_tree_model_get_iter(model2, &iter, path))
944 return FALSE;
945 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
947 col = column2index(column);
948 if (event->type == GDK_2BUTTON_PRESS) {
949 enum prop_type ptype;
950 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
952 if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
953 // goes down into menu
954 current = menu;
955 display_tree_part();
956 gtk_widget_set_sensitive(back_btn, TRUE);
957 } else if ((col == COL_OPTION)) {
958 toggle_sym_value(menu);
959 gtk_tree_view_expand_row(view, path, TRUE);
961 } else {
962 if (col == COL_VALUE) {
963 toggle_sym_value(menu);
964 gtk_tree_view_expand_row(view, path, TRUE);
965 } else if (col == COL_NO || col == COL_MOD
966 || col == COL_YES) {
967 change_sym_value(menu, col);
968 gtk_tree_view_expand_row(view, path, TRUE);
972 return FALSE;
975 /* Key pressed: update choice */
976 gboolean
977 on_treeview2_key_press_event(GtkWidget * widget,
978 GdkEventKey * event, gpointer user_data)
980 GtkTreeView *view = GTK_TREE_VIEW(widget);
981 GtkTreePath *path;
982 GtkTreeViewColumn *column;
983 GtkTreeIter iter;
984 struct menu *menu;
985 gint col;
987 gtk_tree_view_get_cursor(view, &path, &column);
988 if (path == NULL)
989 return FALSE;
991 if (event->keyval == GDK_space) {
992 if (gtk_tree_view_row_expanded(view, path))
993 gtk_tree_view_collapse_row(view, path);
994 else
995 gtk_tree_view_expand_row(view, path, FALSE);
996 return TRUE;
998 if (event->keyval == GDK_KP_Enter) {
1000 if (widget == tree1_w)
1001 return FALSE;
1003 gtk_tree_model_get_iter(model2, &iter, path);
1004 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1006 if (!strcasecmp(event->string, "n"))
1007 col = COL_NO;
1008 else if (!strcasecmp(event->string, "m"))
1009 col = COL_MOD;
1010 else if (!strcasecmp(event->string, "y"))
1011 col = COL_YES;
1012 else
1013 col = -1;
1014 change_sym_value(menu, col);
1016 return FALSE;
1020 /* Row selection changed: update help */
1021 void
1022 on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1024 GtkTreeSelection *selection;
1025 GtkTreeIter iter;
1026 struct menu *menu;
1028 selection = gtk_tree_view_get_selection(treeview);
1029 if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1030 gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1031 text_insert_help(menu);
1036 /* User click: display sub-tree in the right frame. */
1037 gboolean
1038 on_treeview1_button_press_event(GtkWidget * widget,
1039 GdkEventButton * event, gpointer user_data)
1041 GtkTreeView *view = GTK_TREE_VIEW(widget);
1042 GtkTreePath *path;
1043 GtkTreeViewColumn *column;
1044 GtkTreeIter iter;
1045 struct menu *menu;
1047 gint tx = (gint) event->x;
1048 gint ty = (gint) event->y;
1049 gint cx, cy;
1051 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1052 &cy);
1053 if (path == NULL)
1054 return FALSE;
1056 gtk_tree_model_get_iter(model1, &iter, path);
1057 gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1059 if (event->type == GDK_2BUTTON_PRESS) {
1060 toggle_sym_value(menu);
1061 current = menu;
1062 display_tree_part();
1063 } else {
1064 browsed = menu;
1065 display_tree_part();
1068 gtk_widget_realize(tree2_w);
1069 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1070 gtk_widget_grab_focus(tree2_w);
1072 return FALSE;
1076 /* Fill a row of strings */
1077 static gchar **fill_row(struct menu *menu)
1079 static gchar *row[COL_NUMBER];
1080 struct symbol *sym = menu->sym;
1081 const char *def;
1082 int stype;
1083 tristate val;
1084 enum prop_type ptype;
1085 int i;
1087 for (i = COL_OPTION; i <= COL_COLOR; i++)
1088 g_free(row[i]);
1089 bzero(row, sizeof(row));
1091 row[COL_OPTION] =
1092 g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1093 sym && !sym_has_value(sym) ? "(NEW)" : "");
1095 if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1096 row[COL_COLOR] = g_strdup("DarkGray");
1097 else if (opt_mode == OPT_PROMPT &&
1098 menu_has_prompt(menu) && !menu_is_visible(menu))
1099 row[COL_COLOR] = g_strdup("DarkGray");
1100 else
1101 row[COL_COLOR] = g_strdup("Black");
1103 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1104 switch (ptype) {
1105 case P_MENU:
1106 row[COL_PIXBUF] = (gchar *) xpm_menu;
1107 if (view_mode == SINGLE_VIEW)
1108 row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1109 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1110 break;
1111 case P_COMMENT:
1112 row[COL_PIXBUF] = (gchar *) xpm_void;
1113 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1114 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1115 break;
1116 default:
1117 row[COL_PIXBUF] = (gchar *) xpm_void;
1118 row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1119 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1120 break;
1123 if (!sym)
1124 return row;
1125 row[COL_NAME] = g_strdup(sym->name);
1127 sym_calc_value(sym);
1128 sym->flags &= ~SYMBOL_CHANGED;
1130 if (sym_is_choice(sym)) { // parse childs for getting final value
1131 struct menu *child;
1132 struct symbol *def_sym = sym_get_choice_value(sym);
1133 struct menu *def_menu = NULL;
1135 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1137 for (child = menu->list; child; child = child->next) {
1138 if (menu_is_visible(child)
1139 && child->sym == def_sym)
1140 def_menu = child;
1143 if (def_menu)
1144 row[COL_VALUE] =
1145 g_strdup(_(menu_get_prompt(def_menu)));
1147 if (sym->flags & SYMBOL_CHOICEVAL)
1148 row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1150 stype = sym_get_type(sym);
1151 switch (stype) {
1152 case S_BOOLEAN:
1153 if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
1154 row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1155 if (sym_is_choice(sym))
1156 break;
1157 case S_TRISTATE:
1158 val = sym_get_tristate_value(sym);
1159 switch (val) {
1160 case no:
1161 row[COL_NO] = g_strdup("N");
1162 row[COL_VALUE] = g_strdup("N");
1163 row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1164 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1165 break;
1166 case mod:
1167 row[COL_MOD] = g_strdup("M");
1168 row[COL_VALUE] = g_strdup("M");
1169 row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1170 break;
1171 case yes:
1172 row[COL_YES] = g_strdup("Y");
1173 row[COL_VALUE] = g_strdup("Y");
1174 row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1175 row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1176 break;
1179 if (val != no && sym_tristate_within_range(sym, no))
1180 row[COL_NO] = g_strdup("_");
1181 if (val != mod && sym_tristate_within_range(sym, mod))
1182 row[COL_MOD] = g_strdup("_");
1183 if (val != yes && sym_tristate_within_range(sym, yes))
1184 row[COL_YES] = g_strdup("_");
1185 break;
1186 case S_INT:
1187 case S_HEX:
1188 case S_STRING:
1189 def = sym_get_string_value(sym);
1190 row[COL_VALUE] = g_strdup(def);
1191 row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1192 row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1193 break;
1196 return row;
1200 /* Set the node content with a row of strings */
1201 static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1203 GdkColor color;
1204 gboolean success;
1205 GdkPixbuf *pix;
1207 pix = gdk_pixbuf_new_from_xpm_data((const char **)
1208 row[COL_PIXBUF]);
1210 gdk_color_parse(row[COL_COLOR], &color);
1211 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1212 FALSE, FALSE, &success);
1214 gtk_tree_store_set(tree, node,
1215 COL_OPTION, row[COL_OPTION],
1216 COL_NAME, row[COL_NAME],
1217 COL_NO, row[COL_NO],
1218 COL_MOD, row[COL_MOD],
1219 COL_YES, row[COL_YES],
1220 COL_VALUE, row[COL_VALUE],
1221 COL_MENU, (gpointer) menu,
1222 COL_COLOR, &color,
1223 COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1224 COL_PIXBUF, pix,
1225 COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1226 COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1227 COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1228 COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1229 COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1230 -1);
1232 g_object_unref(pix);
1236 /* Add a node to the tree */
1237 static void place_node(struct menu *menu, char **row)
1239 GtkTreeIter *parent = parents[indent - 1];
1240 GtkTreeIter *node = parents[indent];
1242 gtk_tree_store_append(tree, node, parent);
1243 set_node(node, menu, row);
1247 /* Find a node in the GTK+ tree */
1248 static GtkTreeIter found;
1251 * Find a menu in the GtkTree starting at parent.
1253 GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1254 struct menu *tofind)
1256 GtkTreeIter iter;
1257 GtkTreeIter *child = &iter;
1258 gboolean valid;
1259 GtkTreeIter *ret;
1261 valid = gtk_tree_model_iter_children(model2, child, parent);
1262 while (valid) {
1263 struct menu *menu;
1265 gtk_tree_model_get(model2, child, 6, &menu, -1);
1267 if (menu == tofind) {
1268 memcpy(&found, child, sizeof(GtkTreeIter));
1269 return &found;
1272 ret = gtktree_iter_find_node(child, tofind);
1273 if (ret)
1274 return ret;
1276 valid = gtk_tree_model_iter_next(model2, child);
1279 return NULL;
1284 * Update the tree by adding/removing entries
1285 * Does not change other nodes
1287 static void update_tree(struct menu *src, GtkTreeIter * dst)
1289 struct menu *child1;
1290 GtkTreeIter iter, tmp;
1291 GtkTreeIter *child2 = &iter;
1292 gboolean valid;
1293 GtkTreeIter *sibling;
1294 struct symbol *sym;
1295 struct property *prop;
1296 struct menu *menu1, *menu2;
1298 if (src == &rootmenu)
1299 indent = 1;
1301 valid = gtk_tree_model_iter_children(model2, child2, dst);
1302 for (child1 = src->list; child1; child1 = child1->next) {
1304 prop = child1->prompt;
1305 sym = child1->sym;
1307 reparse:
1308 menu1 = child1;
1309 if (valid)
1310 gtk_tree_model_get(model2, child2, COL_MENU,
1311 &menu2, -1);
1312 else
1313 menu2 = NULL; // force adding of a first child
1315 #ifdef DEBUG
1316 printf("%*c%s | %s\n", indent, ' ',
1317 menu1 ? menu_get_prompt(menu1) : "nil",
1318 menu2 ? menu_get_prompt(menu2) : "nil");
1319 #endif
1321 if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1322 (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1323 (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
1325 /* remove node */
1326 if (gtktree_iter_find_node(dst, menu1) != NULL) {
1327 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1328 valid = gtk_tree_model_iter_next(model2,
1329 child2);
1330 gtk_tree_store_remove(tree2, &tmp);
1331 if (!valid)
1332 return; /* next parent */
1333 else
1334 goto reparse; /* next child */
1335 } else
1336 continue;
1339 if (menu1 != menu2) {
1340 if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node
1341 if (!valid && !menu2)
1342 sibling = NULL;
1343 else
1344 sibling = child2;
1345 gtk_tree_store_insert_before(tree2,
1346 child2,
1347 dst, sibling);
1348 set_node(child2, menu1, fill_row(menu1));
1349 if (menu2 == NULL)
1350 valid = TRUE;
1351 } else { // remove node
1352 memcpy(&tmp, child2, sizeof(GtkTreeIter));
1353 valid = gtk_tree_model_iter_next(model2,
1354 child2);
1355 gtk_tree_store_remove(tree2, &tmp);
1356 if (!valid)
1357 return; // next parent
1358 else
1359 goto reparse; // next child
1361 } else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1362 set_node(child2, menu1, fill_row(menu1));
1365 indent++;
1366 update_tree(child1, child2);
1367 indent--;
1369 valid = gtk_tree_model_iter_next(model2, child2);
1374 /* Display the whole tree (single/split/full view) */
1375 static void display_tree(struct menu *menu)
1377 struct symbol *sym;
1378 struct property *prop;
1379 struct menu *child;
1380 enum prop_type ptype;
1382 if (menu == &rootmenu) {
1383 indent = 1;
1384 current = &rootmenu;
1387 for (child = menu->list; child; child = child->next) {
1388 prop = child->prompt;
1389 sym = child->sym;
1390 ptype = prop ? prop->type : P_UNKNOWN;
1392 if (sym)
1393 sym->flags &= ~SYMBOL_CHANGED;
1395 if ((view_mode == SPLIT_VIEW)
1396 && !(child->flags & MENU_ROOT) && (tree == tree1))
1397 continue;
1399 if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT)
1400 && (tree == tree2))
1401 continue;
1403 if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1404 (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1405 (opt_mode == OPT_ALL && menu_get_prompt(child)))
1406 place_node(child, fill_row(child));
1407 #ifdef DEBUG
1408 printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1409 printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1410 printf("%s", prop_get_type_name(ptype));
1411 printf(" | ");
1412 if (sym) {
1413 printf("%s", sym_type_name(sym->type));
1414 printf(" | ");
1415 printf("%s", dbg_sym_flags(sym->flags));
1416 printf("\n");
1417 } else
1418 printf("\n");
1419 #endif
1420 if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1421 && (tree == tree2))
1422 continue;
1424 if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
1425 || (view_mode == FULL_VIEW)
1426 || (view_mode == SPLIT_VIEW))*/
1427 if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
1428 || (view_mode == FULL_VIEW)
1429 || (view_mode == SPLIT_VIEW)) {
1430 indent++;
1431 display_tree(child);
1432 indent--;
1437 /* Display a part of the tree starting at current node (single/split view) */
1438 static void display_tree_part(void)
1440 if (tree2)
1441 gtk_tree_store_clear(tree2);
1442 if (view_mode == SINGLE_VIEW)
1443 display_tree(current);
1444 else if (view_mode == SPLIT_VIEW)
1445 display_tree(browsed);
1446 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1449 /* Display the list in the left frame (split view) */
1450 static void display_list(void)
1452 if (tree1)
1453 gtk_tree_store_clear(tree1);
1455 tree = tree1;
1456 display_tree(&rootmenu);
1457 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1458 tree = tree2;
1461 void fixup_rootmenu(struct menu *menu)
1463 struct menu *child;
1464 static int menu_cnt = 0;
1466 menu->flags |= MENU_ROOT;
1467 for (child = menu->list; child; child = child->next) {
1468 if (child->prompt && child->prompt->type == P_MENU) {
1469 menu_cnt++;
1470 fixup_rootmenu(child);
1471 menu_cnt--;
1472 } else if (!menu_cnt)
1473 fixup_rootmenu(child);
1478 /* Main */
1479 int main(int ac, char *av[])
1481 const char *name;
1482 char *env;
1483 gchar *glade_file;
1485 #ifndef LKC_DIRECT_LINK
1486 kconfig_load();
1487 #endif
1489 bindtextdomain(PACKAGE, LOCALEDIR);
1490 bind_textdomain_codeset(PACKAGE, "UTF-8");
1491 textdomain(PACKAGE);
1493 /* GTK stuffs */
1494 gtk_set_locale();
1495 gtk_init(&ac, &av);
1496 glade_init();
1498 //add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1499 //add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1501 /* Determine GUI path */
1502 env = getenv(SRCTREE);
1503 if (env)
1504 glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
1505 else if (av[0][0] == '/')
1506 glade_file = g_strconcat(av[0], ".glade", NULL);
1507 else
1508 glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1510 /* Load the interface and connect signals */
1511 init_main_window(glade_file);
1512 init_tree_model();
1513 init_left_tree();
1514 init_right_tree();
1516 /* Conf stuffs */
1517 if (ac > 1 && av[1][0] == '-') {
1518 switch (av[1][1]) {
1519 case 'a':
1520 //showAll = 1;
1521 break;
1522 case 'h':
1523 case '?':
1524 printf("%s <config>\n", av[0]);
1525 exit(0);
1527 name = av[2];
1528 } else
1529 name = av[1];
1531 conf_parse(name);
1532 fixup_rootmenu(&rootmenu);
1533 conf_read(NULL);
1535 switch (view_mode) {
1536 case SINGLE_VIEW:
1537 display_tree_part();
1538 break;
1539 case SPLIT_VIEW:
1540 display_list();
1541 break;
1542 case FULL_VIEW:
1543 display_tree(&rootmenu);
1544 break;
1547 gtk_main();
1549 return 0;
1552 static void conf_changed(void)
1554 bool changed = conf_get_changed();
1555 gtk_widget_set_sensitive(save_btn, changed);
1556 gtk_widget_set_sensitive(save_menu_item, changed);