home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!bone.think.com!paperboy.osf.org!june.osf.org!dbl
- From: dbl@osf.org (David Lewis)
- Newsgroups: comp.windows.x,news.answers,comp.answers
- Subject: comp.windows.x Frequently Asked Questions (FAQ) 7/7
- Followup-To: poster
- Date: 2 Oct 1996 20:16:57 GMT
- Organization: Open Software Foundation
- Lines: 1160
- Approved: news-answers-request@MIT.Edu
- Distribution: world
- Expires: Sun, 27 Oct 1996 00:00:00 GMT
- Message-ID: <52uijp$bs0@paperboy.osf.org>
- Reply-To: faq%craft@uunet.uu.net (X FAQ maintenance address)
- NNTP-Posting-Host: june.osf.org
- Summary: useful information about the X Window System
- Xref: senator-bedfellow.mit.edu comp.windows.x:110959 news.answers:83419 comp.answers:21530
-
- Archive-name: x-faq/part7
- Last-modified: 1996/09/26
-
- ----------------------------------------------------------------------
- Subject: 149) I'm writing a widget and can't use a float as a resource value.
-
- Float resources are not portable; the size of the value may be larger than
- the size of an XtPointer. Try using a pointer to a float instead; the Xaw
- Scrollbar float resources are handled in this way.
-
- ----------------------------------------------------------------------
- Subject: 150) Is this a memory leak in the X11R4 XtDestroyWidget()?!
-
- Yes. This is the "unofficial" fix-19 for the X11R4 Destroy.c:
-
- *** Destroy.c.1.37 Thu Jul 11 15:41:25 1991
- --- lib/Xt/Destroy.c Thu Jul 11 15:42:23 1991
- ***************
- *** 1,4 ****
- --- 1,5 ----
- /* $XConsortium: Destroy.c,v 1.37 90/09/28 10:21:32 swick Exp $ */
- + /* Plus unofficial patches in revisions 1.40 and 1.41 */
-
- /***********************************************************
- Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
- ***************
- *** 221,239 ****
- */
-
- int i = 0;
- ! DestroyRec* dr = app->destroy_list;
- while (i < app->destroy_count) {
- if (dr->dispatch_level >= dispatch_level) {
- Widget w = dr->widget;
- if (--app->destroy_count)
- bcopy( (char*)(dr+1), (char*)dr,
- ! app->destroy_count*sizeof(DestroyRec)
- );
- XtPhase2Destroy(w);
- }
- else {
- i++;
- - dr++;
- }
- }
- }
- --- 222,245 ----
- */
-
- int i = 0;
- ! DestroyRec* dr;
- while (i < app->destroy_count) {
- +
- + /* XtPhase2Destroy can result in calls to XtDestroyWidget,
- + * and these could cause app->destroy_list to be reallocated.
- + */
- +
- + dr = app->destroy_list + i;
- if (dr->dispatch_level >= dispatch_level) {
- Widget w = dr->widget;
- if (--app->destroy_count)
- bcopy( (char*)(dr+1), (char*)dr,
- ! (app->destroy_count - i) * sizeof(DestroyRec)
- );
- XtPhase2Destroy(w);
- }
- else {
- i++;
- }
- }
- }
-
- [from Donna Converse, converse@x.org]
-
- ----------------------------------------------------------------------
- Subject: 151) Is this a memory leak in the X11R4 deletion of work procs?!
-
- Apparently the X11R4 NextEvent.c`CallWorkProc fails to properly replace
- the work proc record back on the free list correctly.
-
- if (delete) {
- w->next = freeWorkRecs;
- freeWorkRecs = w->next; /* should be =w; */
- }
-
- ----------------------------------------------------------------------
- Subject: 152) Why does the process size of my X programs go up,up,up?
-
- Using "ps" may not show any decrease in memory size after a malloc/free pair.
- With most vendors' implementations of memory managers, the call to free does
- not return memory to the operating system; it is probably maintained on a free
- list for the process. In addition, ps may not be an accurate report of current
- memory usage requirements.
-
- ----------------------------------------------------------------------
- Subject: 153) Are callbacks guaranteed to be called in the order registered?
-
- Although some books demonstrate that the current implementation of Xt happens
- to call callback procedures in the order in which they are registered, the
- specification does not guarantee such a sequence, and supplemental
- authoritative documents (i.e. the Asente/Swick volume) do say that the order
- is undefined. Because the callback list can be manipulated by both the
- widget and the application, Xt cannot guarantee the order of execution.
-
- In general, the callback procedures should be thought of as operating
- independently of one another and should not depend on side-effects of other
- callbacks operating; if a seqence is needed, then the single callback to be
- registered can explicitly call other functions necessary.
-
- [4/92; thanks to converse@x.org]
-
- ----------------------------------------------------------------------
- Subject: 154) Why doesn't XtDestroyWidget() actually destroy the widget?
-
- XtDestroyWidget() operates in two passes, in order to avoid leaving dangling
- data structures; the function-call marks the widget, which is not actually
- destroyed until your program returns to its event-loop.
-
- ----------------------------------------------------------------------
- Subject: 155) How can I open multiple displays with Xt?
-
- Just open each display separately with XOpenDisplay or XtOpenDisplay. The
- latter is much simpler, since the Xt main loop will automatically poll all
- displays for events (if you put them all in the same application context).
-
- However, consult the skeleton X programs for multiple-displays to see how to
- handle the breaking of one display connection; normally Xlib issues an XIO
- error and then calls exit().
-
- [Thanks to Ken Lee (kenton@rahul.net); 4/95]
-
- ----------------------------------------------------------------------
- Subject: 156) How do I query the user synchronously using Xt?
-
- It is possible to have code which looks like this trivial callback,
- which has a clear flow of control. The calls to AskUser() block until answer
- is set to one of the valid values. If it is not a "yes" answer, the code drops
- out of the callback and back to an event-processing loop:
-
- void quit(Widget w, XtPointer client, XtPointer call)
- {
- int answer;
- answer = AskUser(w, "Really Quit?");
- if (RET_YES == answer)
- {
- answer = AskUser(w, "Are You Really Positive?");
- if (RET_YES == answer)
- exit(0);
- }
- }
-
- A more realistic example might ask whether to create a file or whether
- to overwrite it.
- This is accomplished by entering a second event-processing loop and
- waiting until the user answers the question; the answer is returned to the
- calling function. That function AskUser() looks something like this, where the
- Motif can be replaced with widget-set-specific code to create some sort of
- dialog-box displaying the question string and buttons for "OK", "Cancel" and
- "Help" or equivalents:
-
- int AskUser(w, string)
- Widget w;
- char *string;
- {
- int answer=RET_NONE; /* some not-used marker */
- Widget dialog; /* could cache&carry, but ...*/
- Arg args[3];
- int n = 0;
- XtAppContext context;
-
- n=0;
- XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
- XmSTRING_DEFAULT_CHARSET)); n++;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
- dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
- XtAddCallback(dialog, XmNokCallback, response, &answer);
- XtAddCallback(dialog, XmNcancelCallback, response, &answer);
- XtAddCallback(dialog, XmNhelpCallback, response, &answer);
- XtManageChild(dialog);
-
- context = XtWidgetToApplicationContext(w);
- while ((RET_NONE == answer) || XtAppPending(context))
- XtAppProcessEvent (context, XtIMAll);
- XtDestroyWidget(dialog); /* blow away the dialog box and shell */
- return answer;
- }
-
- The dialog supports three buttons, which are set to call the same
- function when tickled by the user. The variable answer is set when the user
- finally selects one of those choices:
-
- void response(w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- int *answer = (int *) client;
- XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
- switch (reason->reason) {
- case XmCR_OK:
- *answer = RET_YES; /* some #define value */
- break;
- case XmCR_CANCEL:
- *answer = RET_NO;
- break;
- case XmCR_HELP:
- *answer = RET_HELP;
- break;
- default:
- return;
- }
- }
-
- and the code unwraps back to the point at which an answer was needed and
- continues from there.
-
- Note that modifications are needed to handle receiving WM_DELETE_WINDOW on
- the window; possibly WM_DELETE_WINDOW can be handled by setting the "answer"
- variable.
-
- [Thanks to Dan Heller (now argv@z-code.com); note that the code in his book
- caches the dialog but neglects to make sure that the callbacks point to the
- current automatic "answer".]
-
- ----------------------------------------------------------------------
- Subject: 157) How do I determine the name of an existing widget?
- I have a widget ID and need to know what the name of that widget is.
-
- Users of R4 and later are best off using the XtName() function, which
- will work on both widgets and non-widget objects.
-
- If you are still using R3, you can use this simple bit of code to do
- what you want. Note that it depends on the widget's internal data structures
- and is not necessarily portable to future versions of Xt, including R4.
-
- #include <X11/CoreP.h>
- #include <X11/Xresource.h>
- String XtName (widget)
- Widget widget; /* WILL work with non-widget objects */
- {
- return XrmNameToString(widget->core.xrm_name);
- }
-
- [7/90; modified with suggestion by Larry Rogers (larry@boris.webo.dg.com) 9/91]
-
- ----------------------------------------------------------------------
- Subject: 158) Why do I get a BadDrawable error drawing to XtWindow(widget)?
- I'm doing this in order to get a window into which I can do Xlib graphics
- within my Xt-based program:
-
- > canvas = XtCreateManagedWidget ( ...,widgetClass,...) /* drawing area */
- > ...
- > window = XtWindow(canvas); /* get the window associated with the widget */
- > ...
- > XDrawLine (...,window,...); /* produces error */
-
- The window associated with the widget is created as a part of the
- realization of the widget. Using a window id of None ("no window") could
- create the error that you describe. It is necessary to call XtRealizeWidget()
- before attempting to use the window associated with a widget.
- Note that the window will be created after the XtRealizeWidget() call,
- but that the server may not have actually mapped it yet, so you should also
- wait for an Expose event on the window before drawing into it.
-
- ----------------------------------------------------------------------
- Subject: 159) Where can I get documentation on Xaw, the Athena widget set?
-
- Check ftp.x.org in /pub/R5untarred/mit/hardcopy for the originals of
- documentation distributed with X11R5. In R6, see xc/doc/specs/Xaw or
- xc/doc/hardcopy/Xaw.
-
- ----------------------------------------------------------------------
- Subject: 160) What's the difference between actions and callbacks?
-
- Actions and callbacks may be closely tied; the user may click a mouse-button
- in an object's window, causing an action procedure in that particular object
- to be called. As part of its processing of the event, the action procedure
- may inform the application via a callback registered on the object. However,
- callbacks can be given for any reason, including some that don't arise as a
- result of user action; and many actions don't result in any notification to
- the application.
-
- Callbacks generally are a means of interaction between the user interface
- (UI) and some other piece of code interested in the "results"; the interested
- party to which the data is communicated is usually the application's back-end
- functions but may be another widget in a related part of the UI. For
- example, a text widget invokes a callback to say "the user just entered this
- text string; never mind what I had to do to get it or what X events took
- place."
-
- In object-oriented programming terminology, callback lists are messages
- defined by the widget class by which the widget instance notifies another
- entity that something significant has happened to the widget.
-
- Actions, however, constitute a widget's repertoire of internal i/o
- behaviors. Actions are not about results; actions are about "how", not
- "what" gets done. The text widget may define a dozen or two actions which
- define how the user can manipulate the text; the procedures for removing a
- line of text or switching two words can be associated with particular X event
- sequences (and in fact often rely on particular types of events).
-
- Actions are (in OOP terminology) methods of the widget class by which the
- widget responds to some external stimulus (one or more X events).
-
- To avoid confusing yourself on the issue of actions vs. callbacks, try
- thinking of actions defined by an application as methods *of the application*
- -- applications may define actions, as well -- by which the application
- responds to one or more X events (and happens to be handed an object handle
- as part of the method argument list). Similarly, callback handlers registered
- by an application with a widget can be thought of as methods of the
- application which respond to messages from a widget or widgets.
-
- [Thanks to Michael Johnson (michael@maine.maine.edu) and to Kerry Kimbrough]
-
- ----------------------------------------------------------------------
- Subject: 161) How do I simulate a button press/release event for a widget?
-
- You can do this using XSendEvent(); it's likely that you're not setting the
- window field in the event, which Xt needs in order to match to the widget
- which should receive the event.
-
- If you're sending events to your own application, then you can use
- XtDispatchEvent() instead. This is more efficient than XSendEvent() in that
- you avoid a round-trip to the server.
-
- Depending on how well the widget was written, you may be able to call its
- action procedures in order to get the effects you want.
-
- [courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]
-
- ----------------------------------------------------------------------
- Subject: 162) Can I make Xt or Xlib calls from a signal handler?
-
- No. Xlib and Xt have no mutual exclusion for protecting critical sections. If
- your signal handler makes such a call at the wrong time (which might be while
- the function you are calling is already executing), it can leave the library
- in an inconsistent state. Note that the ANSI C standard points out that
- behavior of a signal handler is undefined if the signal handler calls any
- function other than signal() itself, so this is not a problem specific to
- Xlib and Xt; the POSIX specification mentions other functions which may be
- called safely but it may not be assumed that these functions are called by
- Xlib or Xt functions.
-
- Setting a global variable is one of the few permitted operations. You can
- work around the problem by setting a flag in the interrupt handler and later
- checking it with a work procedure or a timer event which has previously been
- added or by using a custom event loop.
-
- R6 Xt has have support for signal handlers; there is a mechanism to set a
- flag in a signal handler, and XtAppNextEvent will notice that the flag has
- been set and call the associated callbacks.
-
- Note: the article in The X Journal 1:4 and the example in the first edition
- of O'Reilly & Associates' Volume 6 are in error.
-
- [Thanks to Pete Ware (ware@cis.ohio-state.edu) and Donna Converse
- (converse@x.org), 5/92]
-
- An alternate solution is to create a pipe and add the read side of the pipe
- as an input event with XtAppAddInput; then write a byte to the write side of
- the pipe with your signal handler (write is re-entrant). The callback for the
- read side of the pipe reads the byte and does the actual processing that you
- intended. You may want the byte to be the signal number unless your callback
- handles only one kind.
-
- [Thanks to Steve Kappel (stevek@apertus.com)]
-
- ----------------------------------------------------------------------
- Subject: 163)! What are these "Xlib: unexpected async reply" errors?
-
- You'll typically get these errors if you are writing a multi-threaded
- application and are making X calls from more than one thread -- one of the
- more common new ways to introduce memory corruption into Xlib (using bogus
- pointers is another, as is mixing up XFree/XtFree/free calls. Even an
- operation as simple as XSendEvent can't be called from a second thread.).
- Prior to X11R6, X doesn't support multi-threading; check the X11R6
- documentation for how to write a threaded application safely with X11R6 and
- later versions of X (including being sure to enable Xlib's multi-thread
- support).
-
- Common widget sets are also unsafe to use except from within one thread. The
- versions of Motif from OSF, for example, offer no support for
- multi-threading.
-
- ----------------------------------------------------------------------
- Subject: 164) What are these "Xlib sequence lost" errors?
-
- You may see these errors if you issue Xlib requests from an Xlib error
- handler, or, more likely, if you make calls which generate X requests to Xt
- or Xlib from a signal handler, which you shouldn't be doing in any case.
-
- ----------------------------------------------------------------------
- Subject: 165) How can my Xt program handle socket, pipe, or file input?
-
- It's very common to need to write an Xt program that can accept input both
- from a user via the X connection and from some other file descriptor, but
- which operates efficiently and without blocking on either the X connection or
- the other file descriptor.
-
- A solution is use XtAppAddInput(). After you open your file descriptor, use
- XtAppAddInput() to register an input handler. The input handler will be
- called every time there is something on the file descriptor requiring your
- program's attention. Write the input handler like you would any other Xt
- callback, so it does its work quickly and returns. It is important to use
- only non-blocking I/O system calls in your input handlers.
-
- Most input handlers read the file descriptor, although you can have an input
- handler write or handle exception conditions if you wish.
-
- Be careful when you register an input handler to read from a disk file. You
- will find that the function is called even when there isn't input pending.
- XtAppAddInput() is actually working as it is supposed to. The input handler
- is called whenever the file descriptor is READY to be read, not only when
- there is new data to be read. A disk file (unlike a pipe or socket) is almost
- always ready to be read, however, if only because you can spin back to the
- beginning and read data you've read before. The result is that your function
- will almost always be called every time around XtAppMainLoop(). There is a
- way to get the type of interaction you are expecting; add this line to the
- beginning of your function to test whether there is new data:
-
- if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) return;
-
- But, because this is called frequently, your application is effectively in a
- busy-wait; you may be better off not using XtAppAddInput() and instead
- setting a timer and in the timer procedure checking the file for input.
-
- [courtesy Dan Heller (argv@ora.com), 8/90; mouse@larry.mcrcim.mcgill.edu 5/91;
- Ollie Jones (oj@pictel.com) 6/92]
-
- There are two alternatives: the simple one is to use XtAppAddTimeout instead
- of XtAppAddInput and check for input occasionally; the more complex solution,
- and perhaps the better one, is to popen or fork&exec a child which does
- blocking reads on the file, relaying what it has read to your application via
- a pipe or a socket. XtAppAddInput will work as expected on pipes and
- sockets.
-
- Thanks to Kaleb Keithley (kaleb@x.org); 12/93]
-
- ----------------------------------------------------------------------
- Subject: 166) Why doesn't my Xt timer go off when it is supposed to (sic) ?
-
- Xt timers are non-preemptive; they do not operate like signal interrupts.
- That is, they don't suspend execution of the client program at a specific
- interval and call the timer procedure.
-
- Rather, timers are handled by Xt as another form of input. The Xt event loop
- watches for X events and for socket activity; the select() statement Xt uses
- returns when the first timer is set to go off. Xt then calls any timers that
- have expired.
-
- The implementation means that Xt timers can't be used for real-time
- operations. If one callback takes some time to operate, for example, any
- timers that "should have" gone off during its operation are not called until
- the thread of execution has again returned to Xt's event loop.
-
- ----------------------------------------------------------------------
- Subject: 167) What's this R6 error: X Toolkit Error: NULL ArgVal in XtGetValues?
-
- The application has a bug! A workaround is described in Section 3.4 of
- the R6 release notes. Here's the relevant excerpt:
-
- GetValuesBC
- Setting this variable to YES allows illegal XtGetValues requests with
- NULL ArgVal to usually succeed, as R5 did. Some applications erro-
- neously rely on this behavior. Support for this will be removed in a
- future release.
-
- ----------------------------------------------------------------------
- Subject: 168) Why do I get a BadMatch error when calling XGetImage?
-
- The BadMatch error can occur if the specified rectangle goes off the edge of
- the screen. If you don't want to catch the error and deal with it, you can take
- the following steps to avoid the error:
-
- 1) Make a pixmap the same size as the rectangle you want to capture.
- 2) Clear the pixmap to background using XFillRectangle.
- 3) Use XCopyArea to copy the window to the pixmap.
- [Whoa! this answer is currently under reexamination.]
- 4) If you get a NoExpose event, the copy was clean. Use XGetImage to grab the
- image from the pixmap.
- 5) If you get one or more GraphicsExpose events, the copy wasn't clean, and
- the x/y/width/height members of the GraphicsExpose event structures tell you
- the parts of the pixmap which aren't good.
- 6) Get rid of the pixmap; it probably takes a lot of memory.
-
- [10/92; thanks to Oliver Jones (oj@pictel.com)]
-
- ----------------------------------------------------------------------
- Subject: 169) How can my application tell if it is being run under X?
-
- A number of programs offer X modes but otherwise run in a straight
- character-only mode. The easiest way for an application to determine that it
- is running on an X display is to attempt to open a connection to the X
- server:
-
- display = XOpenDisplay(display_name);
- if (display)
- { do X stuff }
- else
- { do curses or something else }
-
- where display_name is either the string specified on the command-line
- following -display, by convention, or otherwise is (char*)NULL [in which case
- XOpenDisplay uses the value of $DISPLAY, if set].
-
- This is superior to simply checking for the existence a -display command-line
- argument or checking for $DISPLAY set in the environment, neither of which is
- adequate. [5/91]
-
- Note that there is a lengthy delay if $DISPLAY exists but is set to a machine
- which is not currently running an X server.
-
- ----------------------------------------------------------------------
- Subject: 170) How do I make a "busy cursor" while my application is computing?
- Is it necessary to call XDefineCursor() for every window in my application?
-
- The easiest thing to do is to create a single InputOnly window that
- is as large as the largest possible screen; make it a child of your toplevel
- window (which must be realized) and it will be clipped to that window, so it
- won't affect any other application. (It needs to be as big as the largest
- possible screen in case the user enlarges the window while it is busy or
- moves elsewhere within a virtual desktop.) Substitute "toplevel" with your
- top-most widget here (similar code should work for Xlib-only applications;
- just use your top Window):
-
- unsigned long valuemask;
- XSetWindowAttributes attributes;
-
- /* Ignore device events while the busy cursor is displayed. */
- valuemask = CWDontPropagate | CWCursor;
- attributes.do_not_propagate_mask = (KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
- attributes.cursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
-
- /* The window will be as big as the display screen, and clipped by
- its own parent window, so we never have to worry about resizing */
- XCreateWindow(XtDisplay(toplevel), XtWindow(toplevel), 0, 0,
- 65535, 65535, (unsigned int) 0, 0, InputOnly,
- CopyFromParent, valuemask, &attributes);
-
- where the maximum size above could be replaced by the real size of the screen,
- particularly to avoid servers which have problems with windows larger than
- 32767.
-
- When you want to use this busy cursor, map and raise this window; to go back to
- normal, unmap it. This will automatically keep you from getting extra mouse
- events; depending on precisely how the window manager works, it may or may not
- have a similar effect on keystrokes as well.
-
- In addition, note also that most of the Xaw widgets support an XtNcursor
- resource which can be temporarily reset, should you merely wish to change the
- cursor without blocking pointer events.
-
- [thanks to Andrew Wason (aw@cellar.bae.bellcore.com), Dan Heller
- (now argv@z-code.com), and mouse@larry.mcrcim.mcgill.edu; 11/90,5/91]
-
- ----------------------------------------------------------------------
- Subject: 171) How do I fork without hanging my parent X program?
-
- An X-based application which spawns off other Unix processes which
- continue to run after it is closed typically does not vanish until all of its
- children are terminated; the children inherit from the parent the open X
- connection to the display.
- What you need to do is fork; then, immediately, in the child process,
- close (ConnectionNumber(XtDisplay(widget)));
- to close the file-descriptor in the display information. After this do your
- exec. You will then be able to exit the parent.
- Alternatively, before exec'ing make this call, which causes the file
- descriptor to be closed on exec.
- (void) fcntl(ConnectionNumber(XDisplay), F_SETFD, 1);
-
- [Thanks to Janet Anstett (anstettj@tramp.Colorado.EDU), Gordon Freedman
- (gjf00@duts.ccc.amdahl.com); 2/91. Greg Holmberg (holmberg@frame.com), 3/93.]
-
- ----------------------------------------------------------------------
- Subject: 172) Why doesn't anything appear when I run this simple program?
-
- > ...
- > the_window = XCreateSimpleWindow(the_display,
- > root_window,size_hints.x,size_hints.y,
- > size_hints.width,size_hints.height,BORDER_WIDTH,
- > BlackPixel(the_display,the_screen),
- > WhitePixel(the_display,the_screen));
- > ...
- > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask|
- > ButtonReleaseMask);
- > XMapWindow(the_display,the_window);
- > ...
- > XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- > ...
-
- You are right to map the window before drawing into it. However, the
- window is not ready to be drawn into until it actually appears on the screen --
- until your application receives an Expose event. Drawing done before that will
- generally not appear. You'll see code like this in many programs; this code
- would appear after the window was created and mapped:
- while (!done)
- {
- XNextEvent(the_display,&the_event);
- switch (the_event.type) {
- case Expose: /* On expose events, redraw */
- XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- break;
- ...
- }
- }
-
- Note that there is a second problem: some Xlib implementations don't
- set up the default graphics context to have correct foreground/background
- colors, so this program could previously include this code:
- ...
- the_GC_values.foreground=BlackPixel(the_display,the_screen); /* e.g. */
- the_GC_values.background=WhitePixel(the_display,the_screen); /* e.g. */
- the_GC = XCreateGC(the_display,the_window,
- GCForeground|GCBackground,&the_GC_values);
- ...
-
- Note: the code uses BlackPixel and WhitePixel to avoid 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.
-
- Also note that actually using BlackPixel and WhitePixel is usually the wrong
- thing to do in a finished program, as it ignores the user's preference for
- foreground and background.
-
- And also note that you can run into the same situation in an Xt-based program
- if you draw into the XtWindow(w) right after it has been realized; it may
- not yet have appeared.
-
- ----------------------------------------------------------------------
- Subject: 173) What is the difference between a Screen and a screen?
-
- The 'Screen' is an Xlib structure which includes the information about
- one of the monitors or virtual monitors which a single X display supports. A
- server can support several independent screens. They are numbered unix:0.0,
- unix:0.1, unix:0.2, etc; the 'screen' or 'screen_number' is the second digit --
- the 0, 1, 2 which can be thought of as an index into the array of available
- Screens on this particular Display connection.
- The macros which you can use to obtain information about the particular
- Screen on which your application is running typically have two forms -- one
- which takes a Screen and one with takes both the Display and the screen_number.
- In Xt-based programs, you typically use XtScreen(widget) to determine
- the Screen on which your application is running, if it uses a single screen.
- (Part of the confusion may arise from the fact that some of the macros
- which return characteristics of the Screen have "Display" in the names --
- DisplayWidth, DisplayHeight, etc.)
-
- ----------------------------------------------------------------------
- Subject: 174) Can XGetWindowAttributes get a window's background pixel/pixmap?
-
- 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. [courtesy Dave Lemke of NCD and
- Stuart Marks of Sun]
-
- Note that the same applies to the border pixel/pixmap. This is a (mis)feature
- of the protocol which allows the server to manipulate the pixel/pixmap
- however it wants. By not requiring the server to keep the original pixel or
- pixmap, some (potentially a lot of) space can be saved. [courtesy Jim
- Fulton, then of X Consortium]
-
- ----------------------------------------------------------------------
- Subject: 175) How do I create a transparent window?
-
- A completely transparent window is easy to get -- use an InputOnly
- window. In order to create a window which is *mostly* transparent, you have
- several choices:
- - the SHAPE extension first released with X11R4 offers an easy way to
- make non-rectangular windows, so you can set the shape of the window to fit the
- areas where the window should be nontransparent; however, not all servers
- support the extension.
- - a machine-specific method of implementing transparent windows for
- particular servers is to use an overlay plane supported by the hardware. Note
- that there is no X notion of a "transparent color index".
- - a generally portable solution is to use a large number of tiny
- windows, but this makes operating on the application as a unit difficult.
- - a final answer is to consider whether you really need a transparent
- window or if you would be satisfied with being able to overlay your application
- window with information; if so, you can draw into separate bitplanes in colors
- that will appear properly.
-
- [thanks to der Mouse, mouse@lightning.McRCIM.McGill.EDU, 3/92; see also
- The X Journal 1:4 for a more complete answer, including code samples for this
- last option]
-
- ----------------------------------------------------------------------
- Subject: 176) Why doesn't GXxor produce mathematically-correct color values?
-
- When using GXxor you may expect that drawing with a value of black on a
- background of black, for example, should produce white. However, the drawing
- operation does not work on RGB values but on colormap indices. The color that
- the resulting colormap index actually points to is undefined and visually
- random unless you have actually filled it in yourself. [On many X servers Black
- and White often 0/1 or 1/0; programs taking advantage of this mathematical
- coincidence will break.]
- If you want to be combining colors with GXxor, then you should be
- allocating a number of your own color cells and filling them with your chosen
- pre-computed values.
- If you want to use GXxor simply to switch between two colors, then you
- can take the shortcut of setting the background color in the GC (graphics
- context) to 0 and the foreground color to a value such that when it draws over
- red, say, the result is blue, and when it draws over blue the result is red.
- This foreground value is itself the XOR of the colormap indices of red and
- blue.
-
- [Thanks to Chris Flatters (cflatter@zia.aoc.nrao.EDU) and Ken Whaley
- (whaley@spectre.pa.dec.com), 2/91]
-
- ----------------------------------------------------------------------
- Subject: 177) Why does every color I allocate show up as black?
-
- Make sure you're using 16 bits and not 8. The red, green, and blue
- fields of an XColor structure are scaled so that 0 is nothing and 65535 is
- full-blast. If you forget to scale (using, for example, 0-255 for each color)
- the XAllocColor function will perform correctly but the resulting color is
- usually black.
-
- [Thanks to Paul Asente, asente@adobe.com, 7/91]
-
- ----------------------------------------------------------------------
- Subject: 178) Why do I get a protocol error when creating a cursor (sic)?
-
- You may have had this code working on a monochrome system by
- coincidence. Cursor pixmaps must always have a depth of 1; when you create
- the cursor pixmap use the depth of 1 rather than the default depth of the
- screen.
-
- ----------------------------------------------------------------------
- Subject: 179) Why can't my program get a standard colormap?
- I have an image-processing program which uses XGetRGBColormap() to get the
- standard colormap, but it doesn't work.
-
- XGetRGBColormap() when used with the property XA_RGB_DEFAULT_MAP does
- not create a standard colormap -- it just returns one if one already exists.
- Use xstdcmap or do what it does in order to create the standard colormap first.
-
- [1/91; from der Mouse (mouse@larry.mcrcim.mcgill.edu)]
-
- ----------------------------------------------------------------------
- Subject: 180) Why doesn't the shared-memory extension appear to work?
-
- Using the MIT shared-memory extension (MIT-SHM) is a fine way to speed up
- manipulation and display of images. But be aware that XShmQueryExtension(dpy)
- returns only information on whether or not the server to which your program
- is connected is capable of supporting the shared-memory extension -- it
- doesn't confirm that your application is running on the same machine on which
- you are running that server. The client and server have to be on the same
- machine to be able to use shared memory.
-
- Current documentation is available via
- ftp://ftp.x.org/pub/R6untarred/xc/doc/specs/Xext/mit-shm.ms .
-
- [thanks to Kaleb Keithley (kaleb@x.org); 3/95]
-
- ----------------------------------------------------------------------
- Subject: 181) Why does the pixmap I copy to the screen show up as garbage?
-
- The initial contents of pixmaps are 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 a 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). [courtesy Dave Lemke of NCD and Stuart Marks of Sun]
-
- ----------------------------------------------------------------------
- Subject: 182) How do I get the width/height of an existing pixmap?
-
- XGetGeometry() works on Drawables -- either windows or pixmaps. In the case
- of a pixmap, though, the x,y, and border_width values are 0 (meaningless).
-
- ----------------------------------------------------------------------
- Subject: 183) How can I most quickly send an image to the X server?
-
- The fastest mechanism may be to use an XImage and the shared-memory
- extension to reduce the transmission time.
- The MIT-SHM code, documentation, and example client programs can be
- found on the X11R5 source tape; many vendors also support the extension.
- If bandwidth is a problem, the X Image Extension has facilities for
- transmitting compressed images.
-
- ----------------------------------------------------------------------
- Subject: 184) How do I check whether a window ID is valid?
- My program has the ID of a window on a remote display. I want to check whether
- the window exists before doing anything with it.
-
- Because X is asynchronous, there isn't a guarantee that the window
- would still exist between the time that you got the ID and the time you sent an
- event to the window or otherwise manipulated it. What you should do is send the
- event without checking, but install an error handler to catch any BadWindow
- errors, which would indicate that the window no longer exists. This scheme
- will work except on the [rare] occasion that the original window has been
- destroyed and its ID reallocated to another window.
- You can use this scheme to make a function which checks the validity
- of a window; you can make this operation almost synchronous by calling
- XSync() after the request, although there is still no guarantee that the
- window will exist after the result (unless the sterver is grabbed). On the
- whole, catching the error rather than pre-checking is preferable.
-
- [courtesy Ken Lee (now kenton@esd.sgi.com), 4/90; 12/93]
-
- ----------------------------------------------------------------------
- Subject: 185) Can I have two applications draw to the same window?
-
- Yes. The X server assigns IDs to windows and other resources (actually, the
- server assigns some bits, the client others), and any application that knows
- the ID can manipulate the resource (almost any X server resource, except for
- GCs and private color cells, can be shared).
-
- The problem you face is how to disseminate the window ID to multiple
- applications. A simple way to handle this (and which solves the problem of
- the applications' running on different machines) is in the first application
- to create a specially-named property on the root-window and put the window ID
- into it. The second application then retrieves the property, whose name it
- also knows, and then can draw whatever it wants into the window.
-
- [Note: this scheme works if and only if there is only one instance of the
- first application running, and the scheme is subject to the limitations
- mentioned in the Question about using window IDs on remote displays.]
-
- Note also that you will still need to coordinate any higher-level cooperation
- among your applications; you may find the Synchronization extension in R6
- useful for this.
-
- Note also that two processes can share a window but should not try to use the
- same server connection. If one process is a child of the other, it should
- close down the connection to the server and open its own connection.
-
- Note also that Display IDs and GC values describe addresses local to an
- application and cannot be transmitted to another application; note also that
- if you are using Xt you may not share widget IDs, which are local to the
- client.
-
- Note also that several clients may draw to a window but for particular X
- events such as button-presses only one client can receive the event.
-
- [mostly courtesy Phil Karlton (karlton@wpd.sgi.com) 6/90]
-
- ----------------------------------------------------------------------
- Subject: 186) Why can't my program work with tvtwm or swm?
-
- A number of applications, including xwd, xwininfo, and xsetroot, do not
- handle the virtual root window which tvtwm and swm use; they typically return
- the wrong child of root. A general solution is to add this code or to use it in
- your own application where you would normally use RootWindow(dpy,screen):
-
- /* Function Name: GetVRoot
- * Description: Gets the root window, even if it's a virtual root
- * Arguments: the display and the screen
- * Returns: the root window for the client
- */
- #include <X11/Xatom.h>
- Window GetVRoot(dpy, scr)
- Display *dpy;
- int scr;
- {
- Window rootReturn, parentReturn, *children;
- unsigned int numChildren;
- Window root = RootWindow(dpy, scr);
- Atom __SWM_VROOT = None;
- int i;
-
- __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
- XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren);
- for (i = 0; i < numChildren; i++) {
- Atom actual_type;
- int actual_format;
- long nitems, bytesafter;
- Window *newRoot = NULL;
-
- if (XGetWindowProperty(dpy, children[i], __SWM_VROOT, 0, 1,
- False, XA_WINDOW, &actual_type, &actual_format, &nitems,
- &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) {
- root = *newRoot;
- break;
- }
- }
-
- XFree((char *)children);
- return root;
- }
-
- [courtesy David Elliott (dce@smsc.sony.com). Similar code is in ssetroot, a
- version of xsetroot distributed with tvtwm. 2/91]
-
- A header file by Andreas Stolcke of ICSI on
- ftp.x.org:contrib/libraries/vroot.shar functions similarly by providing
- macros for RootWindow and DefaultRootWindow; code can include this header
- file first to run properly in the presence of a virtual desktop.
-
- (Note the possible race condition.)
-
- ----------------------------------------------------------------------
- Subject: 187) Can I rely on a server which offers backing store?
-
- You can assume only that the X server has the capability of doing
- backing store and that it might do so and keep your application's visuals
- up-to-date without your program's involvement; however, the X server can run
- out of resources at any time, so you must be able to handle the exposure
- events yourself. You cannot rely on a server which offers backing store to
- maintain your windows' contents on your behalf.
-
- ----------------------------------------------------------------------
- Subject: 188) How do I catch the "close window" event to avoid "fatal IO error"?
-
- Several windows managers offer a function such as f.kill or f.delete
- which sends a message to the application that it should delete its window;
- this is usually interpreted as a shutdown message.
- The application needs to catch the WM_DELETE_WINDOW client message.
- There is a good example in the xcalc sources in X11R5.
- Motif-based applications should in addition set the resource
- XmNdeleteResponse on the top-level shell to XmDO_NOTHING, whether they are
- using the Motif window manager or not.
- If the application doesn't handle this message the window manager may
- wind up calling XKillClient, which disconnects the client from the display and
- typically gives an Xlib error along the lines of "fatal IO error 32 (Broken
- pipe)".
-
- [Thanks to Kaleb Keithley, kaleb@x.org; 11/93]
-
- ----------------------------------------------------------------------
- Subject: 189) How do I keep a window from being resized by the user?
-
- Resizing the window is done through the window manager; window managers
- can pay attention to the size hints your application places on the window, but
- there is no guarantee that the window manager will listen. You can try setting
- the minimum and maximum size hints to your target size and hope for the best.
- Note that you may wish to reconsider your justification for this
- restriction.
-
- ----------------------------------------------------------------------
- Subject: 190) How do I keep a window in the foreground at all times?
-
- It's rather antisocial for an application to constantly raise itself
- [e.g. by tracking VisibilityNotify events] so that it isn't overlapped --
- imagine the conflict between two such programs running.
- The only sure way to have your window appear on the top of the stack
- is to make the window override-redirect; this means that you are temporarily
- assuming window-management duties while the window is up, so you want to do
- this infrequently and then only for short periods of time (e.g. for popup
- menus or other short parameter-setting windows).
-
- [thanks to der Mouse (mouse@larry.mcrcim.mcgill.edu); 7/92]
-
- ----------------------------------------------------------------------
- Subject: 191) How do I make text and bitmaps blink in X?
-
- There is no easy way. Unless you're willing to depend on some sort of
- extension (as yet non-existent), you have to arrange for the blinking yourself,
- either by redrawing the contents periodically or, if possible, by playing games
- with the colormap and changing the color of the contents.
-
- [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 7/91]
-
- ----------------------------------------------------------------------
- Subject: 192) How do I get a double-click in Xlib?
-
- Users of Xt have the support of the translation manager to help
- get notification of double-clicking.
- There is no good way to get only a double-click in Xlib, because the
- protocol does not provide enough support to do double-clicks. You have to do
- client-side timeouts, unless the single-click action is such that you can defer
- actually taking it until you next see an event from the server. Thus, you
- have to do timeouts, which means system-dependent code. On most UNIXish
- implementations, you can use XConnectionNumber to get the file descriptor of
- the X connection and then use select() or something similar on that.
- Note that many user-interface references suggest that a double-click
- be used to extend the action indicated by a single-click; if this is the case
- in your interface then you can execute the first action and as a compromise
- check the timestamp on the second event to determine whether it, too, should
- be the single-click action or the double-click action.
-
- [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 4/93]
-
- ----------------------------------------------------------------------
- Subject: 193) How do I render rotated text?
-
- The X Logical Font Description was enhanced for R6 to allow embedding a
- transformation matrix in certain fields of an XLFD name. Thus arbitrary
- rotation, scaling, shearing, etc. are possible. To draw text along an
- arbitrarily sloped line, open a font with the appropriate rotation
- transformation and individually place and draw each character. Drawing text
- along a curve requires a different font for each character orientation
- needed. The overhead of opening so many fonts is somewhat mitigated by
- another XLFD extension which allows you to ask for a subset of the
- characters. See section 4 of xc/doc/specs/XLFD/xlfd.tbl.ms in the R6
- distribution. Also see The X Resource, Issue Nine, p. 211, "New Font
- Technology for X11R6," by Nathan Meyers. (Note: due to changes after
- publication deadline, the information in the Meyers paper about the syntax of
- character set subsetting is out of date.) These capabilities are also
- available to an R5 X server using an R6 font server.
-
- If you are not using R6, your only choice, if you want to stay within the
- core X protocol, is to render the text into a pixmap, read it back via
- XGetImage(), rotate it "by hand" with whatever matrices you want, and put it
- back to the server via XPutImage(); more specifically:
-
- 1) create a bitmap B and write your text to it.
- 2) create an XYBitmap image I from B (via XGetImage).
- 3) create an XYBitmap Image I2 big enough to handle the transformation.
- 4) for each x,y in I2, I2(x,y) = I(a,b) where
- a = x * cos(theta) - y * sin(theta)
- b = x * sin(theta) + y * cos(theta)
- 5) render I2
-
- Note that you should be careful how you implement this not to lose bits; an
- algorithm based on shear transformations may in fact be better.
-
- The high-level server-extensions and graphics packages available for X also
- permit rendering of rotated text: Display PostScript, PEX, PHiGS, and GKS,
- although most are not capable of arbitrary rotation and probably do not use
- the same fonts that would be found on a printer.
-
- In addition, if you have enough access to the server to install a font on it,
- you can create a font which consists of letters rotated at some predefined
- angle. Your application can then itself figure out placement of each glyph.
-
- [courtesy der Mouse (mouse@larry.mcrcim.mcgill.edu), Eric Taylor
- (etaylor@wilkins.bmc.tmc.edu), and Ken Lee (now kenton@esd.sgi.com), 11/90;
- Liam Quin (lee@sq.com), 12/90; Dave Wiggins (dpw@x.org), 5/94.]
-
- InterViews (C++ UI toolkit, in the X contrib software) has support for
- rendering rotated fonts in X. It could be one source of example code.
- [Brian R. Smith (brsmith@cs.umn.edu), 3/91]
-
- Another possibility is to use the Hershey Fonts; they are stroke-rendered and
- can be used by X by converting them into XDrawLine requests.
- [eric@pencom.com, 10/91]
-
- The xrotfont program by Alan Richardson (mppa3@syma.sussex.ac.uk) (posted to
- comp.sources.x July 14 1992) paints a rotated font by implementing the method
- above and by using an outline (Hershey) font.
-
- The xvertext package by Alan Richardson (mppa3@syma.sussex.ac.uk) is a set of
- functions to facilitate the writing of text at any angle. It is on ftp.x.org
- as R5contrib/xvertext.5.0.shar.Z.
-
- O'Reilly's X Resource issue 3 includes information from HP about
- modifications to the X fonts server which provide for rotated and scaled
- text. The modifications are on ftp.x.org in R5contrib/hp_xlfd_enhancements/.
-
- Bristol Technology's XPrinter product has extensions to Xlib to rotate text.
- Send email to info@bristol.com for more details.
-
- ----------------------------------------------------------------------
- Subject: 194) Why doesn't my multi-threaded X program work (sic) ?
-
- Support in Xlib and Xt for multi-threaded X programs is included in X11R6.
- See the documentation for XInitThreads, XtToolkitThreadInitialize, section
- 2.7 of the Xlib specification, section 7.12 of the Xt specification, and the
- article "Multi-Threaded Xlib," The X Resource, Issue 5, by Stephen Gildea.
- The following discussion applies only to pre-R6 libraries:
-
- You cannot use non-thread aware, non-reentrant libraries with threads.
-
- If you must do this, you have only one choice: call the functions from the
- initial thread only.
-
- Why opening windows from other threads causes protocol errors can be
- explained easily: you are accessing shared resources (the display
- structure, the connection to the display, static data in the Xlib) from
- a number of threads at the same time, without using any form of
- exclusive access control.
-
- [Thanks to casper@fwi.uva.nl (Casper H.S. Dik)]
-
- ----------------------------------------------------------------------
- Subject: 195) How can I ensure that only one instance of my application is running?
-
- There are several mechanisms on the client-side you can use to ensure that
- attempts to run multiple copies of an application are caught; you can use
- them if you know that the second copy of the application will be invoked on
- the same machine or the same network as the first or if you know that they
- share a common view of a file-system. The common license-manager daemons
- operate in this way.
-
- A simple method that uses the X server as a conduit among several
- applications which may be running on different machines and hence have only
- the X server in common is for the first client to grab ownership of a
- specially-named selection; the selection can be registered with the X
- Registry to ensure its uniqueness. Subsequent invocations of the program can
- check to see whether XGetSelectionOwner() for that selection returns an X
- window; the program logic first checks to see whether or not it is a
- duplicate, exiting if so, and otherwise sets the marker by asserting
- ownership of the selection.
-
- An alternative method, in which the first application writes a property to
- the root window and subsequent invocations check for the existence of the
- property as a sign that they are duplicate versions, fails both for being
- easy to defeat and for tending to refuse to start up the first application
- when it should do so -- if previous invocations crashed and the X server was
- set not to remove the property when a client disconnects, the property may
- have been left as a marker when it should have been removed.
-
- [Thanks to Nicholas Young (youngn@logica.co.uk); 4/95]
-
- Sample code implementing an alternate scheme is available from
- http://www.wri.com/~cwikla/xcenter/singleLaunch
-
- ----------------------------------------------------------------------
- Subject: 196) How can I have two applications communicate via the X server?
-
- The communication can take place via special property values; the two
- applications can change the value of a property and each watch for changes to
- it. If the communication is two-directional then two properties can be used.
- The technique is appropriate for small messages which can be encoded easily.
-
- It is expensive and unnecessary to communicate via properties on the root
- window; a window owned by one of the applications is preferable. There is a
- problem, however, in communicating the window ID from one application to the
- other.
-
- The application owning the window can assert ownership of a specially-named
- selection; the selection can be registered with the X Registry to ensure its
- uniqueness. The second application loops, requesting the value of the
- selection; the first application encodes the ID of its window and sends it.
- The second application can then use XSelectInput() to get PropertyNotify
- events on that window.
-
- Thereafter, communication is via that window via XGetWindowProperty() and
- XChangeProperty().
-
- Watch also for the deletion of the property in order to disconnect properly;
- one of the applications may have exited.
-
- ----------------------------------------------------------------------
- Subject: 197) Where can I get information on internationalizing applications?
-
- See http://www.vlsivie.tuwien.ac.at/mike/i18n.html and
- ftp://ftp.vlsivie.tuwien.ac.at//pub/8bit/i18n-programming .
-
- ----------------------------------------------------------------------
- Subject: 198) What is the X Registry? (How do I reserve names?)
-
- There are places in the X Toolkit, in applications, and in the X protocol
- that define and use string names. The context is such that conflicts are
- possible if different components use the same name for different things.
-
- The X Consortium maintains a registry of names in these domains:
- orgainization names, selection names, selection targets, resource types,
- application classes, and class extension record types; and several others.
-
- The list as of April 1994 is in the file xc/registry in the R6 distribution.
- The current Registry is also available by sending "send docs registry" to the
- xstuff mail server.
-
- To register names (first come, first served) or to ask questions send to
- xregistry@x.org; be sure to include a postal address for confirmation.
-
- [11/90; condensed from Asente/Swick Appendix H; 1/94]
- ----------------------------------------------------------------------
-
- David B. Lewis faq%craft@uunet.uu.net
-
- "Just the FAQs, ma'am." -- Joe Friday
-