neil@yc.estec.nl (Neil Dixon) (02/12/90)
Some months ago I inquired about the correct method of picking from a device independent display list in SBDL, in this newsgroup. Since there is no equivalent of `pick_from_segment' for device independent display lists in SBDL, the answer appears to be that the programmer must perform his/her own traversal of the display list, looking for a hit after each `display_element' call. If somebody already has the code to do this sort of thing, could they send it to me, before I go ahead and implent it myself. At first glance it looks like a very messy thing to have to do. I also see no reason why HP have not implemented this type of thing in SBDL (other than for PHIGS compatibility?), since I've discovered at least one situation in which it's virtually vital for this functionality to exist; namely when running an SBDL application in an X window. When running an application under X, it's necessary to be able to handle resizeing of the window containing the graphics. In this case you normally need to redraw whatever graphics are displayed in the new sized window. The only way Starbase can see this change in size is for the user to reopen the graphics window with a call to `gopen'. However, if you are using a device dependent display list, the display list is destroyed by the gopen call (or is this a bug?) and this then has to be regenerated, which may well be a non-trivial task. The most efficient solution is to use a device independent display list, but if the application is required to perform picking on the resulting graphics output, then the above described functionality is required. Is there anybody at HP prepared to comment on my suggestions; refute my arguments; give me a better solution; etc... -- Neil Dixon <neil@yc.estec.nl> UUCP:...!mcvax!esatst!neil, BITNET: NDIXON@ESTEC Thermal Control & Life Support Division (YC) European Space Research and Technology Centre (ESTEC), Noordwijk, The Netherlands.
stroyan@hpfcso.HP.COM (Mike Stroyan) (02/13/90)
> Some months ago I inquired about the correct method of picking from a > device independent display list in SBDL, in this newsgroup. Since > there is no equivalent of `pick_from_segment' for device independent > display lists in SBDL, the answer appears to be that the programmer > must perform his/her own traversal of the display list, looking for a > hit after each `display_element' call. You can use pick_from_segment with a device independent display list. It may not perform as well as a device dependent display list because the transformation and clipping will be done by the CPU rather than any graphics accelerator box you are using. There is no pick_from_segment equivalent that uses a second file descriptor to do the hit checks. > I also see no reason why HP have not implemented this type of thing in > SBDL (other than for PHIGS compatibility?), since I've discovered at > least one situation in which it's virtually vital for this > functionality to exist; namely when running an SBDL application in an > X window. When running an application under X, it's necessary to be > able to handle resizeing of the window containing the graphics. In > this case you normally need to redraw whatever graphics are displayed > in the new sized window. The only way Starbase can see this change in > size is for the user to reopen the graphics window with a call to > `gopen'. However, if you are using a device dependent display list, > the display list is destroyed by the gopen call (or is this a bug?) No, it's intentional. > and this then has to be regenerated, which may well be a non-trivial task. > The most efficient solution is to use a device independent display > list, but if the application is required to perform picking on the > resulting graphics output, then the above described functionality is required. > Is there anybody at HP prepared to comment on my suggestions; refute > my arguments; give me a better solution; etc... > -- > Neil Dixon <neil@yc.estec.nl> UUCP:...!mcvax!esatst!neil If you had to regenerate a device dependent display list for faster picking, you could use a series of display_segment calls to copy a device independent display list to open segments in a device dependent display list. It would be simple, but rather slow and quite wasteful of memory. Actually, you do not need to close a graphics descriptor to react to an X window resize. You can use set_p1_p2 to scale the graphics to a area smaller than the original window open size. The example program below creates a large window in a motif DrawingArea widget, gopen's the window, then scales down the window and set_p1_p2 area. Since the parent window is always of a normal size, the momentarily large graphics window never appears to be very large. Warning- you probably don't want to ask for backing store in the graphics window until it is scaled down to a reasonable size. Mike Stroyan, stroyan@hpfcla.hp.com # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Mike Stroyan <stroyan@hpstryn> on Mon Feb 12 17:33:48 1990 # # This archive contains: # DRawingArea Makefile drawing_area.c # LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - DRawingArea cat >DRawingArea <<'@EOF' *geometry: 300x300-10+10 *topShadowColor: #7197e5 *bottomShadowColor: #36486e *foreground: black *background: steel blue *Starbase.background: black @EOF chmod 664 DRawingArea echo x - Makefile cat >Makefile <<'@EOF' SHELL=/bin/sh CFLAGS= -g X11LIBS= -lXhp11 -lX11 XTKLIBS= -lXw -lXtR2 XTKLIBS= -lXm -lXt SBLIBS= -ldd98550 -lXwindow -lsb1 -lsb2 SBLIBS= -lddsox11 -lsb1 -lsb2 LPATH=LPATH="/lib:/usr/lib" LDFLAGS= $(SBLIBS) $(XTKLIBS) $(X11LIBS) -lm -lmalloc default: drawing_area # These rules have to be spelled out to put the library "flags" after # the source file. .SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .p .p~ .g .c: $(LPATH) $(CC) -o $* $< $(CFLAGS) $(LDFLAGS) @EOF chmod 644 Makefile echo x - drawing_area.c cat >drawing_area.c <<'@EOF' #include <stdio.h> #include <starbase.c.h> #include <Xm/Xm.h> #include <Xm/Form.h> #include <Xm/PushB.h> #include <Xm/Frame.h> #include <Xm/DrawingA.h> static int display = -1; redraw() { clear_view_surface(display); fill_color(display, 0.3, 0.5, 0.2); ellipse(display, 0.3, 0.4, 0.5, 0.5, 0.7); flush_buffer(display); } void quit(widget, client_data, call_data) Widget widget; caddr_t client_data; caddr_t call_data; { if (display != -1) gclose(display); exit(0); } #define SIZE 2048 void expose(widget, client_data, call_data) Widget widget; caddr_t client_data; XmDrawingAreaCallbackStruct *call_data; { Arg arg[10]; int n; Dimension width, height; if (XtWindow(widget) == NULL) return; /* Wait for the last expose event in this group */ if (call_data->event->xexpose.count != 0) return; if (display == -1) { int temp; /* Call gopen with the window at it's original largest size. */ temp = gopen( make_X11_gopen_string(XtDisplay(widget), XtWindow(widget)), OUTDEV, "sox11", 0); /* Allow the DrawingArea widget to resize. * The client_data parameter contains the address of the * DrawingArea or Frame widget which should be made resizable * now that the gopen has completed. */ n = 0; XtSetArg(arg[n], XmNresizable, True); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetValues(*((Widget *) client_data), arg, n); /* Now tell resize callback that the display is ready. */ display = temp; /* Find the size to draw the image for the first time. */ n = 0; XtSetArg(arg[n], XmNwidth, &width); n++; XtSetArg(arg[n], XmNheight, &height); n++; XtGetValues(widget, arg, n); if (width > SIZE) width = SIZE; if (height > SIZE) height = SIZE; set_p1_p2(display, FRACTIONAL, 0.0, 1.0-height/(double)SIZE, 0.0, width/(double)SIZE, 1.0, 1.0); } redraw(); } void resize(widget, client_data, call_data) Widget widget; caddr_t client_data; caddr_t call_data; { Arg arg[10]; int n; Dimension width, height; if (XtWindow(widget) == NULL) return; if (display == -1) return; /* Sync out the resize before reading the new size. */ XSync(XtDisplay(widget), 0); n = 0; XtSetArg(arg[n], XmNwidth, &width); n++; XtSetArg(arg[n], XmNheight, &height); n++; XtGetValues(widget, arg, n); if (width > SIZE) width = SIZE; if (height > SIZE) height = SIZE; set_p1_p2(display, FRACTIONAL, 0.0, 1.0-height/(double)SIZE, 0.0, width/(double)SIZE, 1.0, 1.0); redraw(); } void drawing_area_input(widget, client_data, call_data) Widget widget; caddr_t client_data; XmDrawingAreaCallbackStruct *call_data; { int valid; float x, y, z; register XEvent *event = call_data->event; printf("Received input callback\n"); if (display == -1) return; dc_to_vdc(display, event->xbutton.x, event->xbutton.y, 0, &x, &y, &z); printf("VDC coordinates are %f, %f, %f\n", x, y, z); } main(argc, argv) int argc; char *argv[]; { Widget toplevel, outer, quit_button, frame, drawing_area; Arg arg[15]; int n; toplevel = XtInitialize("main", "DRawingArea", NULL, 0, &argc, argv); if (argc != 1) { fprintf(stderr, "Usage mistake\n"); exit(1); } n = 0; outer = XtCreateManagedWidget(NULL, xmFormWidgetClass, toplevel, arg, n); n = 0; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNlabelString, XmStringCreate("Quit", XmSTRING_DEFAULT_CHARSET)); n++; quit_button = XtCreateManagedWidget("quit", xmPushButtonWidgetClass, outer, arg, n); XtAddCallback(quit_button, XmNactivateCallback, quit, NULL); n = 0; XtSetArg(arg[n], XmNtopWidget, quit_button); n++; XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(arg[n], XmNshadowThickness, 5); n++; XtSetArg(arg[n], XmNresizable, False); n++; frame = XtCreateManagedWidget("Starbase", xmFrameWidgetClass, outer, arg, n); n = 0; XtSetArg(arg[n], XmNwidth, SIZE); n++; XtSetArg(arg[n], XmNheight, SIZE); n++; drawing_area = XtCreateManagedWidget("Starbase", xmDrawingAreaWidgetClass, frame, arg, n); XtAddCallback(drawing_area, XmNexposeCallback, expose, (caddr_t) &frame); XtAddCallback(drawing_area, XmNresizeCallback, resize, drawing_area); XtAddCallback(drawing_area, XmNinputCallback, drawing_area_input, NULL); XtRealizeWidget(toplevel); XtMainLoop(); } @EOF chmod 644 drawing_area.c exit 0