Ошибка сегментирования в списке

Автор blattodea, 02 марта 2024, 03:18:55

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

blattodea

Такая вот беда. Решил я попробовать сделать список по книжице на C и Motif, но при запуске программки, вылезает ошибка — «Ошибка сегментирования». Судя по всему, что-то там с памятью не ладно. Вот такой маленький код списка:

#include <Xm/List.h>

char *months[] = {
"item01", "item02", "item03", "item04", "item05", "item06", "item07",
"item08", "item09", "item10"
};

int

main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, list_w;
XtAppContext app;
Arg args[5];
int i, n = XtNumber (months);
XmStringTable str_list;

XtSetLanguageProc (NULL, NULL, NULL);

toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);

str_list = (XmStringTable) XtMalloc(n * sizeof (XmString *));

for (i = 0; i < n; i++)
str_list[i] = XmStringCreateLocalized (months[i]);

XtSetArg (args[n], XmNvisibleItemCount, n); n++;
XtSetArg (args[n], XmNitemCount, n);
XtSetArg (args[n], XmNitems, str_list);
XtSetArg (args[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++;
XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;

list_w = XmCreateScrolledList (toplevel, "scrollable_list", args, n);
XtManageChild (list_w);

for (i = 0; i < n; i++)
XmStringFree (str_list[i]);
XtFree ((char *) str_list);

XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}

Поскольку у меня самые минимальные познания во всей этой азбуке, ткните пальцем где косяк и помогите, пожалуйста с решением. Насколько я понимаю, баг где-то в области:

str_list = (XmStringTable) XtMalloc(n * sizeof (XmString *));

Graf

Оно может быть всё, что угодно.
Посмотри о чём компилятор выше говорит, там может быть и разгадка.

flanker

не, тут надо что-то вроде "valgrind".

blattodea

#3
Решил проблему, но, если честно, я не вполне понял как. Я просто переписал код заново, добавил новые виджеты и оно само перестало ругаться :biggrin_mini:

Вот код, можно сохранить например, в interface.c, скомпиллить и запустить. Всё работает. Но дальше я не сумею, надо кого-то привлекать для написания логики. Это давняя так сказать, мечта — простейшая морда к таблице SQLite3, которая выводит в список строки с номерами растений в коллекции, умеет создавать новые строки, редактировать их и удалять. В идеале — чтобы всё это она умела выводить в pdf.

Если кто шарит в C, напишите логику и прикрутим к моей поделке, полезное дело сделаем :)

Собственно:

#include <stdio.h>
#include <ctype.h>
#include <Xm/MainW.h>
#include <Xm/RowColumn.h>
#include <Xm/LabelG.h>
#include <Xm/TextF.h>
#include <Xm/MessageB.h>
#include <Xm/FileSB.h>
#include <Xm/ToggleBG.h>
#include <Xm/PushBG.h>
#include <Xm/Form.h>
#include <Xm/CascadeB.h>

/* Data for List */

char *numbers[] = {
"0001 Billbergia magnifica Mez",
"0002 Hechtia rosea É. Morren ex Baker",
"0003 Lutheria glutinosa (Lindl.) Barfuss et W. Till",
"0004 Tillandsia usneoides (L.) L.",
"0005 Deuterocohnia brevifolia (Griseb.) M. A. Spencer et L. B. Sm.",
"0006 Pitcairnia paniculata (Ruiz et Pav.) Ruiz et Pav.",
"0007 Fosterella penduliflora (C. H. Wright) L. B. Sm.",
"0008 Aechmea recurvata (Klotzsch) L. B. Sm. cf. var. recurvata",
"0009 Pitcairnia bromeliifolia L'Hér. var. bromeliifolia",
"0010 Puya mirabilis (Mez) L. B. Sm.",
"0011 Deuterocohnia longipetala (Baker) Mez",
"0012 Dyckia marnier-lapostollei L. B. Sm. var. marnier-lapostollei",
"0013 Puya sp.",
"0014 Fosterella villosula (Harms) L. B. Sm.",
"0015 Fosterella albicans (Griseb.) L. B. Sm.",
"0016 Fosterella rusbyi (Mez) L. B. Sm.",
"0017 Pitcairnia aphelandriflora Lem.",
"0018 Pitcairnia undulata Scheidw.",
"0019 Pitcairnia xanthocalyx Mart.",
"0020 Pitcairnia chiapensis Miranda",
"0021 Pitcairnia grafii Rauh",
"0022 Pitcairnia pungens Kunth var. pungens",
"0023 Pitcairnia orchidifolia Mez",
"0024 Pitcairnia bifrons (Lindl.) Read",
"0025 Pitcairnia sceptrigera Mez",
"0026 Pitcairnia pulverulenta Ruiz et Pav.",
"0027 Pitcairnia flammea Lindl. var. roezlii (É. Morren) L. B. Sm.",
"0028 Pitcairnia caricifolia Mart. ex Schult. et Schult. f. var. caricifolia",
"0029 Pitcairnia flammea Lindl. var. glabrior L. B. Sm.",
"0030 Pitcairnia sp.",
"0031 Pitcairnia integrifolia Ker Gawl.",
"0032 Pitcairnia cf. rubronigriflora Rauh",
"0033 Pitcairnia cf. straminea (Poepp. ex Mez) Mez",
"0034 Pitcairnia funkiae M. A. Spencer et L. B. Sm.",
"0035 Dyckia rariflora Schult. et Schult. f.",
"0036 Deuterocohnia cf. abstrusa (A. Cast.) N. Schuetz",
"0037 Dyckia fosteriana L. B. Sm.",
"0038 Puya alpestris (Poepp.) Gay subsp. alpestris",
"0039 Puya minima L. B. Sm.",
"0040 Tillandsia purpurea Ruiz et Pav.",
"0041 Tillandsia araujei Mez",
"0042 Tillandsia harrisii Ehlers",
"0043 Tillandsia albida Mez et Purpus",
"0044 Tillandsia paucifolia Baker",
"0045 Tillandsia stricta Sol. ex Ker Gawl.",
"0046 Tillandsia paleacea C. Presl",
"0047 Tillandsia filifolia Schltdl. et Cham.",
"0048 Tillandsia bandensis Baker",
"0049 Tillandsia karwinskyana Schult. et Schult. f.",
"0050 Tillandsia recurvata (L.) L.",
"0051 Tillandsia andicola Gillies ex Baker",
"0052 Tillandsia stricta Sol. ex Ker Gawl.",
"0053 Tillandsia cf. recurvata (L.) L.",
"0054 Tillandsia capillaris Ruiz et Pav.",
"0055 Tillandsia cf. streptocarpa Baker",
"0056 Tillandsia virescens Ruiz et Pav.",
"0057 Tillandsia sp.",
"0058 Aechmea fasciata (Lindl.) Baker",
"0059 Cryptanthus reisii Leme",
"0060 Cryptanthus zonatus (Vis.) Beer",
"0061 Pitcairnia heterophylla (Lindl.) Beer",
"0062 Pitcairnia punicea Scheidw.",
"0063 Vriesea saundersii (Carrière) E. Morren",
"0064 Tillandsia araujei Mez",
"0065 Tillandsia seleriana Mez",
"0066 Tillandsia ionantha Planch. var. ionantha",
"0067 Tillandsia fuchsii W. Till f. gracilis W. Till",
"0068 Tillandsia vanhyningii (M. B. Foster) Beutelspacher et García-Martínez",
"0069 Tillandsia caput-medusae E. Morren",
"0070 Tillandsia intermedia Mez",
"0071 Tillandsia retorta Griseb. ex Baker",
"0072 Tillandsia tricholepis Baker",
"0073 Tillandsia myosura Griseb. ex Baker",
"0074 Tillandsia neglecta E. Pereira",
"0075 Tillandsia vernicosa Baker",
"0076 Tillandsia bergeri Mez",
"0077 Tillandsia juncea (Ruiz et Pav.) Poir.",
"0078 Tillandsia bulbosa Hook.",
"0079 Pitcairnia echinata Hook. var. echinata",
"0080 Pitcairnia imbricata (Brongn.) Regel",
"0081 Pitcairnia lanuginosa Ruiz et Pav.",
"0082 Pitcairnia maidifolia (C. Morren) Decne. ex Planch.",
"0083 Tillandsia ariza-juliae L. B. Sm. et Jiménez",
"0084 Tillandsia loliacea Mart. ex Schult. et Schult. f.",
"0085 Lophiarella splendida (A. Rich. ex Duch.) Carnevali et Cetzal",
"0086 Tillandsia albida Mez et Purpus",
"0087 Tillandsia mallemontii Glaz. ex Mez",
"0088 Tillandsia sp.",
"0089 Tillandsia ionantha Planch. var. cf. ionantha",
"0090 Tillandsia albertiana Verv.",
"0091 Tillandsia cf. bergeri Mez",
"0092 Tillandsia tricholepis Baker",
"0093 Tillandsia ×rectifolia C. A. Wiley ex Rauh",
"0094 Tillandsia recurvata (L.) L.",
"0095 Tillandsia aëranthos (Loisel.) L. B. Sm.",
"0096 Tillandsia butzii Mez",
"0097 Lophiaris lanceana (Lindl.) Braem",
"0098 Psychopsis papilio (Lindl.) H. G. Jones",
"0099 Psychopsis krameriana (Rchb. f.) H. G. Jones",
"0100 Tillandsia usneoides (L.) L.",
"0101 Tillandsia usneoides (L.) L.",
"0102 Tillandsia latifolia Meyen var. latifolia",
"0103 Ananas comosus (L.) Merr. var. comosus cv. Pérola",
"0104 Tillandsia marconae W. Till et Vitek",
};

/* Global */

Widget toplevel;

int main(argc, argv)
int argc;
char *argv[];
{
Widget main_w, menubar, menu, widget, rowcol_1, label, toggle_box, btn_1, btn_2, rowcol_2, text, list, form, button_watch, button_ed, button_del;
XtAppContext app;
Arg arg[1];
Arg args[10];
int n = 0;
int i;
    int count = XtNumber (numbers);
    XmStringTable str_list;
XmString file, edit, connect, quit, add, export, help;
void file_cb(), edit_cb(), help_cb(), watch_cb(), nedit_cb(), del_cb();

XtSetLanguageProc (NULL, NULL, NULL);

/* Initialize toolkit and parse command line options. */
toplevel = XtVaAppInitialize (&app, "Linnaeus",
NULL, 0, &argc, argv, NULL, NULL);

/* main window contains a MenuBar and Work area */
main_w = XtVaCreateManagedWidget("main_window", xmMainWindowWidgetClass, toplevel,
XmNwidth, 800,
NULL);

/* Create a simple MenuBar that contains three menus */
file = XmStringCreateLocalized ("File");
edit = XmStringCreateLocalized ("Edit");
menubar = XmVaCreateSimpleMenuBar (main_w, "menubar",
XmVaCASCADEBUTTON, file, 'F',
XmVaCASCADEBUTTON, edit, 'E',
NULL);
XmStringFree (file);
XmStringFree (edit);

/* don't free "help" compound string yet -- reuse it later */

/* Tell the menubar which button is the help menu  */
if (widget = XtNameToWidget (menubar, "button_2"))
XtVaSetValues (menubar, XmNmenuHelpWidget, widget, NULL);

/* First menu is the File menu -- callback is file_cb() */
connect = XmStringCreateLocalized ("Connect...");
quit = XmStringCreateLocalized ("Quit");
XmVaCreateSimplePulldownMenu (menubar, "file_menu", 0, file_cb,
XmVaPUSHBUTTON, connect, 'C', NULL, NULL,
XmVaSEPARATOR,
XmVaPUSHBUTTON, quit, 'Q', NULL, NULL,
NULL);
XmStringFree (connect);
XmStringFree (quit);

/* Second menu is the Edit menu */
add = XmStringCreateLocalized ("Add Number");
export = XmStringCreateLocalized ("Export to PDF");
XmVaCreateSimplePulldownMenu (menubar, "edit_menu", 1, edit_cb,
XmVaPUSHBUTTON, add, 'A', NULL, NULL,
XmVaPUSHBUTTON, export, 'x', NULL, NULL,
NULL);
XmStringFree (add);
XmStringFree (export);

/* get help widget ID to add callback */
help = XtVaCreateManagedWidget ("Help",
xmCascadeButtonWidgetClass, menubar,
XmNmnemonic, 'H',
NULL);
XtAddCallback (help, XmNactivateCallback, help_cb, NULL);

/* Tell the menubar which button is the help menu  */
XtSetArg (args[n], XmNmenuHelpWidget, help);
n++;
XtSetValues (menubar, args, n);

XtManageChild (menubar);

/* Work area */

rowcol_1 = XtVaCreateWidget ("rowcol",
xmRowColumnWidgetClass, main_w,
NULL);

rowcol_2 = XtVaCreateWidget ("rowcol_2",
xmRowColumnWidgetClass, rowcol_1,
XmNorientation, XmHORIZONTAL,
NULL);

label = XtVaCreateManagedWidget ("Number Search:",
xmLabelGadgetClass, rowcol_2,
XmNorientation, XmHORIZONTAL,
NULL);

XtSetArg (args[n], XmNorientation, XmHORIZONTAL); n++;
toggle_box = XmCreateSimpleRadioBox (rowcol_2, "radio_box", args, n);
   
btn_1 = XtVaCreateManagedWidget ("By Number",
xmToggleButtonGadgetClass, toggle_box,
XmNset, True,
NULL);
btn_2 = XtVaCreateManagedWidget ("By Taxon",
xmToggleButtonGadgetClass, toggle_box,
NULL);

XtManageChild (toggle_box);

XtManageChild (rowcol_2);

text = XtVaCreateManagedWidget ("search_text",
xmTextFieldWidgetClass, rowcol_1,
XmNtraversalOn, True,
NULL);

/* List of Items */

str_list = (XmStringTable) XtMalloc (count * sizeof (XmString *));

for (i = 0; i < count; i++)
str_list[i] = XmStringCreateLocalized (numbers[i]);

/* Widget List */
XtSetArg (args[n], XmNheight, 300); n++;
XtSetArg (args[n], XmNvisibleItemCount, 10); n++;
XtSetArg (args[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++;
XtSetArg (args[n], XmNscrollBarDisplayPolicy, XmSTATIC); n++;
XtSetArg (args[n], XmNlistSizePolicy, XmCONSTANT); n++;
XtSetArg (args[n], XmNitems, str_list);  n++;
    XtSetArg (args[n], XmNitemCount, count); n++;
list = XmCreateScrolledList (rowcol_1, "list", args, n);

XtManageChild (list);

for (i = 0; i < n; i++)
XmStringFree (str_list[i]);
XtFree ((XtPointer) str_list);

form = XtVaCreateWidget ("form", xmFormWidgetClass, rowcol_1,
XmNfractionBase, 7,
NULL);

button_watch = XtVaCreateManagedWidget ("Watch",
xmPushButtonGadgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 1,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 2,
XmNshowAsDefault, True,
//XmNsensitive, False,
//XmNshowAsDefault, False,
XmNdefaultButtonShadowThickness, 1,
XmNmnemonic, 'W',
XmNheight, 30,
NULL);

XtAddCallback (button_watch, XmNactivateCallback, watch_cb, NULL);

button_ed = XtVaCreateManagedWidget ("Edit",
xmPushButtonGadgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 3,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 4,
XmNshowAsDefault, True,
//XmNsensitive, False,
//XmNshowAsDefault, False,
XmNdefaultButtonShadowThickness, 1,
XmNmnemonic, 't',
XmNheight, 30,
NULL);

XtAddCallback (button_ed, XmNactivateCallback, nedit_cb, NULL);

button_del = XtVaCreateManagedWidget ("Delete",
xmPushButtonGadgetClass, form,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 5,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 6,
XmNshowAsDefault, True,
//XmNsensitive, False,
//XmNshowAsDefault, False,
XmNdefaultButtonShadowThickness, 1,
XmNmnemonic, 'D',
XmNheight, 30,
NULL);

XtAddCallback (button_del, XmNactivateCallback, del_cb, NULL);

XtManageChild (form);

XtManageChild (rowcol_1);

XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}

void
file_cb(widget, client_data, call_data)
Widget widget;        /* menu item that was selected */
XtPointer client_data;  /* the index into the menu */
XtPointer call_data;  /* unused */
{
static Widget dialog; /* make it static for reuse */

int item_no = (int) client_data;
XmString xm_string;
extern void quit_cb();
Arg args[5];
XtSetArg (args[0], XmNmessageString, xm_string);
int n = 0;
char *text = (char *) client_data;

xm_string = XmStringCreateLocalized ("Are you sure you want to quit?");

XtSetArg (args[n], XmNautoUnmanage, True); n++;

if (item_no == 1) {
XtSetArg (args[n], XmNmessageString, xm_string); n++;
dialog = XmCreateQuestionDialog (toplevel, "quit_sel", args, n);
XmStringFree(xm_string);
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtAddCallback (dialog, XmNokCallback, quit_cb, NULL);

} else {
dialog = XmCreateFileSelectionDialog (toplevel, "file_sel", NULL, 0);
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtAddCallback (dialog, XmNcancelCallback, XtDestroyWidget, NULL);
}

XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}

/* callback routines for Quit dialog */
void
quit_cb (dialog, client_data, call_data)
Widget dialog;
XtPointer client_data;
XtPointer call_data;
{
exit(0);
}

void
edit_cb(widget, client_data, call_data)
Widget widget;        /* menu item that was selected */
XtPointer client_data;  /* the index into the menu */
XtPointer call_data;  /* unused */
{
char *labels[] = { "Number:", "Taxon:", "Type:", "Year:", "Source:" };

int item_no = (int) client_data;
Widget rowcol, label, text;
XmString t = XmStringCreateLocalized ("Enter file name for PDF result:");
Arg args[5];
int n = 0;
int i;

static Widget dialog; /* make it static for reuse */

if (item_no == 1) {

XtSetArg (args[n], XmNselectionLabelString, t); n++;
XtSetArg (args[n], XmNautoUnmanage, False); n++;
dialog = XmCreatePromptDialog (toplevel, "export", args, n);
XmStringFree (t); /* always destroy compound strings when done */

/* If the user selects cancel, just destroy the dialog */
XtAddCallback (dialog, XmNcancelCallback, XtDestroyWidget, NULL);

/* No help is available... */
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));

} else {

/* "Open" was selected.  Create a Motif FileSelectionDialog w/callback */
if (!dialog) {

XtSetArg (args[n], XmNautoUnmanage, False); n++;
XtSetArg (args[n], XmNwidth, 600); n++;
dialog = XmCreatePromptDialog (toplevel, "add number", args, n);

rowcol = XtVaCreateManagedWidget ("rowcolumn",
xmRowColumnWidgetClass, dialog,
XmNorientation, XmVERTICAL,
NULL);

/* If the user selects cancel, just destroy the dialog */
XtAddCallback (dialog, XmNcancelCallback, XtDestroyWidget, NULL);

/* No help is available... */
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
   
for (i = 0; i < XtNumber (labels); i++) {
label =  XtVaCreateManagedWidget (labels[i],
xmLabelGadgetClass, rowcol,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 3,
XmNalignment, XmALIGNMENT_END,
NULL);
text = XtVaCreateManagedWidget ("text",
xmTextFieldWidgetClass, rowcol,
XmNtraversalOn, True,
XmNrightAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 4,
NULL);
}
}
}
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}

void
help_cb(widget, client_data, call_data)
Widget widget;     
XtPointer client_data;
XtPointer call_data; 
{
String *context_help[] = {
"MANAGER OF BOTANICAL COLLECTIONS ''LINNAEUS'' 0.0.1\nMarch 9, 2024\n\nDevelopers: Max,...\nLicense: LGPL v2.1",
NULL
};

static Widget dialog, text;

if (!dialog) {
Arg args[10];
int n = 0;
int i;

dialog = XmCreateInformationDialog (toplevel, "help_dialog", NULL, 0);

XtSetArg (args[n], XmNrows, 12); n++;
XtSetArg (args[n], XmNcolumns, 70); n++;
XtSetArg (args[n], XmNeditable, False); n++;
XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
XtSetArg (args[n], XmNscrollHorizontal, False); n++;
XtSetArg (args[n], XmNwordWrap, True); n++;
XtSetArg (args[n], XmNautoUnmanage, True); n++;
XtSetArg (args[n], XmNvalue, *context_help); n++;
text = XmCreateScrolledText (dialog, "help_text", args, n);
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_MESSAGE_LABEL));

XtManageChild (text);
}
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}

void
watch_cb(widget, client_data, call_data)
Widget widget;     
XtPointer client_data;
XtPointer call_data; 
{
String *context_watch[] = {
"Number: 0005\nTaxon: Deuterocohnia brevifolia (Griseb.) M. A. Spencer et L. B. Sm.\nType: plant\nYear: 2022\nSource: Russian Academy of Sciences Vladimir Komarov Botanical Institute's Botanical Garden of Peter the Great",
NULL
};

static Widget dialog, text;

if (!dialog) {
Arg args[10];
int n = 0;
int i;

dialog = XmCreateInformationDialog (toplevel, "watch_dialog", NULL, 0);

XtSetArg (args[n], XmNrows, 12); n++;
XtSetArg (args[n], XmNcolumns, 70); n++;
XtSetArg (args[n], XmNeditable, False); n++;
XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg (args[n], XmNcursorPositionVisible, False); n++;
XtSetArg (args[n], XmNscrollHorizontal, False); n++;
XtSetArg (args[n], XmNwordWrap, True); n++;
XtSetArg (args[n], XmNautoUnmanage, True); n++;
XtSetArg (args[n], XmNvalue, *context_watch); n++;
text = XmCreateScrolledText (dialog, "watch_text", args, n);
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_CANCEL_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_MESSAGE_LABEL));

XtManageChild (text);
}
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}

void
nedit_cb(widget, client_data, call_data)
Widget widget;        /* menu item that was selected */
XtPointer client_data;  /* the index into the menu */
XtPointer call_data;  /* unused */
{
char *labels[] = { "Number:", "Taxon:", "Type:", "Year:", "Source:" };

Widget rowcol, label, text;
Arg args[5];
int n = 0;
int i;

static Widget dialog; /* make it static for reuse */

/* "Open" was selected.  Create a Motif FileSelectionDialog w/callback */
if (!dialog) {

XtSetArg (args[n], XmNautoUnmanage, False); n++;
XtSetArg (args[n], XmNwidth, 600); n++;
dialog = XmCreatePromptDialog (toplevel, "edit number", args, n);

rowcol = XtVaCreateManagedWidget ("rowcolumn",
xmRowColumnWidgetClass, dialog,
XmNorientation, XmVERTICAL,
NULL);

/* If the user selects cancel, just destroy the dialog */
XtAddCallback (dialog, XmNcancelCallback, XtDestroyWidget, NULL);

/* No help is available... */
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_TEXT));
XtUnmanageChild (XmSelectionBoxGetChild (dialog, XmDIALOG_SELECTION_LABEL));
   
for (i = 0; i < XtNumber (labels); i++) {
label =  XtVaCreateManagedWidget (labels[i],
xmLabelGadgetClass, rowcol,
XmNtopAttachment, XmATTACH_FORM,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_POSITION,
XmNrightPosition, 3,
XmNalignment, XmALIGNMENT_END,
NULL);
text = XtVaCreateManagedWidget ("text",
xmTextFieldWidgetClass, rowcol,
XmNtraversalOn, True,
XmNrightAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_POSITION,
XmNleftPosition, 4,
NULL);
}
}
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}

void
del_cb(widget, client_data, call_data)
Widget widget;        /* menu item that was selected */
XtPointer client_data;  /* the index into the menu */
XtPointer call_data;  /* unused */
{
static Widget dialog; /* make it static for reuse */

int item_no = (int) client_data;
XmString xm_string;
extern void quit_cb();
Arg args[5];
XtSetArg (args[0], XmNmessageString, xm_string);
int n = 0;
char *text = (char *) client_data;

xm_string = XmStringCreateLocalized ("Really delete?");

XtSetArg (args[n], XmNautoUnmanage, True); n++;

XtSetArg (args[n], XmNmessageString, xm_string); n++;
dialog = XmCreateQuestionDialog (toplevel, "del_sel", args, n);
XmStringFree(xm_string);
XtUnmanageChild (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON));
XtAddCallback (dialog, XmNokCallback, del_cb, NULL);

XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}