[comp.windows.open-look] Xview Panel List Bug.

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. |
***********************************************************************