Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hplabs!hpfcso!stroyan From: stroyan@hpfcso.HP.COM (Mike Stroyan) Newsgroups: comp.sys.hp Subject: Re: Picking from Device Independent Starbase Display List Message-ID: <7370081@hpfcso.HP.COM> Date: 13 Feb 90 00:53:28 GMT References: <1059@esatst.yc.estec.nl> Organization: Hewlett-Packard, Fort Collins, CO, USA Lines: 289 > 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 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 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 #include #include #include #include #include #include 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