karln@uunet.uu.net (04/26/91)
There seems to be a bit a bug discussion going on here. While we're at it, I figured I would bounce this one around the net for the heck of it. The bug here is with the panel list function. When the user selects or deselects a line on the panel the notify routines is call with op set to either Select or Deselect. (PANEL_LIST_OP_SELECT/DESELECT). This is fine. The problem is when you deselect in the program a list item that the user selected. When the user selects a different list item, a notification call takes place for the deselect even though it already deselected it from code. This would be no big deal except the reason I deselected the list item was that I just deleted it. So now I am getting a deselect call for an item that does not exist anymore. Ultimitly this cause the program to crash and dump core. Please find attached program example (Thanks Lennart :-). In order to get a core dump (Just what You wanted!), just delete all the items in the list starting from the last to the first. When you delete the last item, slam core dump. As usual, the only way I found to fix it was to xv_destroy the panel_list and rebuild it. Karl Nicholas. ------------------------------------Cut Here-------------- #include <stdio.h> #include <xview/xview.h> #include <xview/panel.h> #define KEY_LIST 1 char *list_strings[] = { "hej", "hopp", "alla", "feta", "nyllen", NULL }; Panel_item buttond; int CurrentLine; void refill_list(button, event) Panel_item button; Event *event; { Panel_item list; int i; list = (Panel_item) xv_get(button, XV_KEY_DATA, KEY_LIST); /* delete all existing rows */ for (i = xv_get(list, PANEL_LIST_NROWS); i > 0; i--) xv_set(list, PANEL_LIST_DELETE, i - 1, NULL); /* fill with new, fresh ones */ for (i = 0; list_strings[i] != NULL; i++) xv_set(list, PANEL_LIST_STRING, i, list_strings[i], NULL); } void delete_list(button, event) Panel_item button; Event *event; { Panel_item list; list = (Panel_item) xv_get(button, XV_KEY_DATA, KEY_LIST); xv_set ( buttond, PANEL_INACTIVE, TRUE, NULL ); xv_set(list, PANEL_LIST_SELECT, CurrentLine, FALSE, NULL ); xv_set(list, PANEL_LIST_DELETE, CurrentLine, NULL); } void list_notifier(list, string, data, op, event) Panel_item list; char *string; caddr_t data; Panel_list_op op; Event *event; { char *strop; int i = 0; switch (op) { case PANEL_LIST_OP_SELECT: strop = "selected"; xv_set ( buttond, PANEL_INACTIVE, FALSE ); break; case PANEL_LIST_OP_DESELECT: strop = "deselected"; xv_set ( buttond, PANEL_INACTIVE, TRUE ); break; default: strop = "<other op>"; break; } for (i = xv_get(list, PANEL_LIST_NROWS) - 1; i >= 0; i--) { if ( xv_get(list, PANEL_LIST_SELECTED, i ) ) { break; } } printf ("%d\n", i ); CurrentLine = i; printf("-- %#x %s\n", string, strop); printf("[%s]\n", string); } main(argc, argv) int argc; char **argv; { Frame frame; Panel panel; Panel_item button, list; char **strp; xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0); frame = xv_create(NULL, FRAME, NULL); panel = xv_create(frame, PANEL, NULL); list = xv_create(panel, PANEL_LIST, PANEL_LIST_DISPLAY_ROWS, 8, PANEL_LIST_WIDTH, 100, PANEL_NOTIFY_PROC, list_notifier, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, NULL); button = xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Refill list", PANEL_NOTIFY_PROC, refill_list, XV_KEY_DATA, KEY_LIST, list, NULL); buttond = xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Delete", PANEL_NOTIFY_PROC, delete_list, PANEL_INACTIVE, TRUE, XV_KEY_DATA, KEY_LIST, list, NULL); for (strp = list_strings; *strp != NULL; strp++) printf("%#x: %s\n", *strp, *strp); xv_main_loop(frame); } ----------------------------Cut Here-------------------- -- *********************************************************************** | Karl Nicholas | A recent Gallop Poll showed that 1 in 6 | | karln%karln@uunet.uu.net | Americans have spoken to a dead person. | ***********************************************************************