-------------------------------------------------------------------------------
Using `editdres' in your applications

You have to register an event handler named '_EditResCheckMessages' on each
toplevel window in your application. This event handler is defined in
libXmu.a.    --- I don't think this is actually true!

-------------------------------------------------------------------------------
Permanent Objects in X Server

  dpy:     your existing connection
  tempdpy: a secondary connection dedicated to make something permanent.

    tempdpy = XOpenDisplay(DisplayName(dpy));
    XSetCloseDownMode(tempdpy, RetainPermanent);
    create_something_to_be_permanent(tempdpy);
    XCloseDisplay(tempdpy);

Don't do anything else with this second display connection, as you don't
want anything else to become permanent. For more information, have a look
in the Xmu source code for the creation of standard colormap atoms.

DO NOT USE the dpy of a normal Xlib or Xt client to make something
permanent. You would make things permanent you wouldn't like to leave on
the display when your program is finished.  ;-)

For Example: If you open a window with the `RetainPermanent' connection,
then after the client closes down the window will still be there. If the
window manager then makes an explicite XKillClient() requests for that
window, all of the permanent set of information will then be deleted.

-------------------------------------------------------------------------------
ColorMap allocation
  XInstallColormap() call is used only be window managers to change the
  actual colormap. To set the color map an application uses use the call
  XSetWMColormapWindows() or XtSetWMColormapWindows() to set the
  WM_COLORMAP_WINDOWS property on the toplevel windows.  NOTE: you must
  have the widgets realised before using this call in Xt

-------------------------------------------------------------------------------
Color allocation notes

  * To convert a color range of 0-255 to a X11 color range of 0-65535
    you must multiple by 257 not 256. The reason for this is that
                 255*257    =>   65535
    This would also result in color #aabbcc becoming #aaaabbbbcccc which
    is the correct solution as used by the RGB data base.  

  * The reverse of the above can divide by either 256 or 257 due to the
    integer division of each color compenent.

-------------------------------------------------------------------------------
Color Allocation
    My color program always fails on XAllocColorCells()!

    Your program is assuming that the default colormap for the screen is a
    dynamic one, that is, one out of which you can allocate nonshared color
    cells via XAllocColorCells().  Some servers have a static colormap as
    their default colormap, so XAllocColorCells() will fail.

    You have several alternatives.  One possibility is to change your program
    to use XAllocColor().  You won't be able to alter the color once you've
    allocated it, but you may not have needed to do that in the first place.
    You should use XAllocColor() in preference to XAllocColorCells() if you
    simply want to get colors on the screen.  The reason is that
    XAllocColor() allows the same colors to be shared amongst different
    clients.

    If you really need to allocate and change colormap cells, then you still
    need to use XAllocColorCells() or XAllocColorPlanes().  For these calls
    to work, you must search the server's visual list for a visual that
    supports dynamic colormaps.  Then, you must create a colormap against
    this visual and allocate colors out of this colormap.  If the server
    doesn't have any dynamic visuals, your program simply won't work on this
    server.  If you successfully create and use your own dynamic colormap,
    you'll also have to create a window using the same visual and set that
    window's colormap attribute to be your newly created colormap.  Don't
    forget to set up WM_COLORMAP_WINDOWS so the window manager can install
    your colormap.

-------------------------------------------------------------------------------
Drawing a large `fat' point
  The Best method from the network is 
     Draw a line of length 0, with a width of desired diameter and a
     cap style of rounded. Other methods are more difficult or slow.

-------------------------------------------------------------------------------
Notes on Drawing Bitmaps
  * XCopyPlane copies a bitmap to a pixmap with the appropriate
    foreground and background colours of the GC. (0-back 1-fore)
  * XCopyArea copies a pixmap map to a destination of the SAME depth
    without any changes to the coloring of the output.
  * Icon bitmaps have to be given to the window manager as bitmaps
    as that is what is expected. A pixmap icon must be setup as a
    icon window instead of a true icon.  :-(

Results :-
  To set a bitmap for command widgets from an included data file (IE
not via a resource setting) requires a pixmap to be created with the
bitmap stored in it using the correct color scheme.

I suggest the following (though there may be a better way)..
   1/ Copy the bitmap data into a pixmap of depth 1 in the server. 
   2/ perform a XCopyPlane from this `bitmap' into a pixmap of the
      correct depth using a GC with the appropite foreground and
      background colors set.
   3/ destroy the intermediate depth 1 pixmap if you don't what it
      for other purposes.

WARNING: Label Widgets handle its image as a Bitmap is pixmap depth is
equal to 1. This can produce an inverted image for pixmaps on some
monocrome displays. (those with black pixel == 0)

-------------------------------------------------------------------------------
Drawing non-rectangular bitmaps/pixmaps

If you are using the XPM library then the mask is created for you when
you are making the pixmap. Here is how to use it or another bitmap
as a mask to what you are drawing.

METHOD 1:
  Here is the clip mask method mentioned above...
    The solution is to use your bitmap as a clip mask in the Graphics
  context.  What the mask does is only allow drawing on the pixels where
  1's are in the bitmap.

    XSetClipMask( display, gc, bitmapmask );
    XSetClipOrigin( display, gc, 0, 0 );
    XCopyArea( display, pixmap, XtWindow(widget), gc, 0, 0,
                   width, height, 0, 0 ); 
    /* clean up */
    XSetClipMask( display, gc, None );

  x and y are the upper left corner of the rectangle where the bitmap is
  to be placed. The mask must be a 2 plane pixmap (i.e. a bitmap);
  These masks are automatically created by the Xpm libraries.

  This is slow due to mask convertsion to rectangle lists.
                                 -- Jason Schmidt     leolore@iastate.edu

METHOD 2:
    XCopyArea(display, pixmap, window, gcxor, 0, 0, w, h, x, y);
    XSetForeground(display, gcand, 0);
    XSetBackground(display, gcand, ~0);
    XCopyPlane(display, mask, window, gcand, 0, 0, w, h, x, y, 1L);
    XCopyArea(display, pixmap, window, gcxor, 0, 0, w, h, x, y);

  NOTE:  pixmap = colour pixmap    mask = 1 plane pixmap
  It is pretty quick and you don't need clip masks, shape extensions etc.
                              -- Justin Kibell  jck@jaguar.catt.citri.edu.au

METHOD 3: Use the mask as a shapemask with the X11 Nonrectangular Shape
    Window Extension. Typically this is what should be done when the icon
    is used in a desktop.     -- Arnaud Le Hors <lehors@x.org>

    But you can do this witha widget window too. (See my IconLabel Widget)

-------------------------------------------------------------------------------
Pixmap in a Label Widgets

The label widget draws bitmaps differently to bitmaps, but it can't tell
the difference on monochrome displays. Thus on some monochrome displays
pixmaps are drawn inverted as the white and black pixel values don't match
that of a normal bitmap (white=0 and black=1).

IE: pixmaps in labels on SUN monochrome consoles are correct but are inverted
on NCD monochrome displays.

To fix this
     if ( display_depth == 1 || white_pixel == 1 )
       Invert the colors of your pixmap before assigning to a label.

NOTE: swapping white and black on a label is not a good solution as
the internal spacing will then have the wrong color.

Solution

  ...insert example here...anyone?...

-------------------------------------------------------------------------------
X Pixmaps with the color None..
   The Color None if not masked using the Mask Bitmap generated comes out
as Pixel Value 0.  This pixel value is white on Sun and Dec  X servers but
black on NCD's, and other X Terminals and many other workstations like
Silicon Graphic machines.

The simple fix is to use the following coding..

  ======8<------
  static XpmColorSymbol attr_nonesymbol[] = { {NULL, "none", 0} };
  static unsigned long attr_valuemask =
       XpmColorSymbols | XpmReturnPixels | XpmCloseness;

  /* ...initialize... */
  attr_nonesymbols[0].pixel = app_data.icon_trans;   /* transparent color */

  /* do the job */
  item->attr.valuemask = attr_valuemask;
  item->attr.colorsymbols = attr_nonesymbols;
  item->attr.numsymbols = XtNumber(attr_nonesymbols);
  item->attr.closeness = 40000;

  status = XpmReadPixmapFile(display, DefaultRootWindow(display),
	      item->fname, &item->pixmap, NULL, &item->attr);

  /* Now remove the transparent pixel from the pixel list
  ** Otherwise it will be freed later when it shouldn't. :-( */
  { int i,j;
    for( i = j = 0;  i < item->attr.npixels;  i++ ) {
      if( item->attr.pixels[i] == app_data.icon_trans )
        continue;            /* don't include the none pixel color */
      item->attr.pixels[j++] = item->attr.pixels[i];
    }
    item->attr.npixels = j;  /* the number of pixels now */
  }
  ======8<------

WARNING: The above is not really as simple as it seems. See the latest
xbmbrowser program and look at the Chnages made for version 4.4 of the
program.

NOTE: The  XpmColorSymbol array elements has three items of which only
two are ever used for the substitution. This means there are three
ways the substitution can be performed.

        XpmColorSymbol Elements    |
      name       value      pixel  |  Results in
    -------------------------------+------------------------------------
     "symbol"   "color"       ?    |  symbol with the color "color"
     "symbol"    NULL       pixel  |  symbol with the specified pixel
      NULL      "color"     pixel  |  "color" with the value of pixel
    -------------------------------+------------------------------------

-------------------------------------------------------------------------------
Panning Pixmaps
  A pixmap that is larger than the window(viewport) and you can move it
(display it) without having to do more redraws and heavy IO.

        1) Draw into a pixmap, then do the panning by hand using XCopyArea()
        though this doesn't sound like something you want to do..

        2)  Create a window. Create a subwindow.  Draw into your pixmap.
        Set that pixmap as the background of the subwindow.  Use XMoveWindow()
        to move the subwindow for panning.

-------------------------------------------------------------------------------
Nonrectangular pointer zones (many) in window (non-orthogonal)
    It is perfectly feasible and pretty easy to do with the SHAPE
routines. Another solution is to just draw all the zones in the 
englobbing rectangular window an track the pointer motion events and
calculate manually in which zone the pointer is (to highlight it or
do whatever you want). You should probably try the first solution
first, but many X servers are a bit sluggish when dealing with
non-rectangular windows (Clip mask problem).
                               lecom@slhp1.epfl.ch (Claude Lecommandeur)

-------------------------------------------------------------------------------
General Speedup hints
 Joe English (joe@trystero.art.com) :
    * Don't create and destroy widgets on the fly.  Try to reuse them.
      (This will avoid many problems with buggy toolkits, too.)

    * Use a line width of 0 in GCs.  On some servers this makes a HUGE
      difference.

    * Compress and collapse multiple Expose events.  This can make the
      difference between a fast application and a completely unusable
      one.

 Francois Staes (frans@kiwi.uia.ac.be) :
    * Just a small remark: I once heard that using a better malloc
      function would greatly increase performance of Xt based applications
      since they use malloc heavily. They suggested trying out the GNUY
      malloc, but I didn't find the time yet. I did some tests on small
      programs just doing malloc and free, and the differences were indeed
      very noticeable ( somewhat 5 times faster)

  Joe Stewart (joes@lpi.liant.com)
    * for long button press actions -- fork off a sub-process to deal with
      the problem. This leaves the application running normally. Or
      start a WorkProc in Xt.

-------------------------------------------------------------------------------
Icons and Window state
  There are three states for windows: Withdrawn, Normal, and Iconic.
    Newly created top-level windows are in the Withdrawn state.

    Withdrawn -> Any 
       The client should map the window with WM_HINTS.initial_state being
       set to NormalState or IconicState as appropriate.
    Any -> Withdrawen
       The client should unmap the window and follow it with a synthetic
       UnmapNotify event to itself to allow correct event programming.
       R5 has a new library routine to do this properly for WM.
    Normal -> Iconic 
       The client should send a client message to iconify itself.  This is
       done for you by the Xlib routine XIconifyWindow to make this job
       easier.
    Iconic -> Normal
       The client should map the window. WM_HINTS.initial_state is
       irrelevent.
                               --- der Mouse    mouse@larry.mcrcim.mcgill.edu

-------------------------------------------------------------------------------
Application Exits
  Note that in many Unix-based implementations of Xlib, there's a sort of
race condition around XIO errors; because of the way the connection
between the server and the client is implemented, you may get a SIGPIPE
before the next time you try to interact with the X11 server, ie, before
you notice the XIO error.  Since the default action for SIGPIPE is to
abort the program, this is something of a problem.
                                --- Matt Landau    matt@centerline.com

   For applications that do not use WM_DELETE_WINDOW, a I/O error handler
that exits quietly instead of printing a noisy complaint first. should be used.
IE:
     myIOerror(d) Display *d; { exit(0); }
     ...
     SetIOErrorHandler(myIOerror);
                                --- der Mouse    mouse@larry.mcrcim.mcgill.edu

  The problem with your (above) solution is that while it cures the single
erroneous error, it also defeats the the reporting of other, real errors
in the same "swell foop", which is why I said, "IMHO, programs that don't
participate..."
                                --- Kaleb Keithley    kaleb@thyme.jpl.nasa.gov

-------------------------------------------------------------------------------
Signal Handling in X
    There IS a reason not to do Xt or Xlib calls within a signal handler.
It has to do with confusing the X protocol, as well as this, the libraries
are not re-entrent.

Two safe methods are
   1/ Set a flag (the only truly safe method) and Check this flag in
      you Work Procedure, or a XtTimeer Proc.
   2/ Create a pipe added to the event loop with XtAppAddInput().
      This method seems most universal on the network.
-----
How to use a pipe to handle signals
   * In your X application startup code create a pipe.
   * Attach the readable end of the pipe to the X event queue using
     XtAppAddInput.
   * Create a signal handler and register it with the signals you want
     to handle in the event loop.
   * In the signal handler code, build a message with the signal number
     and any other info you might need to handle the signal, then
     write() it to the writable end of the pipe.

Now when you get a signal, your signal handler will write to the pipe which
will make the event dispatcher call your input event handler that can
really process the signal...    --- Tom Horsley   tahorsley@csd.harris.com
-----
This is not totally safe unless you are careful about overflowing the
buffering capacity of the pipe.  And I don't think anyone guarantees
how much buffering pipes have, or even that they have any at all.  At
the price of a few of extra syscalls per signal received, you can avoid
assuming more than one byte of buffering....
                           --- der Mouse   -- mouse@larry.mcrcim.mcgill.edu

-------------------------------------------------------------------------------
Multiple Displays
| I have an Xt application that uses multiple displays (one app context).
| When I try to call XtOpenDisplay on a display that currently has the
| xdm login prompt, my application hangs (waiting for XtOpenDisplay to
| return).

Sure, opening the display hangs, but only for a certain amount of time. You
could interrupt it by winding up a timer, doing a setjump and then
XtOpenDisplay. When the timer strikes you longjump back. And don't forget
to cancel the timer if opening the display succeeded.

    signal (SIGALRM, XtOpenTimeout);
    if (setjmp (xtOpenJump))
    {
        LogError ("XtOpenDisplay timeout expired for display %s.\n", d->name);
        signal (SIGALRM, SIG_DFL);
        alarm (0);          
        return False;
    }
    else
    {
        alarm ((unsigned) d->openTimeout);
        argc = 0;
        d->display = XtOpenDisplay (applicationContext, d->name, "xlogin",
                                    "Xlogin", NULL, 0, &argc, NULL);
        signal (SIGALRM, SIG_DFL);
        alarm (0);          
        if (d->display == NULL)
            return False;
        Debug (1, "XtOpenDisplay (%s) successful\n", DisplayString
               (d->display));
        /* ... */
        return True;
    }

NOTE: I can't get this to work - Anthony

-------------------------------------------------------------------------------
Ephemeral Annotations (Rubberbanding Color Screens)
XOR 
    On color screens XOR can produce `random' color selections which may
  or maynot be actually visiable. Only if you install your own color map
  can you be sure that this would would as expecated directly.

    What's often appropriate is to interchange the foreground color with the
  background color.  If your graphics has the concept of a foreground and a
  background, you can do XOR animation that switches foreground and
  background by setting the GC foreground pixel to the XOR of the
  foreground and background pixels.  In C, this would be

      XGCValues gcvalues;
      gcvalues.foreground = fgpixel ^ bgpixel;
      XChangeGC(dpy,gc,GCForeground,&gcvalues);

  For monochrome graphics, you can use

      gcvalues.foreground =
      BlackPixel(dpy,DefaultScreen(dpy))^WhitePixel(dpy,DefaultScreen(dpy));

                         --- X11 Top Ten Questions: Dave Lemke (lemke@ncd.com)

XOR with color cycling
    XOR works poorly in pictures involving randomized or `grainy' data
  (such as satalite maps).  
                           --- rosenth@vision.ethz.ch (Lukas Rosenthaler)

    Although a XOR'ed line may be hard to see. A flashing one is almost
  certainly visible.  While the annotation is up, continually erase and
  redraw it three times a second slightly different using an Xt timer
  proc. IE: XOR plane 1 then 2, 3, 4...  and repeat. to remove just xor
  all the planes that is currently xor'ed. 
    Even though the effect of XOR drawing in a random color map yields
  random colors, this technique should yield enough different random
  colors on your annotation lines over a period of a couple of seconds
  that users will see them clearly.
                                         --- Oliver Jones (miki.pictel.com)

XOR with `ant' dash lines
    Same principle as above. Draw the annotation lines dashed, and redraw
  them continually as you reset the origin of the dash pattern. This will
  make the annotation lines crawl, the way lassos and marquees do on Mac
  drawing programs.
                                         --- Oliver Jones (miki.pictel.com)

Overlay Color plane
    An alternative is to devote one or two color planes to be overlay
  planes.  This means that you lose those planes for displaying colors for
  your main image, but you gain the ability of being able to "overlay" an
  image over your main image. I should also point out that this technique
  is further simplified by technology that allows you to selectively write
  to certain pixel planes, instead of all of them. I believe X supports
  this, via the XSetPlaneMask function.     --- Doug Young <dougy@xvt.com>

Backing Plane
    This works by using the backing pixmap used for expose redraws, as a
  tiling pattern. Just draw your annotation as normal but to undraw from
  the backing pixmap use the following GC.
        function:       GXcopy
        fill_style:     FillSolid
        tile:           the backing pixmap
        ts_x_origin:    0
        ts_y_origin:    0
  And draw the annotation again to erase it.
                                          --- Jim Mayer (mayer@wrc.xerox.com)

-------------------------------------------------------------------------------
Double Buffering
  One method is to divid the color planes into two sections to flip
  between.  This is used by the Xpilot program. Problem is, this solution
  requires num_colours * num_colours colours to be allocated, limiting you
  to 16 colours on a 256 color machine.

  Alternitively, you can add support for the MIT double buffering
  extension.  This should give a noticeable increase in speed.

  Lacking that, I would implement it much like the original ICO did in
  that I would draw into pixmaps and copy them into the window as needed.

-------------------------------------------------------------------------------
Xresources from Xlib programs
   If you just want to get resources, look at XGetDefault, which "[...]
provides a simple interface for clients not wishing to use the X toolkit
or the more elaborate interfaces provided by the resource manager
[...].".  If you want something more complicated, look at
XResourceManagerString and XScreenResourceString (the latter does not
exist pre-R5), XrmGetFileDatabase, XrmGetStringDatabase, and
XrmGetResource.  There are many other Xrm* functions; check out the Xlib
documentation.  (And don't forget to call XrmInitialize.)

                                   der Mouse --- mouse@mcrcim.mcgill.edu

-------------------------------------------------------------------------------
