On Thu, Sep 05, 2002 at 10:46:38PM -0700, Michael Cardenas wrote: > Attached is a patch against cvs for > > debian-installer/tools/cdebconf/src/modules/frontend/gtk/gtk.c > > that corrects a number of the problems discussed below. Unfortunately, > I still can't test, as I mentioned in an earlier email, so I would > appreciate if someone could verify this patch before applying it. > Thanks to Mithrandir, I was able to get the tests working. Attached is a newer patch that is radically improved over the last one. Improvements include: - dialogs are now hidden before calling gtk_main_quit, so after hitting "finish" the dialog goes away - titlebar is set to question short description - text handler works now and no longer crashes There are still some problems with default values, such as selecting them in the dialogs, filling them in, etc. Also, the test I was using has only one question per call to go. Is this similar to how the installer will really flow? I was using "Finish" if there were no more questions, but it seems that this is incorrect, and I should use next. But in that case, the frontend needs the ability to tell the caller to go forward to the next question or back to the previous one. Also, do we need udebs for gtk and X or not? I imagine that we could make d-i detect the video card and monitor, and if it's capable of displaying graphics, download x and gtk or gtkfb from the mirror. -- michael cardenas | lead software engineer | lindows.com | hyperpoem.net "As a man is, so he sees." - William Blake
Index: gtk.c =================================================================== RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/frontend/gtk/gtk.c,v retrieving revision 1.1 diff -u -r1.1 gtk.c --- gtk.c 5 Sep 2002 12:30:23 -0000 1.1 +++ gtk.c 6 Sep 2002 07:43:12 -0000 @@ -67,12 +67,12 @@ #define _(x) x #endif -int gBool; -int gSelectNum; -char *gPassword; -int gMultiChoices[100]; -gboolean gBack, gNext; -GtkWidget *gRadio; +struct multicheck_data +{ + int multiChoices[100]; + GtkWidget **choices; +}; + /* * Function: passwd_callback @@ -82,14 +82,17 @@ * Assumptions: */ void passwd_callback( GtkWidget *widget, - GtkWidget *entry ) + GtkWidget *data ) { const char *entrytext; - entrytext = gtk_entry_get_text (GTK_ENTRY (entry)); - - gPassword = malloc(strlen(entrytext)); - strcpy(gPassword, entrytext); + char **callstring; + + callstring = (char **)data; + + entrytext = gtk_entry_get_text (GTK_ENTRY (widget)); + *callstring = strdup(entrytext); + printf("Password captured.\n"); } @@ -103,15 +106,19 @@ void check_callback( GtkWidget *widget, gpointer data ) { + gboolean *gbool; + + gbool = (gboolean *)data; + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { /* If control reaches here, the toggle button is down */ - gBool = 1; + *gbool = TRUE; } else { /* If control reaches here, the toggle button is up */ - gBool = 0; + *gbool = FALSE; } } @@ -126,10 +133,13 @@ gpointer data ) { int i, val; - GtkWidget **choices; gboolean done; + struct multicheck_data *call_data; + GtkWidget **choices; + + call_data = (struct multicheck_data *)data; + choices = call_data->choices; - choices = (GtkWidget **)data; i = 0; done = FALSE; @@ -149,7 +159,7 @@ { if(*choices == widget) { - gMultiChoices[i] = val; + call_data->multiChoices[i] = val; done = TRUE; } @@ -170,12 +180,15 @@ void select_callback( GtkWidget *widget, gpointer data ) { + GtkWidget **radio; + + radio = (GtkWidget **)data; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { /* If control reaches here, the toggle button is down */ printf("selected: %p\n", widget); - gRadio = widget; + *radio = widget; } else { @@ -187,39 +200,6 @@ /* - * Function: choice_callback - * Input: none - * Output: none - * Description: respond to button press and determing which button was pressed - * Assumptions: - */ -void choice_callback( GtkWidget *widget, - gpointer data ) -{ - int i; - GtkWidget **choices; - gboolean done; - - choices = (GtkWidget **)data; - i = 0; - done = FALSE; - - while(*choices && !done) - { - if(*choices == widget) - { - gSelectNum = i; - done = TRUE; - } - - i++; - choices++; - } - -} - - -/* * Function: next * Input: none * Output: none @@ -229,10 +209,12 @@ void next( GtkWidget *widget, gpointer data ) { - gNext = TRUE; - gBack = FALSE; + GtkWidget *window; + + window = (GtkWidget *)data; g_print ("next\n"); + gtk_widget_hide(window); gtk_main_quit(); } @@ -240,14 +222,18 @@ * Function: back * Input: none * Output: none - * Description: go back to previous question - * Assumptions: + * Description: go back to previous question. + * Assumptions: the question handler loop will increment before continuing + * so move back two questions in order to move back one. */ void back( GtkWidget *widget, gpointer data ) { - gBack = TRUE; - gNext = FALSE; + struct question **pq; + + pq = (struct question **)data; + + *pq = (*pq)->prev->prev; g_print ("back\n"); gtk_main_quit(); @@ -299,6 +285,8 @@ GtkWidget *nextButton, *backButton; GtkWidget *descbox, *label, *elabel, *separator; + gtk_window_set_title(GTK_WINDOW(window), question_description(q)); + //set up window signal handlers //TODO: move this out of here! g_signal_connect (G_OBJECT (window), "delete_event", @@ -334,7 +322,7 @@ { backButton = gtk_button_new_with_label ("Back"); g_signal_connect (G_OBJECT (backButton), "clicked", - G_CALLBACK (back), NULL); + G_CALLBACK (back), &q); gtk_box_pack_start(GTK_BOX(box), backButton, FALSE, 5, 5); gtk_widget_show (backButton); } @@ -346,7 +334,8 @@ nextButton = gtk_button_new_with_label("Finish"); g_signal_connect (G_OBJECT (nextButton), "clicked", - G_CALLBACK (next), NULL); + G_CALLBACK (next), window); + gtk_box_pack_start(GTK_BOX(box), nextButton, FALSE, 5, 5); gtk_widget_show (nextButton); @@ -358,75 +347,6 @@ /* - * Function: getwidth - * Input: none - * Output: int - width of screen - * Description: get the width of the current terminal - * Assumptions: doesn't handle resizing; caches value on first call - * - * TODO: implement this to get the size of the X desktop - -static const int getwidth(void) -{ - static int res = 80; - static int inited = 0; - int fd; - struct winsize ws; - - if (inited == 0) - { - inited = 1; - if ((fd = open("/dev/tty", O_RDONLY)) > 0) - { - if (ioctl(fd, TIOCGWINSZ, &ws) == 0) - res = ws.ws_col; - close(fd); - } - } - return res; -} -*/ - - -/* - * Function: wrap_print - * Input: const char *str - string to display - * Output: none - * Description: prints a string to the screen with word wrapping - * Assumptions: string fits in <500 lines - * Simple greedy line-wrapper - -static void wrap_print(const char *str) -{ - - int i, lc; - char *lines[500]; - - lc = strwrap(str, getwidth() - 1, lines, DIM(lines)); - - for (i = 0; i < lc; i++) - { - printf("%s\n", lines[i]); - DELETE(lines[i]); - } -} -*/ - -/* - * Function: texthandler_displaydesc - * Input: struct frontend *obj - UI object - * struct question *q - question for which to display the description - * Output: none - * Description: displays the description for a given question - * Assumptions: none - * -static void texthandler_displaydesc(struct frontend *obj, struct question *q) -{ - wrap_print(question_description(q)); - wrap_print(question_extended_description(q)); -}*/ - -/* * Function: gtkhandler_boolean * Input: struct frontend *obj - frontend object * struct question *q - question to ask @@ -436,14 +356,15 @@ */ static int gtkhandler_boolean(struct frontend *obj, struct question *q) { - int ans = -1; int def = -1; const char *defval; GtkWidget *window; GtkWidget *boolButton; GtkWidget *hboxtop, *hboxbottom, *bigbox; + gboolean gbool; defval = question_defaultval(q); + if (defval) { if (strcmp(defval, "true") == 0) @@ -465,7 +386,7 @@ boolButton = gtk_check_button_new_with_label ( (gchar *)question_description(q) ); g_signal_connect (G_OBJECT (boolButton), "clicked", - G_CALLBACK (check_callback), NULL); + G_CALLBACK (check_callback), &gbool); gtk_box_pack_start(GTK_BOX(hboxtop), boolButton, FALSE, 5, 5); gtk_widget_show (boolButton); @@ -484,16 +405,8 @@ gtk_main (); - if(gBool) - { - ans = 1; - } - else - { - ans = 0; - } + question_setvalue(q, (gbool ? "true" : "false")); - question_setvalue(q, (ans ? "true" : "false")); return DC_OK; } @@ -518,16 +431,15 @@ GtkWidget *window; GtkWidget *hboxtop, *hboxbottom, *bigbox; GtkWidget **choiceButtons; + struct multicheck_data call_data; + + memset(&call_data.choices, 0, sizeof(call_data.multiChoices)); count = strchoicesplit(question_choices(q), choices, DIM(choices)); dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults)); - choiceButtons = (GtkWidget **)malloc( (count * (sizeof(GtkWidget *)) + 1) ); - - for(i = 0; i < count; i++) - choiceButtons[i] = (GtkWidget *)malloc(sizeof(GtkWidget *)); - - choiceButtons[count + 1] = 0; + choiceButtons = (GtkWidget **)malloc( (count + 1) * (sizeof(GtkWidget *)) ); + choiceButtons[count] = 0; if (dcount > 0) for (i = 0; i < count; i++) @@ -535,7 +447,7 @@ if (strcmp(choices[i], defaults[j]) == 0) { selected[i] = 1; - gMultiChoices[i] = 1; + call_data.multiChoices[i] = 1; } //create the window for the question @@ -548,13 +460,15 @@ add_common_buttons(window, hboxbottom, bigbox, q); + call_data.choices = choiceButtons; + for (i = 0; i < count; i++) { //create a button for each choice here and init the global place to store them choiceButtons[i] = gtk_check_button_new_with_label ( (gchar *)choices[i] ); g_signal_connect (G_OBJECT (choiceButtons[i]), "clicked", - G_CALLBACK (multicheck_callback), choiceButtons); + G_CALLBACK (multicheck_callback), &call_data); gtk_box_pack_start(GTK_BOX(hboxtop), choiceButtons[i], FALSE, 5, 0); gtk_widget_show (choiceButtons[i]); @@ -581,7 +495,7 @@ for (i = 0; i < count; i++) { - if(gMultiChoices[i]) + if(call_data.multiChoices[i]) { if(j) { @@ -593,9 +507,8 @@ } } - for (i = 0; i < count; i++) - free(choiceButtons[i]); - + free(choiceButtons); + printf("%s", answer); question_setvalue(q, answer); @@ -662,6 +575,7 @@ char passwd[256] = {0}; GtkWidget *window, *hboxbottom, *hboxtop, *bigbox; GtkWidget *entry; + char *callstring; //create the window for the question window = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -674,9 +588,10 @@ //add actual password field entry = gtk_entry_new (); gtk_entry_set_max_length (GTK_ENTRY (entry), 50); + g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (passwd_callback), - entry); + &callstring); gtk_box_pack_start (GTK_BOX (hboxtop), entry, TRUE, TRUE, 0); gtk_widget_show (entry); @@ -696,7 +611,10 @@ gtk_main(); - strcpy(passwd, gPassword); + if(callstring) + strcpy(passwd, callstring); + else + strcpy(passwd, ""); question_setvalue(q, passwd); return DC_OK; @@ -725,14 +643,15 @@ GtkWidget *hboxtop, *hboxbottom, *bigbox; GtkWidget **choiceButtons; GtkWidget *firstButton, *nextButton; + GtkWidget *radio; + int selectNum; + + selectNum = 0; count = strchoicesplit(question_choices(q), choices, DIM(choices)); dcount = strchoicesplit(question_defaultval(q), defaults, DIM(defaults)); - choiceButtons = (GtkWidget **)malloc( (count * (sizeof(GtkWidget *)) + 1) ); - - for(i = 0; i < count; i++) - choiceButtons[i] = (GtkWidget *)malloc(sizeof(GtkWidget *)); + choiceButtons = (GtkWidget **)malloc( (count+1) * ( sizeof(GtkWidget *) ) ); choiceButtons[count + 1] = 0; @@ -742,7 +661,7 @@ if (strcmp(choices[i], defaults[j]) == 0) { selected[i] = 1; - gSelectNum = i; + selectNum = i; } //create the window for the question @@ -771,16 +690,16 @@ choiceButtons[i] = nextButton; g_signal_connect (G_OBJECT (nextButton), "clicked", - G_CALLBACK (select_callback), choiceButtons); + G_CALLBACK (select_callback), &radio); gtk_box_pack_start (GTK_BOX (hboxtop), nextButton, TRUE, TRUE, 0); gtk_widget_show (nextButton); - if(i == gSelectNum) + if(i == selectNum) { printf("setting default to %d\n", i); - GTK_WIDGET_SET_FLAGS (nextButton, GTK_CAN_DEFAULT); - gtk_widget_grab_default (nextButton); + //GTK_WIDGET_SET_FLAGS (nextButton, GTK_CAN_DEFAULT); + //gtk_widget_grab_default (nextButton); } firstButton = nextButton; @@ -803,9 +722,9 @@ while(*choiceButtons) { - if(*choiceButtons == gRadio) + if(*choiceButtons == radio) { - gSelectNum = i; + selectNum = i; break; } else @@ -815,22 +734,18 @@ } } - printf("selected: %d\n", gSelectNum); + printf("selected: %d\n", selectNum); //once the dialog returns, handle the result printf("freeing %d buttons\n", count); - //FIXME: why does this crash?! - /* for (i = 0; i < count; i++) - { - free(choiceButtons[i]); - }*/ + free(choiceButtons[i]); - printf("selectnum: %d\n", gSelectNum); + printf("selectnum: %d\n", selectNum); - if(gSelectNum >= 0 && gSelectNum < count) + if(selectNum >= 0 && selectNum < count) { - strcpy(answer, choices[gSelectNum]); + strcpy(answer, choices[selectNum]); } printf("answer: %s\n", answer); @@ -856,6 +771,7 @@ char passwd[256] = {0}; GtkWidget *window, *hboxbottom, *hboxtop, *bigbox; GtkWidget *entry; + char *callstring; //create the window for the question window = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -867,10 +783,11 @@ //add actual text entry field entry = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (entry), 50); g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (passwd_callback), - entry); + &callstring); gtk_box_pack_start (GTK_BOX (hboxtop), entry, TRUE, TRUE, 0); gtk_widget_show (entry); @@ -889,7 +806,10 @@ gtk_main(); - strcpy(passwd, gPassword); + if(callstring) + strcpy(passwd, callstring); + else + strcpy(passwd, ""); question_setvalue(q, passwd); @@ -914,11 +834,11 @@ char buf[1024]; GtkWidget *window; GtkWidget *hboxtop, *hboxbottom, *bigbox; - GtkWidget *view; + GtkWidget *view, *sw; GtkTextBuffer *buffer; char *text; GtkTextIter start, end; - + //create the window for the question window = gtk_window_new (GTK_WINDOW_TOPLEVEL); bigbox = gtk_vbox_new(FALSE, 0); @@ -929,13 +849,26 @@ //add the text entry field view = gtk_text_view_new (); - gtk_box_pack_start(GTK_BOX(hboxtop), view, FALSE, 5, 5); - gtk_widget_show (view); + //gtk_box_pack_start(GTK_BOX(hboxtop), view, FALSE, 5, 5); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); gtk_text_buffer_get_start_iter (buffer, &start); gtk_text_buffer_get_end_iter (buffer, &end); + sw = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + gtk_box_pack_start(GTK_BOX(hboxtop), sw, FALSE, 5, 5); + + //gtk_container_add (window, vpaned); + + gtk_container_add (GTK_CONTAINER (sw), view); + + gtk_widget_show (view); + gtk_widget_show (sw); + //adjust the size gtk_widget_set_size_request(view, 200, 100); @@ -955,6 +888,9 @@ gtk_main(); + gtk_text_buffer_get_start_iter (buffer, &start); + gtk_text_buffer_get_end_iter (buffer, &end); + text = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); printf("text captured: %s.\n", text); @@ -1045,8 +981,8 @@ return ret; //I think we need to go back two because the loop - if(gBack && !gNext) - q = q->prev->prev; + //if(gBack && !gNext) + //q = q->prev->prev; break; }
Attachment:
pgpSG3zKjQgGJ.pgp
Description: PGP signature