From: jan@ECHO.CANBERRA.EDU.AU (Jan Newmarch)
Newsgroups: comp.windows.x.motif
Subject: Motif FAQ (Part 4 of 5)
Keywords: FAQ question answer
Date: 17 Aug 92 14:51:54 GMT
Expires: 17 Oct 92 04:31:35 GMT
Reply-To: jan@ise.canberra.edu.au (Jan Newmarch)
Followup-To: comp.windows.x.motif
Distribution: inet
Organization: The Internet

Archive-name: motif-faq/part4
Last-modified: Tue July 14 1992
Version: 2.6




-------------------------------------------------------------------------------
Subject: 80) TOPIC: XMSTRING

-------------------------------------------------------------------------------
Subject: 81) How can I get the Ascii text out of an XmString?

Answer: To get the first line of text from a string created left-to-right


        char *str;
        XmString xmstr;

        /* stuff to create xmstr */
        ...

        /* set str to point to the text */
        XmStringGetLtoR(xmstr, XmSTRING_DEFAULT_CHARSET, &str);
        /* use the string */
        ...

        /* and reclaim space */
        XtFree(str);


-------------------------------------------------------------------------------
Subject: 82) When can XmStrings used as resources be freed?

Answer: The policy OSF have been trying to enforce is that if you set an
XmString or XmStringTable resource, the application is responsible for freeing
the XmStrings used because the widget makes a copy.  If you get an XmString
resource, then the application must free the value gotten.  If you get an
XmStringTable, then the application should NOT free the value gotten.  If the
application wants to manipulate it, it should make a copy first. This policy
appears to be implemented progressively, so may be less true for Motif 1.0 than
1.1.

-------------------------------------------------------------------------------
Subject: 83) Why doesn't XmStringGetNextSegment() work properly?

Answer: The documentation in Motif 1.0 is in error. Instead of

        XmStringGetnextSegment(context, ...)
        XmStringContext * context;

it should be

        XmStringGetnextSegment(context, ...)
        XmStringContext context;

i.e. with no indirection.

-------------------------------------------------------------------------------
Subject: 84) TOPIC: DIALOGS

-------------------------------------------------------------------------------
Subject: 85) How do I stop my dialog disappearing when I press the help button?

Answer: Bulletin board has the resource autoUnmanage which defaults to True.
This unmanages the widget when any button child is activated - including the
help button.  Set this to False to stop it disappearing. Note that you then have
to unmanage the bulletin board yourself when any other button is activated.

-------------------------------------------------------------------------------
Subject: 86) How do I make my own dialog?  I want a dialog with my own set of
buttons that stretch and shrink like the ones in e.g. PromptDialog and its own
contents.

Answer: Start off with say a PromptDialog. Unmanage the buttons you don't want
or manage the Apply button if you want another. Unmanage the other bits of the
selection box you don't want. You can add another WorkArea child to the
selection box for any extra stuff you want.

    /* Copyright 1990, Kee Hinckley and Brian Holt Hawthorne */
    /* Permission granted for any use, provided this copyright */
    /* notice is maintained. */

    /* Create a dialog box */
    argcount = setArgs(&args, XmNautoUnmanage, False, NULL);
    SomeDialog = XmCreatePromptDialog(mainShell, "someDialog", args, argcount);

    /* Now get rid of the things we don't want */
    child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_SELECTION_LABEL);
    XtUnmanageChild(child);
    child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_TEXT);
    XtUnmanageChild(child);

    /* set the callbacks, and make sure the buttons we want are there */
    child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_OK_BUTTON);
    XtAddCallback(child, XmNactivateCallback, callSomeFunc, someArg);
    XtAddCallback(child, XmNactivateCallback, unManage, SomeDialog);
    XtManageChild(child);
    child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_APPLY_BUTTON);
    XtAddCallback(child, XmNactivateCallback, callSomeFunc, someOtherArg);
    XtManageChild(child);
    child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_CANCEL_BUTTON);
    XtAddCallback(child, XmNactivateCallback, dialogUnmanage, SomeDialog);
    XtManageChild(child);

    /* Add a new work area. This can be any manager. */
    child = XmCreateForm(SomeDialog, "someForm", NULL, 0);
    XtManageChild(child);

    /* and fill it up... */
    something = doYourStuff(child);



-------------------------------------------------------------------------------
Subject: 87) How come the title bars for my dialogs now have "_popup" or "<-
popup" concatenated onto the widget name?


Answer: Motif 1.0.3 (?) "fixed" things such that title bars without an explicit
dialogTitle setting use the widget name with "_popup" or whatever added on.  Set
the dialogTitle resource explicitly if you don't want this new default naming
scheme.

-------------------------------------------------------------------------------
Subject: 88) How can I force a dialog window to display?  I manage a "working"
dialog, and do some computing, but the dialog window appears blank until the
work has finished.  How can I force it to be displayed?

Answer: Use this.  (David Brooks, Systems Engineering, Open Software Foundation)

/*
 * This procedure will ensure that, if a dialog window is being mapped,
 * its contents become visible before returning.  It is intended to be
 * used just before a bout of computing that doesn't service the display.
 * You should still call XmUpdateDisplay() at intervals during this
 * computing if possible.
 *
 * The monitoring of window states is necessary because attempts to map
 * the dialog are redirected to the window manager (if there is one) and
 * this introduces a significant delay before the window is actually mapped
 * and exposed.  This code works under mwm, twm, uwm, and no-wm.  It
 * doesn't work (but doesn't hang) with olwm if the mainwindow is iconified.
 *
 * The argument to ForceDialog is any widget in the dialog (often it
 * will be the BulletinBoard child of a DialogShell).
 */

ForceDialog(w)
     Widget w;
{
  Widget diashell, topshell;
  Window diawindow, topwindow;
  Display *dpy;
  XWindowAttributes xwa;
  XEvent event;
  XtAppContext cxt;

/* Locate the shell we are interested in.  In a particular instance, you
 * may know these shells already.
 */

  for (diashell = w;
       !XtIsShell(diashell);
       diashell = XtParent(diashell))
    ;

/* Locate its primary window's shell (which may be the same) */

  for (topshell = diashell;
       !XtIsTopLevelShell(topshell);
       topshell = XtParent(topshell))
    ;

  if (XtIsRealized(diashell) && XtIsRealized(topshell)) {
    dpy = XtDisplay(topshell);
    diawindow = XtWindow(diashell);
    topwindow = XtWindow(topshell);
    cxt = XtWidgetToApplicationContext(diashell);

/* Wait for the dialog to be mapped.  It's guaranteed to become so unless... */

    while (XGetWindowAttributes(dpy, diawindow, &xwa),
           xwa.map_state != IsViewable) {

/* ...if the primary is (or becomes) unviewable or unmapped, it's
   probably iconified, and nothing will happen. */

      if (XGetWindowAttributes(dpy, topwindow, &xwa),
          xwa.map_state != IsViewable)
        break;

/* At this stage, we are guaranteed there will be an event of some kind.
   Beware; we are presumably in a callback, so this can recurse. */

      XtAppNextEvent(cxt, &event);
      XtDispatchEvent(&event);
    }
  }

/* The next XSync() will get an expose event if the dialog was unmapped. */

  XmUpdateDisplay(topshell);
}


-------------------------------------------------------------------------------
Subject: 89) How can I control placement of a popup widget?  Each time a popup
is created, it is placed in or over the middle of its parent.  How can I make it
obey the XmNx and XmNy values?

Answer: Set the resource XmNdefaultPosition for the popup to False.  Set the
position of the popup by the resource values of XmNx and XmNy.  Do not use
XtMoveWidget, as this is for widget writers only.  Here's a demo program from
Dan Heller:

/* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
 * This program is freely distributable without licensing fees and
 * is provided without guarantee or warranty expressed or implied.
 * This program is -not- in the public domain.  This program is
 * taken from the Motif Programming Manual, O'Reilly Volume 6.
 */

/* map_dlg.c -- Use the XmNmapCallback to automatically position
 * a dialog on the screen.  Each time the dialog is displayed, it
 * is mapped down and to the right by 200 pixels in each direction.
 */
#include <Xm/MessageB.h>
#include <Xm/PushB.h>

/* main() --create a pushbutton whose callback pops up a dialog box */
main(argc, argv)
char *argv[];
{
    Widget toplevel, button;
    XtAppContext app;
    void pushed();

    toplevel = XtVaAppInitialize(&app, "Demos",
        NULL, 0, &argc, argv, NULL, NULL);

    button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
        toplevel, NULL, 0);
    XtAddCallback(button, XmNactivateCallback, pushed, "Hello World");

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
}

/* callback function for XmNmapCallback.  Position dialog in 200 pixel
 * "steps".  When the edge of the screen is hit, start over.
 */
static void
map_dialog(dialog, client_data, cbs)
Widget dialog;
XtPointer client_data;
XmAnyCallbackStruct *cbs;
{
    static Position x, y;
    Dimension w, h;

    XtVaGetValues(dialog, XmNwidth, &w, XmNheight, &h, NULL);
    if ((x + w) >= WidthOfScreen(XtScreen(dialog)))
        x = 0;
    if ((y + h) >= HeightOfScreen(XtScreen(dialog)))
        y = 0;
    XtVaSetValues(dialog, XmNx, x, XmNy, y, NULL);
    x += 200, y += 200;
}

/* pushed() --the callback routine for the main app's pushbutton.
 * Create and popup a dialog box that has callback functions for
 * the Ok, Cancel and Help buttons.
 */
void
pushed(w, message)
Widget w;
char *message; /* The client_data parameter passed by XtAddCallback */
{
    Widget dialog;
    Arg arg[3];
    XmString t = XmStringCreateSimple(message);
    extern void response();

    XtSetArg(arg[0], XmNautoUnmanage, False);
    XtSetArg(arg[1], XmNmessageString, t);
    XtSetArg(arg[2], XmNdefaultPosition, False);
    dialog = XmCreateMessageDialog(w, "notice", arg, 3);
    XmStringFree(t);

    XtAddCallback(dialog, XmNmapCallback, map_dialog, NULL);

    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone);
}


-------------------------------------------------------------------------------
Subject: 90) TOPIC: LANGUAGE BINDINGS

-------------------------------------------------------------------------------
Subject: 91) Is there a C++ binding for Motif?

Answer: The University of Lowell had a C++ binding.  The software is available
on any system running X11R3. Currently it is available for both the GNU's C++
compiler g++ v 1.37.1 and the AT&T C++ v 2.0 translator. They do not support
this anymore (lack of funds).  The software is available through ftp 129.63.1.1
in file graphics/MotifC++/Motif1.1-g++.tar.Z A bug fixed version of the binding
can be found at decuac.dec.com (192.5.214.1) for anonymous ftp in
pub/X11/motif++.03.dec.91.tar.Z. This includes some somewhat useful test-
programs.

Or, upon request, by e-mail at the address below, which currently also is the
support/questions/bug-report address.

Ronald van Loon (rvloon@cv.ruu.nl) 3DCV Group, Utrecht, The Netherlands.




Answer: WWL is a library which defines C++ classes around X Toolkit Widgets.  It
is intended to simplify the task of C++ code writers when using the Toolkit by
providing them with C++ objects, methods, type checking and several utility
functions and classes.

WWL has been tested under SunOs4.0.3 on sun3 and sun4, HPUX version 6.5 and 7.0
and Ultrix 4.0 on DECstation 3100 and 5000. It is expected to work on most other
UNIX systems without too many problems.

WWL is distributed as a tar file with all the source, documentation and example.
The file is available using anonymous ftp from

        export.lcs.mit.edu (18.30.0.238   contrib/WWL-1.0.tar.Z
        lri.lri.fr (129.175.15.1)      pub/WWL-1.0.tar.Z


Rogue Wave Software has announced a C++ class library for Motif called View.h++.
It encapsulates 100% of Motif and X-Intrinsics.  It encapsulates OSF/Motif, it
doesn't emulate OSF/Motif.  View.h++ also includes Rogue Waves Tools.h++, the
foundation class library that is included with many C++ compilers.  If you would
like information on View.h++ call or fax

   Voice (503) 754-3010
   Fax   (503) 757-6650
   Rogue Wave Software
   P.O. 2328
   Corvallis, OR 97339


-------------------------------------------------------------------------------
Subject: 92) Is there a Common Lisp binding for Motif?  Answer: Try CLM. This
includes a toolkit demon (in C) that takes a widget description (with
callbacks), and forks a new process for each Motif application (which can be
just a single menu, or whatever).  Lisp can then continue running, with a
separate lightweight lisp process handling the connection & callbacks.  In North
America & net environs, CLM-2.0beta is available from export.lcs.mit.edu.

-------------------------------------------------------------------------------
Subject: 93)* Is there an Ada binding for Motif?

Answer:

From Todd W. Lainhart: Take a look at THINGS, a VAPI with Ada bindings that was
written by the US Air Force (SAC).  It's in the public domain, and available
from export or gatekeeper.dec.com.  It implements Motif or OL look-and-feel. [I
had a look and it seemed to be missing documentation - Jan]

From David Lewis: A company called Rational appears to be making an Xm
implementation.  Also GHG in Texas has most other Xlib and Xt bindings for Ada.

From comp.windows.x FAQ: Ada bindings to Motif, explicitly, will eventually be
made available by the Jet Propulsion Laboratories, probably through the normal
electronic means.  Advance information can be obtained from
dsouleles@dsfvax.jpl.nasa.gov, who may respond as time permits.  Another set of
bindings for Motif is being done by the University of Lowell; information is
available from osfri@osf.org.[11/90]

TeleSoft has bindings for Motif, Xt and Xlib.  They are called TeleWindows.
Contact their customer support department for more information.

     TeleSoft
     5959 Cornerstone Court West
     San Diego, CA 92121-9891
     +1 619-457-2700
     +1 619-452-1334 Fax

     Email: adasales@telesoft.com (Sales)
            adasupport@telesoft.com (Customer Support)


TAE Plus will generate either Ada or C. Contact

        Goddard Space Flight Center
        TAE Suppport Office
        Code 522
        Attn: Arleen Yeager
        Greenbelt, MD  20771
        301-286-6034
        FTS 888-6034

        e-mail:  taeso@postman.gsfc.nasa.gov

        TELEMAIL from a NASA facility:      TELEMAIL outside of NASA:
        [TAESO/GSFCMAIL]GSFC                [TAESO/GSFCMAIL]GSFC/USA
        SPAN is 6162::TAESO

SA-Motif is a complete binding to X Window and Motif for the Ada; it is based in
part upon the SAIC/Unisys bindings. SA-Motif is available on the Sun3, Sun4,
SCO, HPUX, and SGI IRIX. Info: Systems Engineering Research Corporation, 2348
Leghorn Street, #202/Mountain View, CA 94043/1-800-Ada-SERC
(well!serc@apple.com).



-------------------------------------------------------------------------------
Subject: 94) TOPIC: SPECIFIC PLATFORMS

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

Subject: 95) Is it easy to build Motif for a Sun?

Answer: No pattern has emerged to problems about compiling Motif on the Sun
(although people seem to have a lot of different minor problems), and many
reports are that it is straightforward. Read the Motif install instructions
(which often have specific reference to Sun installation), light the blue touch
paper and just standback. [My experience was that I had to add -D_NO_PROTO for
1.1 on a Sparc OS 4.1, and that was all.  Others have added STRINGS_ALIGNED and
NO_REGEXP].


-------------------------------------------------------------------------------
Subject: 96) What compile errors/warnings might I get in both Sun 3 and Sun 4?

Answer:


make: Warning: Too many rules defined for target
make: Warning: Too many rules defined for target
"callbacks.c", line 1530: warning: illegal combination of pointer
and integer, op =
"callbacks.c", line 1531: warning: illegal combination of pointer
and integer, op =
"callbacks.c", line 1532: warning: illegal combination of pointer
and integer, op =
"utils.c", line 73: warning: illegal combination of pointer and integer, op =
"utils.c", line 74: warning: illegal combination of pointer and integer, op =
"utils.c", line 122: warning: illegal combination of pointer and integer, op =
"utils.c", line 123: warning: illegal combination of pointer and integer, op =
"utils.c", line 191: warning: illegal combination of pointer and integer, op =
"utils.c", line 194: warning: illegal combination of pointer and integer, op =
"utils.c", line 195: warning: illegal combination of pointer and integer, op =
"utils.c", line 196: warning: illegal combination of pointer and integer, op =
"utils.c", line 316: warning: illegal combination of pointer and integer, op =
"utils.c", line 334: warning: illegal combination of pointer and integer, op =
"utils.c", line 338: warning: illegal combination of pointer and integer, op =
"utils.c", line 341: warning: illegal combination of pointer and integer, op =
"xmdialogs.c", line 838: warning: illegal combination of pointer
and integer, op =
"xmeditor.c", line 1152: warning: illegal combination of pointer
and integer, op =

These warning messages can be ignored. OSF is aware of these warnings.


-------------------------------------------------------------------------------
Subject: 97) On a Sun 3, what are the mwm startup error messages about?  I get

mwm: Invalid accelerator specification on line 7 of
     specification string
mwm: Invalid accelerator specification on line 31 of
      configuration file


Answer: This is because some Sun keyboards do not have an F10 key and some sun
workstations which have an F10 key do not have X-servers which recognize it.
The F10 key is used by mwm.  If the machine does have an F10 key, the user
should use xmodmap to tell the server it exists.  Otherwise, change the
definition of the DefaultWindowMenu in /usr/lib/X11/system.mwmrc (after
installation) or in /lib/clients/mwm/system.mwmrc (before installation). Change
the accelerator of "Maximize" (it is "Alt<Key>F10)" to something else. Also, you
should change the definition of DEFAULTSYSTEMMENU in the file
/clients/mwm/WmResource.c in a similar fashion.  There is as yet no standard
redefinition for F10.



-------------------------------------------------------------------------------
Subject: 98) Are there problems making shared libraries on a Sun?

Answer: If you use the -pic option you may run out of offset table space.  use
the -PIC option instead.

You may get the message "ld.so: Undefined symbol: __XtInherit" when executing
UIL. There is a problem in shared library build when you compare a function
variable to a routine name, but don't call the routine.  Either, you can build
the Xt library nonshared, or you can put a reference to XtToolkitInitialize in
the UIL main program (or even include a module that references it).  The routine
doesn't even have to be called; it just has to be there.


-------------------------------------------------------------------------------
Subject: 99) Has anyone made shared libraries on an IBM RS/6000?

Answer: From Sakari Jalovaara: There is a problem: Xm redefines VendorShell and
the AIX linker put _both_ Xm's and Xt's VendorShell into programs.  When an AIX
shared library is created as many references inside the library are resolved as
possible.  If the symbol vendorShellClassRec is defined in libXt and referenced,
say, from a function XtFoo() also in libXt, the "ld" run that creates the shared
library resolves the reference:

        XtFoo() -> vendorShellClassRec

Then I create the Motif library that has its own vendorShellClassRec and an
XmBar() function that uses it; libXm will also contain a resolved reference to
vendorShellClassRec:

        XmBar() -> vendorShellClassRec

Finally, I link a program that uses both XtFoo() and XmBar() and the program
will end up with _two_ independent "vendorShellClassRec"s:

        XtFoo() -> vendorShellClassRec [Xt version]
        XmBar() -> vendorShellClassRec [Xm version]

Instant schizo zaphod mode.  In reality, vendorShellClassRec is not referenced
from functions but from other widget class records.

I can't just pull Vendor.o out from the shared Xt (Vendor.o appears to define
the only external symbols redefined by libXm) because AIX shared libraries
apparently can't contain unresolved external references.  If I take out Vendor.o
I have to take out every other file that uses symbols defined there - and then
files that need those files, etc.  I tried it and ended up with three or four
object files in libXt and the res non-sharable.

I kludged around this by putting all of libXt (minus Vendor.o) into the shared
libXm.  It isn't a pretty solution but it works - and beats having a statically
linked two-megabyte "periodic" demo...


-------------------------------------------------------------------------------
Subject: 100)  What is the error  "Unaligned access in XmString" under Ultrix?

Answer: Compile  XmString.c with STRINGS_ALIGNED.

-------------------------------------------------------------------------------
Subject: 101) TOPIC: KEYSYMS

-------------------------------------------------------------------------------
Subject: 102)* What is causing the messages "unknown keysym osfDown..."?  It
happens when I run an application under Motif 1.1

Answer: There is an OSF supplied addition to the /usr/lib/X11/XKeysymDB file.
It is found on the release tape and should have been automatically installed if
the installation procedure was followed in the Release Notes.

You have to copy (or append) lib/Xm/XKeysymDB into /usr/lib/X11.  This may
require root permission.  It is not clear how to fix the problem if you can't do
this.  The error comes from Xt translation table parsing and can't be fixed in
Motif, so if you can't get root permission you may be stuck.  The file is not
copyrighted so you can install it on other systems.

If X has been built so that XKeysymDB is not in this directory, and you don't
know where it is looking, run 'strings libX11.a | grep XKeysymDB' to find the
path.

On a Sun running openwin with shared libraries, you may need to put the path for
the library containing XKeysymDB *first* in the path list in LD_LIBRARY_PATH, or
it may find the wrong XKeysymDB in the wrong directory.

XKeysymDB simply contains the registered keysym values for the OSF keysyms.  The
OSF values are server-independent.  And, all registered keysyms will be included
in an XKeysymDB file to be shipped with X11R5.

In the meantime (till all systems are X11R5+), a list of the registered keysyms
can be found in the X11R4 release in mit/doc/Registry/Xregistry.



-------------------------------------------------------------------------------
Subject: 103) What happens if I can't install Motif Keysyms?

From: tessi!george@nosun.West.Sun.COM (George Mitchell)

Here's what appears to happen if you don't have XKeysymDB in place to define
OSF's virtual keysyms:

1. At class initialize time, for a widget (such as XmText) that uses virtual
keysyms in its event translation table, all entries which refer to those keysyms
fail to parse correctly.  In the case of XmText, instead of ending up with a
translation table with roughly 90 entries, you end up with one that has 29.

2. XKeysymDB doesn't exist, so you'd assume that KeyPress events will get
translated to plain vanilla keysyms, right?  WRONG!  All Motif widgets install a
virtual keysym translator ANYWAY!  Consequently, the backspace key (for example)
gets translated to the keysym osfBackSpace.

3. Therefore, if you augment or override your widget's translations with
translations that refer to plain vanilla BackSpace, they will never be
triggered, because you will NEVER see plain vanilla BackSpace, only
osfBackSpace.

4. But you can't use osfBackSpace in an event translation entry, because you
don't have XKeysymDB installed!

Here's how I'm "dealing" with the problem right now: Motif installs its virtual
keysym translator by calling XtSetKeyTranslator every time a VendorShell (or
subclass) widget is created.  So every time I create a shell, I immediately call
XtSetKeyTranslator (display, XtTranslateKey) to restore the default translator.
No more funny virtual keysyms!  Now I can reinstall non-osfKeySym translations
and have them work the way I expect.


-------------------------------------------------------------------------------
Subject: 104) Why has OSF introduced Keysyms into Motif 1.1?  They weren't there
in Motif 1.0.

Answer: From: ellis@osf.org

Virtual Keysyms are meant to provide a consistent keyboard model for Motif
applications running in a heterogeneous environment in which proprietary (i.e.
vendor specific) non-Motif applications may also be running.

First of all, for the sake of the rest of the readers, let's explain why this is
an issue:

It would be lovely if Motif's translation tables could just use the obvious
keysyms predefined by X.  For example, there are keysyms for XK_BackSpace,
XK_Delete, XK_Left, XK_Right, etc.  Shouldn't these be the ones that are used in
our translations?  Unfortunately, the problem is not so simple.  Some specific
examples:

   While most vendors bind XK_BackSpace to the key at the top right
   of the standard keyboard (often engraved with a leftwards
   pointing arrow), not all do.  In fact, some vendors (including DEC)
   bind that key to XK_Delete.

   While most vendors bind the arrow keys to XK_Up, etc, a number of
   vendors (including Sun, on some servers) bind them to function key
   keysyms.

A simplistic solution would require the use of xmodmap to change the offending
bindings.  That would work swell in an all Motif environment.  However, OSF's
goal (not always perfectly achieved) is interoperability.  That is, we'd like to
make sure that both Motif and non-Motif programs can happily run in the same
environment.

It is expected that a vendor may have a wide variety of existing X-based
software that uses the keysyms as established by that vendor for specific
purposes.  It is expected that these applications may run at the same time as
Motif-based software.  Using xmodmap to change keysyms on the server side could
"break" the existing applications (or at the very least their documentation) by
making some keys unavailable, or by moving the location.

So, we chose not to use xmodmap.  By the way, though OpenLook uses a different
implementation (they recompile their virtual translation tables into actual
translation tables), they basically adopted the same approach, presumably for
similar reasons.

To work properly, the virtual keysym model we implemented depends on Xlib
finding XKeysymDB installed appropriately (which standard Motif installation
does).  This simply defines the keysyms (not the key they are bound to).  This
unfortunate piece of stupidity is necessary because MIT only includes standard
keysyms in keysymdef.h.  It should be said that our lives would be made easier
if MIT would also see fit to include registered keysyms in keysymdef.h as well.

Motif applications determine how to bind virtual to actual keys by looking for
either a resource or a property on the root window which describes what to do.
Note that this information is on the server side, so that all applications use
the same virtual bindings regardless of where they are running.  Mwm will
happily create the property if it finds a .motifbind file in your home directory
when it starts up.  (Actually, things generally work even if none of this is
done, since if all else fails, the Motif toolkit chooses a virtual bindings
table to use based on the identification of the server).

The actual implementation of virtual keys is made possible by a hook in the
Intrinsics.  Undoubtably, the implementation would be simpler and cleaner if
virtual key support was more directly supported by the Intrinsics.  We will be
exploring this possibility in the future.

  -- Ellis

-------------------------------------------------------------------------------
END OF PART FOUR