home *** CD-ROM | disk | FTP | other *** search
- Late Night's Top Ten X11 Questions
-
- Dave Lemke (lemke@ncd.com)
- Stuart Marks (smarks@sun.com)
-
- 1. Why doesn't my program draw anything? I create the window and draw into
- it, but it's always blank.
-
- In order to get a window on the screen, you must map it first, using the
- XMapWindow() call. Drawing into a window and then mapping it won't work
- in most cases.
-
- 1a. But I do map the window before drawing into it, and the window is still
- blank.
-
- The problem here is that if the window is a child of the root window,
- XMapWindow() doesn't actually map the window; it sends a message to the
- window manager asking it to map the window. If you having drawing
- requests right after the XMapWindow() call, they will probably be
- processed before the window manager has actually mapped the window. In
- order to get around this delayed mapping effect, you must wait for an
- Exposure event from the server. This event indicates that your window is
- on the screen and ready to receive graphics. In general, you should
- always draw in response to Exposure events.
-
- 2. Why does my program display in inverse-video on some servers?
-
- You're assuming that 1 is black and 0 is white or vice-versa. The
- relationship between pixels 0 and 1 and the colors black and white is
- implementation-dependent. They may be reversed, or they may not even
- correspond to black and white at all. For instance, an 8-bit grayscale
- server might choose to have 0 be black and 255 be white. If you want to
- draw in black and white, set the foreground and background pixels in the
- GC using BlackPixel() and WhitePixel() macros instead of 0 and 1. This
- will help ensure that your application is portable amongst different
- servers.
-
- 3. Can I get the background pixel/pixmap of a window using
- GetWindowAttributes?
-
- No. Once set, the background pixel or pixmap of a window cannot be
- re-read by clients. The reason for this is that a client can create a
- pixmap, set it to be the background pixmap of a window, and then free the
- pixmap. The window keeps this background, but the pixmap itself is
- destroyed. If you're sure a window has a background pixel (not a
- pixmap), you can use XClearArea() to clear a region to the background
- color and then use XGetImage() to read back that pixel. However, this
- action alters the contents of the window, and it suffers from race
- conditions with exposures.
-
- 4. Why doesn't my program get keystrokes? I select input for
- KeyPress events, but my program never gets them. (Alternatively,
- my program works under uwm, but not under ...)
-
- The window manager controls how the input focus is transferred from one
- window to another. In order to get keystrokes, your program must ask the
- window manager for the input focus. To do this, you must set up what are
- called "hints" for the window manager. If your applications is
- Xlib-based, you can use something like the following:
-
- XWMHints wmhints;
- ...
- wmhints.flags = InputHint;
- wmhints.input = True;
- XSetWMHints(dpy, window, &hints)
-
- If your application is based on the Xt Intrinsics, you can use something
- like the following:
-
- Arg arglist[MAXARGS];
- Cardinal nargs = (Cardinal) 0;
- ...
- XtSetArg(arglist[nargs++], XtNinput, TRUE);
- ...
- XtCreatePopupShell(...);
-
- 5. I encountered a breakpoint when I was debugging a program, and now
- everything is hung. I can still move the mouse around on the screen,
- but I can't type anything or get any mouse clicks to do anything. HELP!
-
- The debugger stopped your program while it was in the middle of what is
- called a "grab". There are various flavors of grabs, but the important
- effect of all of them is that the grabbing client gets serviced at the
- expense of other clients in the system. This kind of feature is
- necessary for doing highly interactive things like pop-up menu tracking.
-
- The problem arises because the program you're debugging grabbed some
- server resource, such as the keyboard, and then hit a breakpoint. The
- debugger is sharing the same resource with the debugged program, which
- has grabbed the keyboard away from the debugger. You can't type
- debugger commands to continue the program, and thus you're stuck.
-
- To get around this problem, you might try to iconify the debugged
- program's window by using the mouse or the keyboard, whichever isn't
- grabbed. When the window goes iconic, any grabs on that window will be
- deactivated by the server.
-
- If the debugged program is in the middle of a server grab, you're really
- stuck. A server grab grabs *all* of the server's resources. Thus, you
- have to attack the problem by going outside of the server. Killing the
- debugged program and its debugger will release the grab and get you
- unstuck, but you obviously can't continue debugging. You might also try
- making a special debugging-mode option to your program so that it doesn't
- grab the server while you're debugging it. If you can't do that, your
- only choice is to debug the offending program from somewhere outside the
- server it's displaying on, e.g. another workstation or a terminal. If
- you're running X11/NeWS from Sun, you can run a SunView shelltool on top
- of the server; it will be unaffected by server grabs.
-
- 6. How do I do XOR drawing to work properly? It doesn't work at all on some
- servers, and I get funny colors on other servers.
-
- It depends on what you mean by "properly." For the most part, when you
- do XOR drawing, you want to do some transient animation that won't
- disturb the contents of the window. You can do this with XOR because the
- first XOR operation will change the contents to something different, and
- then the second XOR operation will restore the original contents. The
- trick is to set up the GC source pixel so that the "something different"
- contrasts properly with the surroundings.
-
- Confusion arises because XOR drawing uses the GC foreground field as the
- source pixel for the XOR operation. If you use your actual foreground
- pixel as the source for XOR, the result will probably be something off in
- a random section of whatever colormap is installed. Unless you've set up
- and installed your own colormap, the color you end up with will be some
- unlikely value over which you don't have any control.
-
- What's often appropriate is to interchange the foreground color with the
- background color. If your graphics has the concept of a foreground and a
- background, you can do XOR animation that switches foreground and
- background by setting the GC foreground pixel to the XOR of the
- foreground and background pixels. In C, this would be
-
- XGCValues gcvalues;
- gcvalues.foreground = fgpixel ^ bgpixel;
- XChangeGC(dpy,gc,GCForeground,&gcvalues);
-
- For monochrome graphics, you can use
-
- gcvalues.foreground =
- BlackPixel(dpy,DefaultScreen(dpy))^WhitePixel(dpy,DefaultScreen(dpy));
-
- 7. I create and draw into a pixmap, but when I copy it to the screen with
- XCopyArea, I get nothing but garbage.
-
- The initial contents of pixmaps is undefined. This means that most
- servers will allocate the memory and leave around whatever happens to be
- there -- which is usually garbage. You probably want to clear the pixmap
- first using XFillRectangle() with an alu function of GXcopy and a
- foreground pixel of whatever color you want as your background (or 0L
- if you are using the pixmap as a mask).
-
- 8. My color program always fails on XAllocColorCells(). But it works on
- other servers.
-
- Your program is assuming that the default colormap for the screen is a
- dynamic one, that is, one out of which you can allocate nonshared color
- cells via XAllocColorCells(). Some servers have a static colormap as
- their default colormap, so XAllocColorCells() will fail.
-
- You have several alternatives. One possibility is to change your program
- to use XAllocColor(). You won't be able to alter the color once you've
- allocated it, but you may not have needed to do that in the first place.
- You should use XAllocColor() in preference to XAllocColorCells() if you
- simply want to get colors on the screen. The reason is that
- XAllocColor() allows the same colors to be shared amongst different
- clients.
-
- If you really need to allocate and change colormap cells, then you still
- need to use XAllocColorCells() or XAllocColorPlanes(). For these calls
- to work, you must search the server's visual list for a visual that
- supports dynamic colormaps. Then, you must create a colormap against
- this visual and allocate colors out of this colormap. If the server
- doesn't have any dynamic visuals, your program simply won't work on this
- server. If you successfully create and use your own dynamic colormap,
- you'll also have to create a window using the same visual and set that
- window's colormap attribute to be your newly created colormap. Don't
- forget to set up WM_COLORMAP_WINDOWS so the window manager can install
- your colormap.
-
- 9. My program worked fine in R3, but fails in X11R4 with an error in
- ChangeWindowAttributes. Also, my Andrew and Interviews code stopped
- working with the same error.
-
- A likely problem is the value given to a window's do_not_propagate mask.
- R3 allowed bogus values to be set, and early version of both Andrew and
- Interviews did just that. X11R4 and several productized servers catch
- this error and complain. The events that can be suppressed are:
-
- KeyPress, KeyRelease, ButtonPress, ButtonRelease, PointerMotion,
- ButtonMotion and Button[1-5]Motion
-
- 10. I set my windows to have BackingStore, yet they still get exposures.
-
- There are several things that can be going on here. The most
- important thing to remember is that backing store is a hint.
- You may have asked for backing store on your window, but the server may
- not have enough memory to service your request. If this is the case,
- the server will go ahead and create and window without backing store,
- and then send you an Exposure event to tell you to draw into it.
-
- Other behavior that could possibly be counterintuitive is that, if you
- create a window with BackingStore == Always, you will get an Exposure
- event as soon as you create the window. The server does this to let you
- know that the initial contents of the window need to be filled. It does
- this even before you have mapped the window.
-
- Some servers will throw away backing store if they start running out of
- memory. A window may start out with backing store, but then have it
- thrown away by the server because of a memory shortage. This window
- will then start getting Exposure events.
-
- Another possibility is a window manager with a 'Refresh' function. Some
- window managers implement this function by doing a ClearArea with the
- Exposure flag set. This will force the server the send an Exposure
- event, even if the window still has backing store.
-
- The bottom line is that clients must *always* be prepared to repaint
- their windows in response to Exposure events. Backing store is a hint,
- and it is only useful to reduce the number of Exposures on the window;
- it doesn't guarantee that none will ever occur. If you need to keep an
- image in the server, but not on the screen, use pixmaps.
-
- [@(#)answers.txt 1.3 89/12/15]
-