stan@portia.Stanford.EDU (Stan Schneider) (01/23/91)
Is anyone out there compiling a more up-to-date XView buglist? The only one I have is the one that comes with OpenWindows. In any case, I think I have a few to add to the list (unbundle the attached shar file for details). If anyone has the motivation to track these down, please let me know. Does anyone know if the XView shipped with OpenWindows 2.0 matches the Aug 3 1990 source release available from MIT? Some of the bugs (notably the spot-help bug) seem to be fixed in the source code I have, but still show up in the shared libraries from Sun. Should I compile the source and hard-link (-Bstatic)? I'd appreciate any experience people can offer. Many apologies for any repeat questions, I've been added to the list recently. TIA, Stan Schneider (stan@sun-valley.stanford.edu) : To unbundle, cut out everything above (&including) the line, put into a file, : and type "sh file" ***************************************************************************** echo x - README cat >README <<'@@@ Fin de README' Openlook Netters: I've worked up some sample programs demonstrating the XView bugs I'm battling with. These all show up on a color IPC running SunOS 4.1 & OpenWin 2.0. -- Stan stan@sun-valley.stanford.edu @@@ Fin de README echo x - makefile cat >makefile <<'@@@ Fin de makefile' ALL = help menu choice rect all: $(ALL) %.o:%.c cc -c -I/usr/openwin/include $*.c %: %.o cc $*.o -o $@ -L/usr/openwin/lib -lxview -lolgx -lX11 -lc shar: shar README makefile *.c help.info > bugs.shar @@@ Fin de makefile echo x - choice.c cat >choice.c <<'@@@ Fin de choice.c' /* ******************************************************************** One simple bug: the strings are truncated. Remove the PANEL_CHOICE_[XY] lines, and the problem goes away. This is not as easy to work around as you might think (a second loop to set the positions seems to work). Any change to the choice item will mess the screen up again. Stan Schneider (stan@sun-valley.stanford.edu) ******************************************************************* */ #include <xview/xview.h> #include <xview/panel.h> Frame frame; Panel panel; void main() { Panel_item choice; int i; char name[32]; frame = xv_create(NULL, FRAME, 0); panel = xv_create(frame, PANEL, 0); choice = xv_create(panel, PANEL_TOGGLE, PANEL_LABEL_STRING, "choice:", 0); for(i=0; i<5; i++) { sprintf(name, "choice%d", i); xv_set(choice, PANEL_CHOICE_X, i, 100+200*i, PANEL_CHOICE_Y, i, 80, PANEL_CHOICE_STRING, i, name, 0); } window_fit(panel); window_fit(frame); window_main_loop(frame); } @@@ Fin de choice.c echo x - help.c cat >help.c <<'@@@ Fin de help.c' /* ******************************************************************** This demos a simple bug in the "spot-help" facility; if it is *first* used over a frame that is later destroyed, it core-dumps if ever used again. This is interesting, since the bug seems to be fixed in the latest version of the MIT code, but not in Sun OpenWindows 2.0?? Stan Schneider (stan@sun-valley.stanford.edu) ******************************************************************* */ #include <xview/xview.h> #include <xview/panel.h> Frame frame, subframe=NULL; Panel panel, subpanel; /*ARGSUSED*/ Notify_value ButtonDoneProc(item, event) Panel_item item; Event *event; { if (subframe != NULL) { xv_set(subframe, FRAME_NO_CONFIRM, TRUE, 0); xv_destroy_safe(subframe); subframe = NULL; } return(NOTIFY_DONE); } void startSub() { subframe = xv_create(frame, FRAME, 0); subpanel = xv_create(subframe,PANEL, PANEL_ACCEPT_KEYSTROKE, TRUE, 0); xv_create(subpanel, PANEL_BUTTON, PANEL_LABEL_STRING, "Press help over this button", XV_HELP_DATA, "help:You_are_gonna_die", PANEL_NOTIFY_PROC, ButtonDoneProc, 0); window_fit(subpanel); window_fit(subframe); xv_set(subframe, XV_SHOW, TRUE, 0); } void main(argc, argv) int argc; char *argv[]; { xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, 0); frame = xv_create(NULL, FRAME, XV_LABEL, "help bug", 0); panel = xv_create(frame, PANEL, PANEL_ACCEPT_KEYSTROKE, TRUE, 0); putenv("HELPPATH=."); xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Don't press this", XV_HELP_DATA, "help:You_are_dead", 0); startSub(); window_fit(panel); window_fit(frame); window_main_loop(frame); } @@@ Fin de help.c echo x - menu.c cat >menu.c <<'@@@ Fin de menu.c' /* ******************************************************************** This demos 6 bugs: 1) pinned menus don't update correctly 2) They take forever to do it. 3) pinned menus that have > 32 items ignore items after #32. 4) Pinup menu windows' titles are truncated. 5) Menus that should fit on the screen are rejected with the message: "XView warning: Menu too large for screen (Command Menu package)" 6) A pin-up that starts single-column does not become multi-column when more items are added, even if its associated pop-up does. I have a better(?) version of this that trashes (xv_destroy's) the menu and completely re-generates it, then re-pins it with menu_default_pin_proc. I didn't send it, because a) it's not the way it should be done, b) it still suffers from 3, 4, 5, and 6, and c) it adds the interesting bug of jumping the cursor if "pop-up pointer jumping" is enabled. The O'Reilly manual admonishes the programmer to "unpin" the menu before updating it, but offers no details on what this means (I tried both setting XV_SHOW and FRAME_CMD_PUSHPIN_IN to FALSE, no change). As a final complaint, the documentation on how to do your own pin-up menus is non-existant. All I could find was a list of pertinent attributes, with no hint on how to use them. Note: although this program always installs or removes items from the end of the list, my application can make much more general modifications. It's really not practical to update the menu in any way other than to delete everything and build it back up. Stan Schneider (stan@sun-valley.stanford.edu) ******************************************************************* */ #include <xview/xview.h> #include <xview/panel.h> Frame frame; Panel panel; Menu choice; char names[100][32]; int NumItems = 0; void InitNames() { int i; for (i=0; i<100; i++) { sprintf(names[i], "Item %d", i); } } void ShowMenu(menu,item) Menu menu; Menu_item item; { register int signo; printf("Selected items: "); for (signo = 0; signo < NumItems; signo++) { item = (Menu_item) xv_get(menu, MENU_NTH_ITEM, signo+2); if((int) xv_get(item, MENU_SELECTED)) { printf("%d ", signo); } } printf("\n"); } void SetOneMenu() { register int signo, i; Frame pinframe; int pinned = FALSE; Menu_item mi; /* Un-pin the window, if necessary. */ pinframe = (Frame) xv_get(choice, MENU_PIN_WINDOW); if (pinframe != NULL) { if ((int) xv_get(pinframe, FRAME_CMD_PUSHPIN_IN) == TRUE) { pinned = TRUE; xv_set(pinframe, FRAME_CMD_PUSHPIN_IN, FALSE, 0); /* xv_set(pinframe, XV_SHOW, FALSE, 0); */ } } /* Trash the old items. */ for(i = (int) xv_get(choice, MENU_NITEMS); i>1; i--) { mi = (Menu_item) xv_get(choice, MENU_NTH_ITEM, i); xv_set(choice, MENU_REMOVE, i, NULL); xv_destroy(mi); } for (signo = 0; signo < NumItems; signo++) { xv_set(choice, MENU_ITEM, MENU_STRING, names[signo], NULL, 0); } if (pinned) { xv_set(pinframe, FRAME_CMD_PUSHPIN_IN, TRUE, 0); /* xv_set(pinframe, XV_SHOW, TRUE, 0); */ } } void setNumItems(slider, value, event) Panel_item slider; int value; Event *event; { NumItems = value; SetOneMenu(); } void main() { frame = xv_create(NULL, FRAME, 0); panel = xv_create(frame, PANEL, 0); choice = xv_create(NULL, MENU_TOGGLE_MENU, MENU_GEN_PIN_WINDOW, frame, "Don't you wish you could read this?", MENU_NOTIFY_PROC, ShowMenu, 0); InitNames(); xv_create(panel, PANEL_ABBREV_MENU_BUTTON, PANEL_LABEL_STRING,"Menu:", PANEL_ITEM_MENU, choice, 0); xv_create(panel, PANEL_SLIDER, PANEL_LABEL_STRING, "NumberOfItems", PANEL_NOTIFY_PROC, setNumItems, 0); window_fit(panel); window_fit(frame); window_main_loop(frame); } @@@ Fin de menu.c echo x - rect.c cat >rect.c <<'@@@ Fin de rect.c' /* ******************************************************************** Bug: You can't get the rect of a window if it's currently iconified. Run this, click "SubFrame", close the main frame, and there's no way to get where the main frame was. P.S.: This may be already covered by some of the many bugs reported for frame_get_rect, it's hard to tell. Stan Schneider (stan@sun-valley.stanford.edu) ******************************************************************* */ #include <xview/xview.h> #include <xview/panel.h> Frame frame, subframe=NULL; Panel panel, subpanel; void printrect(how, r) char *how; Rect *r; { printf("%s: (%d x %d) at %d, %d\n",how, r->r_width,r->r_height,r->r_top,r->r_left); } /* What the hell are all these rects. */ void printRect(frame) Frame frame; { Rect rStorage; Rect *r; if(frame==NULL) return; frame_get_rect(frame, &rStorage); printrect("\nframe_get_rect", &rStorage); if ((int) xv_get(frame, FRAME_CLOSED)) { xv_set(frame, FRAME_CLOSED, FALSE, 0); frame_get_rect(frame, &rStorage); /* <--- Fails */ xv_set(frame, FRAME_CLOSED, TRUE, 0); printrect("\nframe_get_rect after de-iconifying", &rStorage); } r = (Rect *) xv_get(frame, XV_RECT); printrect("XV_RECT", r); r = (Rect *) xv_get(frame, WIN_RECT); printrect("WIN_RECT", r); rStorage.r_left = (int) xv_get(frame, XV_X); rStorage.r_top = (int) xv_get(frame, XV_Y); rStorage.r_width = (int) xv_get(frame, XV_WIDTH); rStorage.r_height = (int) xv_get(frame, XV_HEIGHT); printrect("XV_X,Y,WIDTH,HEIGHT", &rStorage); } void setRect(frame) Frame frame; { Rect rget, rset; Rect *r; int border, header; if(frame==NULL) return; frame_get_rect(frame, &rget); #ifdef SunHasItsActTogether /* This shouldn't move the rect. The rest of this code makes it work. */ frame_set_rect(frame, &rget); } #endif printrect("frame_get_rec", &rget); r = (Rect *) xv_get(frame, XV_RECT); printrect("XV_RECT", r); /* Assumes side borders == bottom border. */ border = (rget.r_width - r->r_width)/2; header = (rget.r_height - r->r_height) - border; rset = rget; rset.r_left += border; rset.r_top += header; printrect("rset", &rset); frame_set_rect(frame, &rset); } void printRects(button, event) Panel_item button; Event *event; { printf("\n\nPrinting rect for frame\n"); printRect(frame); printf("\nPrinting rect for subframe\n"); printRect(subframe); } void setRects(button, event) Panel_item button; Event *event; { printf("\n\nSetting rect for frame\n"); setRect(frame); printf("\nSetting rect for subframe\n"); setRect(subframe); } void startSub() { subframe = xv_create(NULL, FRAME, 0); subpanel = xv_create(subframe,PANEL, 0); xv_create(subpanel, PANEL_BUTTON, PANEL_LABEL_STRING, "Print Rects", PANEL_NOTIFY_PROC, printRects, 0); xv_create(subpanel, PANEL_BUTTON, PANEL_LABEL_STRING, "Set Rects", PANEL_NOTIFY_PROC, setRects, 0); window_fit(subpanel); window_fit(subframe); xv_set(subframe, XV_SHOW, TRUE, 0); } void main() { frame = xv_create(NULL, FRAME, 0); panel = xv_create(frame, PANEL, 0); xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Print Rects", PANEL_NOTIFY_PROC, printRects, 0); xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Set Rects", PANEL_NOTIFY_PROC, setRects, 0); xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Subframe", PANEL_NOTIFY_PROC, startSub, 0); window_fit(panel); window_fit(frame); window_main_loop(frame); } @@@ Fin de rect.c echo x - help.info cat >help.info <<'@@@ Fin de help.info' :You_are_gonna_die Now, press the button itself. Then press help over the other frame's button. Instant SEGV. All you need to do is set help_frame=NULL when the frame is destroyed in help.c # :You_are_dead You'll never see this # @@@ Fin de help.info exit 0