mirror of
https://github.com/IanDarwin/OpenLookCDROM.git
synced 2026-02-20 22:45:59 +00:00
1267 lines
60 KiB
Plaintext
1267 lines
60 KiB
Plaintext
From: dbl@ics.com (David B. Lewis)
|
|
Newsgroups: comp.windows.x,news.answers,comp.answers
|
|
Subject: comp.windows.x Frequently Asked Questions (FAQ) 6/6
|
|
Date: 11 Apr 1995 13:37:36 GMT
|
|
Organization: ICS
|
|
Approved: news-answers-request@MIT.Edu
|
|
Expires: Sun, 14 May 1995 00:00:00 GMT
|
|
Message-ID: <3me0n0$qeq@ics.com>
|
|
Reply-To: faq%craft@uunet.uu.net (X FAQ maintenance address)
|
|
Summary: useful information about the X Window System
|
|
|
|
Archive-name: x-faq/part6
|
|
Last-modified: 1995/04/10
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 120) Why can't I link to the Xlib shape routines?
|
|
When I try to compile certain programs, I get the following link error:
|
|
Undefined:
|
|
_XShapeQueryExtension
|
|
_XShapeCombineMask
|
|
|
|
These routines are actually part of the Shape Extension to X (SHAPE)
|
|
which was introduced in the X11R4 distribution and allows non-rectangular
|
|
windows. Like the other sample server extensions, the shape extension will
|
|
only run on a server which supports it. Pre-X11R4 servers, as well as many
|
|
vendor-supplied servers, do not support the shape extension, in which case
|
|
they will display rectangular windows anyway.
|
|
|
|
In order to use the shape extension, you must link to the library
|
|
libXext.a. In the X11R4 distribution, this library and the associated includes
|
|
will be in the mit/extensions directory. If you do not have these files, do
|
|
not despair: many freeware programs which use the shape extension can also be
|
|
compiled without it by removing the -DSHAPE define from the Makefile; you can
|
|
probably do this and compile successfully against your older vendor-supplied X
|
|
libraries.
|
|
|
|
[from John B. Melby, melby%yk.fujitsu.co.jp@uunet.uu.net, 3/91]
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 121) What are these problems with "_XtInherit not found" on the Sun?
|
|
When I link a X program that I wrote on a SunOS 4.0.3 or 4.1 machine I get the
|
|
error "ld.so: symbol not found _XtInherit".
|
|
|
|
What you are seeing is a side-effect of a kludge in the R4 libXt.a to
|
|
get Sun shared libraries working. Apparently, you can't share a function that
|
|
is both called and compared, as _XtInherit is. This was handled by putting
|
|
_XtInherit in the same file as a function that is always used, thereby
|
|
guaranteeing that it would be loaded -- that is, in Initialize.c, where
|
|
XtToolkitInitialize() and XtInitialize() reside. These routines would normally
|
|
be called.
|
|
|
|
You are probably seeing this error because your program is not a normal
|
|
Xt-based program and does not call XtToolkitInitialize() anywhere.
|
|
1) it may be a program that uses Xt functions but never opens a
|
|
connection to the X server. [OSF/Motif's 1.1.0 UIL had this problem; it called
|
|
XtMalloc() and other Xt functions.] The solution is to add the call to your
|
|
program; the function does not have to be executed, just linked in.
|
|
2) alternatively, your program doesn't need any Xt functions and is
|
|
correct in not calling XtToolkitInitialize() -- it may be an Xlib or XView
|
|
program. In this case, you can remove -lXt from your link command.
|
|
|
|
It should not be necessary to link the shared libraries statically,
|
|
although this will certainly solve the problem.
|
|
|
|
[from Jordan Hayes (now jordan@MooreNet.COM) and Danny Backx (db@sunbim.be);
|
|
11/90]
|
|
|
|
You may also see this error compiling X11R5 programs on a SunOS 4.1.3 machine;
|
|
be sure to set OSTeenyVersion to 3 in the config/sun.cf file.
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 122) TOPIC: PROGRAMMING PROBLEMS AND PUZZLES
|
|
----------------------------------------------------------------------
|
|
Subject: 123) Why doesn't my program get the keystrokes I select for (sic)?
|
|
|
|
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, &wmhints)
|
|
|
|
If your application is based on the Xt Intrinsics, you can set the XtNinput
|
|
resource to be True (as you probably want to in any case); if you don't have
|
|
source, you can start up the application with the resource '*input:True'.
|
|
|
|
Certain window managers, notably dxwm and olwm, are very picky about having
|
|
this done.
|
|
|
|
If you are using Sun's OpenWindows olwm, you can also add this resource
|
|
to your defaults file to use clients that aren't ICCCM-compliant.
|
|
OpenWindows.FocusLenience: true
|
|
|
|
[mostly courtesy Dave Lemke of NCD and Stuart Marks of Sun]
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 124) How do I deiconify a window?
|
|
|
|
To de-iconify a window, map it with XMapWindow(). To iconify a window, use
|
|
XIconifyWindow().
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 125) How do I figure out what window manager is running?
|
|
|
|
You can't reliably tell; whatever mechanism you could use could be
|
|
spoofed in any case.
|
|
For most cases, you shouldn't care which window manager is running, so
|
|
long as you do things in an ICCCM-conformant manner. There are some cases in
|
|
which particular window managers are known to do things wrong; checking for
|
|
particular hints placed on the window by the window manager so that you can
|
|
sidestep the problem may be appropriate in these cases. Alternatively, it may
|
|
be appropriate to determine which window manager is running in order to take
|
|
advantage of specific *added* features (such as olwm's push-pin menus) in order
|
|
to give your program *added* functionality. Beware of usurping the window
|
|
manager's functions by providing that functionality even when it is missing;
|
|
this surely leads to future compatibility problems.
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 126) Is there a skeleton X program available?
|
|
|
|
There is no general framework such as the TransSkel program for the
|
|
Macintosh which handles lots of the odds and ends and overhead of development
|
|
under a window system and which can be used as a platform for additional
|
|
development. In X, the problem is typically solved by using an interactive
|
|
application builder tool or by using cut&paste on existing X applications. Good
|
|
applications which you might look to manipulate when you want to "test just
|
|
this one little thing" include contrib/clients/xskel, a simple R4 program that
|
|
puts up a window and allows sketching in it and offers a starting point for
|
|
quick hacks, the Xaw examples in the examples/ directory in the R3 and R4
|
|
distributions, and the Xlib "Hello World" example in the R3 doc/HelloWorld and
|
|
R4 doc/tutorials/HelloWorld; an updated version of this program which uses R4
|
|
Xlib calls and current ICCCM conventions was posted in 2/90 to comp.windows.x
|
|
by Glenn Widener of Tektronix. [3/90]
|
|
|
|
In addition, a sample Xt program (for Xaw or Xm) by Rainer Klute
|
|
showing how to open multiple displays and how to catch a broken display
|
|
connection is available on ftp.x.org in contrib/mdisp.tar.Z. [4/92]
|
|
A sample multi-display Xt/Xaw program by Oliver Jones is on ftp.x.org
|
|
in contrib/MultiUserVote.tar.Z. (See also his article in The X Resource, Issue
|
|
3, "Multi-User Application Software Using Xt".)
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 127) How can I incorporate an Xlib program in my Xt program?
|
|
|
|
As older Xlib programs are ported to Xt it often makes sense to preserve
|
|
their Xlib-ness while still having Xt-based menus, scrollbars, and other
|
|
GUIisms of current Xt toolkits. The basic problem in merging the two models
|
|
is in the event-delivery mechanism. In an Xt program, the application enters
|
|
an infinite loop in XtAppMainLoop() and Xt thereafter dispatches events to
|
|
widgets without the application's intervention; in contrast, Xlib programs
|
|
typically track the set of events they are interested in and the possible
|
|
windows on which those events can occur and hence call XNextEvent directly
|
|
and then determine what action to take on the event received.
|
|
|
|
One possible solution may be to widgetize the Xlib application. A faster
|
|
solution is probably to break XtAppMainLoop() into its components:
|
|
|
|
void XtAppMainLoop(app)
|
|
XtAppContext app;
|
|
{
|
|
XEvent event;
|
|
|
|
for (;;) {
|
|
XtAppNextEvent(app, &event);
|
|
XtDispatchEvent(&event);
|
|
}
|
|
}
|
|
|
|
and then change the dispatch call to be something like
|
|
|
|
if (!XtDispatchEvent(&event))
|
|
dispatch_xlib_events();
|
|
|
|
That is, if Xt isn't interested in dispatching the event, it must be an event
|
|
on one of the windows created via the code incorporated from the Xlib program
|
|
and can be dispatched in the same way as in the original program.
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 128) Why does XtGetValues not work for me (sic)?
|
|
|
|
The XtGetValues interface for retrieving resources from a widget is
|
|
sensitive to the type of variable. Your code may be doing something like this:
|
|
{
|
|
Arg args[3];
|
|
int i;
|
|
int sensitive; /* oops; wrong data type */
|
|
i=0;
|
|
XtSetArg (args[i], XtNsensitive, &sensitive); i++;
|
|
XtGetValues(widget, args, i );
|
|
...
|
|
}
|
|
|
|
But XtNsensitive is a Boolean, which on most machines is a single byte;
|
|
declaring the variable "sensitive" as Boolean works properly. This problem
|
|
comes up often when using particular toolkits that redefine the Xt types
|
|
Dimension and Position; code that assumes they are int will have similar
|
|
problems if those types are actually short. In general: you are safe if you
|
|
use the actual type of the resource, as it appears in the widget's man page.
|
|
[11/90]
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 129) Why don't XtConfigureWidget/XtResizeWidget/XtMoveWidget work?
|
|
|
|
You're probably trying to use these functions from application code.
|
|
They should be used only internally to widgets; these functions are for a
|
|
parent Composite widget to change the geometry of its children. An
|
|
application which calls XtMoveWidget, for example, effectively defeats
|
|
geometry negotiation and the Composite parent's internal state (if any) will
|
|
no longer be correct. (The Xt specification goes into more detail.)
|
|
The only way for your application to request a geometry change for a
|
|
widget is to issue an XtSetValues call setting some of the geometry
|
|
resources. Although this call will result in the widget-internal functions'
|
|
being called, your application code must use the standard XtSetValues
|
|
interface or risk the widgets' data becoming corrupted.
|
|
Note that functions defined in <X11/IntrinsicP.h>, as these are, are
|
|
typically reserved for use by widgets.
|
|
Other promising functions, XtMakeGeometryRequest() and
|
|
XtMakeResizeRequest(), are also for use only by widgets, in this case by a
|
|
child to request a change from its parent.
|
|
The Xlib calls XMoveWindow() and XResizeWindow() should similarly be
|
|
avoided; they shouldn't be used to change XtNx, XtNy, XtNwidth, or XtNheight.
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 130) Why isn't there an XtReparentWidget call like XReparentWindow?
|
|
|
|
Although there are various details of the current implementation of
|
|
the Xt internals which make reparenting difficult, the major reason that no
|
|
such call exists is that it remains undefined what the set of resources for
|
|
the "new" widget should be. Resources are typically set based on the location
|
|
in the instance hierarchy; what resources should change if the instance moves?
|
|
What should happen to the widget's children? And by the time such semantics are
|
|
defined, there would probably be little advantage over destroying the old
|
|
widget and creating a new widget in the correct location with the desired
|
|
resources, as setting the resources correctly is the majority of work in
|
|
creating a new widget.
|
|
|
|
Note that reparenting is possible in the OI toolkit.
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 131) 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: 132) 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: 133) 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: 134) 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: 135) 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: 136) 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: 137) 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: 138) 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: 139) 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: 140) 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: 141) 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: 142) 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: 143) 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: 144) 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: 145) 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: 146) 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: 147) 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.
|
|
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: 148) 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]
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 149) 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: 150) 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: 151) 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: 152) 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 --
|
|
XDisplayWidth, XDisplayHeight, etc.)
|
|
|
|
----------------------------------------------------------------------
|
|
Subject: 153) 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: 154) 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: 155) 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: 156) 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: 157) 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: 158) 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: 159) 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: 160) 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: 161) 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: 162) 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: 163) 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: 164) 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/vroot.h
|
|
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: 165) 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: 166) 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: 167) 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: 168) 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: 169) 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: 170) 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: 171) 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 contrib/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 contrib/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: 172) 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: 173) 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
|