rusty@GARNET.BERKELEY.EDU (10/07/88)
WorkSpace widget: I don't understand how it does redrawing when it is uncovered (expose events). I'm writing an HP toolkit front-end to metafont and metafont is essentially a "black box" with stubs for doing graphic output and I'm writing toolkit code to glue onto these stubs. The critical point to understand is that I can't use XtMainLoop, so whenever metafont calls one of the drawing routines I have them call my routine mf_x11_events which checks for any pending events and deals with them: static void mf_x11_events() { XEvent event; while (XtPending()) { XtNextEvent(&event); XtDispatchEvent(&event); } } Therefore, whenever metafont isn't calling any of the graphics output routines no X events should be getting handled. My test metafont file draws a character and then does a "readstring" which is a metafont primitive to read a string from standard input. While readstring is waiting for me to type something we're (stuck) in metafont and mf_x11_events can't get called. And yet if I pop up a window manager menu over metafont's window the image does get redrawn. Who is doing the redrawing since I'm not? On the other hand, the workspace widget is inside of a ScrolledWindow widget, and its scroll bars don't respond while readstring is waiting for me to type something. It seems as if the workspace widget is magically redrawing itself. The 2nd question about the WorkSpace widget regards the best way to update the widget. I do my own "backing store". The once-only set up code creates a pixmap thusly: mf_pixmap = XCreatePixmap(mf_display, XtWindow(mf_wg_wspace), WSPACE_WIDTH, WSPACE_HEIGHT, DefaultDepth(mf_display, DefaultScreen(mf_display))); My code scribbles directly on the workspace widget's window and also on the pixmap (which is the same size): XDrawLine(mf_display, XtWindow(mf_wg_wspace), mf_gc, col, (int) row, (int) (*tvect-1), (int) row); XDrawLine(mf_display, mf_pixmap, mf_gc, col, (int) row, (int) (*tvect-1), (int) row); (tvect, col, and row are coming from metafont.) Then, when I get a resize or expose event I just set the pixmap as the background: static void mf_x11_expose(wg, client_data, call_data) Widget wg; caddr_t client_data; caddr_t call_data; /* unused */ { Arg args[1]; XtSetArg(args[0], XtNbackgroundPixmap, (Pixmap) client_data); XtSetValues(wg, args, 1); } This seems to be very fast. On my slow-poke SUN 3/50 it's virtually instantaneous. It occured to me that perhaps this method isn't very efficent (even though it is fast) so I tried doing a copy area: static void mf_x11_expose(wg, client_data, call_data) Widget wg; caddr_t client_data; caddr_t call_data; { XRectangle rect; XClipBox((Region) call_data, &rect); XCopyArea(mf_display, (Pixmap) client_data, XtWindow(wg), mf_gc, rect.x, rect.y, rect.width, rect.height, rect.x, rect.y); } This is noticably slower. Why is that? What is setting the backgroundPixmap doing that makes it faster? ScrolledWindow widget: Is there any way to make it resizable? If I put it inside a form widget or put a form widget inside it (or both) it never gets resized when I resize the window that it is in. Is there a way to make it resizable?