Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!decwrl!parc!news From: Lovstrand@EuroPARC.Xerox.COM (Lennart Lovstrand) Newsgroups: comp.windows.open-look Subject: List Selection Bug Message-ID: <1991Apr17.222421.19223@parc.xerox.com> Date: 17 Apr 91 22:24:21 GMT Sender: news@parc.xerox.com Organization: Rank Xerox EuroPARC, Cambridge, UK Lines: 130 Argh, I've just come across Yet Another XView Bug -- this time it's the PANEL_LIST selection mechanism that is broken. Try this: Create a PANEL_LIST item with PANEL_CHOOSE_ONE and PANEL_CHOOSE_NONE both true and fill it with a set of strings. Make sure it has a defined notifier. Select a row at least once. Now delete all existing rows with PANEL_LIST_DELETE and insert new ones with PANEL_LIST_INSERT and/or PANEL_LIST_STRING. Select an item and notice how XView tries to first deselect a row from the old set *and from memory that already has been freed*! It doesn't matter if you deselect the last selected row before refilling the list -- the result is the same. I wouldn't normally have been in such a bad mood if it wasn't that I've just wasted eight hours on this stupid little bug wading around in the borderlands between Scheme and C thinking that the problem lay in my Elk/XView interface. And trust me, there are more pleasant ways to spend your time... The only workaround I've come up with so far is to destroy the old list and create a new one every time I want to change its contents. Not exactly elegant. If anyone else out there have any other ideas, I would sure like to know. Here's a sample program for curious and core-less: --Lennart #include #include #include #define KEY_LIST 12345 char *list_strings[] = { "hej", "hopp", "alla", "feta", "nyllen", NULL }; void refill_list(button, event) Panel_item button; Event *event; { Panel_item list; int *block, i; list = 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); /* waste some space... */ block = (int *) malloc(20 * sizeof(int)); for (i = 0; i < 20; i++) block[i] = 0x12345678; /* 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 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; switch (op) { case PANEL_LIST_OP_SELECT: strop = "selected"; break; case PANEL_LIST_OP_DESELECT: strop = "deselected"; break; default: strop = ""; break; } 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); for (strp = list_strings; *strp != NULL; strp++) printf("%#x: %s\n", *strp, *strp); xv_main_loop(frame); } -- --Lennart R _A _ N_ K Rank Xerox EuroPARC, 61 Regent St, Cambridge, UK \/ |_ |_) | | \/ Ackpft, Sun-4/75 at EuroPARC, SunOS Release 4(1.1)-2 /\ |_ | \ |_| /\ TOPS-20 Command processor 7(103)-2 [alpha] E u r o P A R C