From: jan@ise.canberra.edu.au (Jan Newmarch)
Newsgroups: comp.windows.x.motif,mail.alfalfa.motif
Subject: Frequently Asked Questions about Motif (Part 3 of 4)
Keywords: FAQ question answer
Date: 8 Apr 92 15:24:31 GMT
Expires: Mon, 8 Jun 1992 15:24:31 GMT
Reply-To: jan@ise.canberra.edu.au (Jan Newmarch)
Followup-To: comp.windows.x.motif
Organization: ise.canberra.edu.au

Archive-name: motif-faq-3
Last-modified: Wed Apr 8 1992
Version: 2.4


-------------------------------------------------------------------------------
Subject: 70) TOPIC: INPUT FOCUS

-------------------------------------------------------------------------------
Subject: 71) How can I direct the keyboard input to a particular widget?

Answer: In Motif 1.1 call XmProcessTraversal(target, XmTRAVERSE_CURRENT).  The
widget (and all of its ancestors) does need to be realized BEFORE you call this.
Otherwise it has no effect.  XmProcessTraversal is reported to have many bugs,
so it may not work right.  A common occurrence is that it doesn't move to the
widget, but if you call XmProcessTraversal *twice* in a row, it will.  If you
can't get it to work, try this from Kee Hinckley:

    // This insane sequence is as follows:
    //      On manage set up a focus callback
    //      On focus callback set up a timer (and get rid of focus callback!)
    //      On timer set the focus (which only works if the parent
    //      has the focus,
    //      which is why we went through all of this garbage)
    // There may be a better way, but I haven't time to try it now.
    //
    static void focusTO(void *data, XtIntervalId *) {
        XmProcessTraversal((Widget) data, XmTRAVERSE_CURRENT);
    }

    static void focusCB(Widget w, XtPointer data, XtPointer) {
        XtRemoveCallback(w, XmNfocusCallback, focusCB, data);
        XtAppAddTimeOut(XtWidgetToApplicationContext(w), 0, focusTO, data);
    }

    void OmXSetFocus(Widget parent, Widget w) {
        XtAddCallback(parent, XmNfocusCallback, focusCB, w);
    }


In Motif 1.0 call the undocumented _XmGrabTheFocus(target).

Do not use the X or Xt calls such as XtSetKeyboardFocus since this bypasses the
Motif traversal layer and can cause it to get confused.  This can lead to odd
keyboard behaviour elsewhere in your application.

-------------------------------------------------------------------------------
Subject: 72)* How can I have a modal dialog which has to be answered before the
application can continue?

Answer: The answer depends on whether you are using the Motif window manager mwm
or not.  Test for this by XmIsMotifWMRunning.

The window manager mwm knows how to control event passing to dialog widgets
declared as modal. If the dialog is set to application modal, then no
interaction with the rest of the application can occur until the dialog is
destroyed or unmanaged.

Use the appropriate code in the following program.  There is followup discussion
after the program.


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

/*
 * ask_user.c -- create a pushbutton that posts a dialog box
 * that asks the user a question that requires an immediate
 * response.  The function that asks the question actually
 * posts the dialog that displays the question, waits for and
 * returns the result.
 */
#include <X11/Intrinsic.h>
#include <Xm/DialogS.h>
#include <Xm/SelectioB.h>
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xm/PushBG.h>
#include <Xm/PushB.h>

XtAppContext app;

#define YES 1
#define NO  2

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

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

    label = XmStringCreateSimple("/bin/rm *");
    button = XtVaCreateManagedWidget("button",
        xmPushButtonWidgetClass, toplevel,
        XmNlabelString,          label,
        NULL);
    XtAddCallback(button, XmNactivateCallback,
        pushed, "Remove Everything?");
    XmStringFree(label);

    XtRealizeWidget(toplevel);
    XtAppMainLoop(app);
}

/* pushed() --the callback routine for the main app's pushbutton. */
void
pushed(w, question)
Widget w;
char *question;
{
    if (AskUser(w, question) == YES)
        puts("Yes");
    else
        puts("No");
}

/*
 * AskUser() -- a generalized routine that asks the user a question
 * and returns the response.
 */
AskUser(parent, question)
char *question;
{
    static Widget dialog;
    XmString text, yes, no;
    static int answer = 0;
    extern void response();

    if (!dialog) {
        dialog = XmCreateQuestionDialog(parent, "dialog", NULL, 0);
        yes = XmStringCreateSimple("Yes");
        no = XmStringCreateSimple("No");
        XtVaSetValues(dialog,
            XmNdialogStyle,        XmDIALOG_APPLICATION_MODAL,
            XmNokLabelString,      yes,
            XmNcancelLabelString,  no,
            NULL);
        XtSetSensitive(
            XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False);
        XtAddCallback(dialog, XmNokCallback, response, &answer);
        XtAddCallback(dialog, XmNcancelCallback, response, &answer);
    }
    text = XmStringCreateSimple(question);
    XtVaSetValues(dialog,
        XmNmessageString,      text,
        NULL);
    XmStringFree(text);
    XtManageChild(dialog);
    XtPopup(XtParent(dialog), XtGrabNone);

    /* while the user hasn't provided an answer, simulate XtMainLoop.
     * The answer changes as soon as the user selects one of the
     * buttons and the callback routine changes its value.  Don't
     * break loop until XtPending() also returns False to assure
     * widget destruction.
     */
    while (answer == 0 || XtAppPending(app))
        XtAppProcessEvent(app, XtIMAll);
    return answer;
}

/* response() --The user made some sort of response to the
 * question posed in AskUser().  Set the answer (client_data)
 * accordingly and destroy the dialog.
 */
void
response(w, answer, reason)
Widget w;
int *answer;
XmAnyCallbackStruct *reason;
{
    switch (reason->reason) {
        case XmCR_OK:
            *answer = YES;
            break;
        case XmCR_CANCEL:
            *answer = NO;
            break;
        default:
            return;
    }
}



If you aren't running a window manager that acknowledges this hint, then you may
have to grab the pointer (and keyboard) yourself to make sure the user doesn't
interact with any other widget.  Change the grab flag in XtPopup to
XtGrabExclusive, and XtRemoveGrab(XtParent(w)) to the response() function.


-------------------------------------------------------------------------------
Subject: 73) TOPIC: MEMORY AND SPEED

-------------------------------------------------------------------------------
Subject: 74)* Why does my application grow in size?

Answer: Motif 1.0 has many memory leaks, particularly in XmString manipulation.
Switch to Motif 1.1.

Answer: The Intrinsics have a memory leak in accelerator table management, and
Motif uses this heavily.  Avoid this by mapping/unmapping widgets rather than
creating/destroying them, or get  X11R4 fix-15/16/17.

Answer: The server may grow in size due to its own memory leaks.  Switch to a
later server.

Answer: You are responsible for garbage collection in `C'.  Some common cases
where a piece of memory becomes garbage are

 a.  Memory is allocated by Motif for XmStrings by the functions XmStringConcat,
     XmStringCopy, XmStringCreate, XmStringCreateLtoR, XmStringCreateSimple,
     XmStringDirectionCreate, XmStringNConcat, XmStringNCopy,
     XmStringSegmentCreate, and XmStringSeparatorCreate.  The values returned by
     these functions should be freed using XmStringFree when they are no longer
     needed.

 b.  Memory is allocated by Motif for ordinary character strings (of type
     String) by Motif in XmStringGetLtoR, XmStringGetNextComponent, and
     XmStringGetNextSegment. After using the string, XtFree() it. [Note that
     XmStrings and Strings are two different data types.  XmStrings are
     XmStringFree'd, Strings are XtFree'd.]

 c.  If you have set the label (an XmString) in a label, pushbutton, etc widget,
     free it after calling XtSetValues() or the widget creation routine by
     XmStringFree().

 d.  If you have set text in a text widget, the text widget makes its own copy.
     Unless you have a use for it, there is no need to keep your own copy.

 e.  If you have set the strings in a list widget the list widget makes its own
     copy.  Unless you have a use for it, there is no need to keep your own
     copy.

 f.  When you get the value of a single compound string from a Widget e.g.
     XmNlabelString, XmNmessageString, ... Motif gives you a copy of its
     internal value.  You should XmStringFree this when you have finished with
     it.

 g.  On the other hand, when you get a value of a Table e.g. XmStringTable for a
     List, you get a *pointer* to the internal Table, and should not free it.

 h.  When you get the value of the text in a widget by XmTextGetString or from
     the resource XmNvalue, you get a copy of the text.  You should XtFree this
     when you have finished with it.

-------------------------------------------------------------------------------
Subject: 75)* Why does my application take a long time to start up?

Answer: You are probably creating too many widgets at startup time.  Delay
creating them until needed.  If you have a large number of resources in text
files (such as in app-defaults), time may be spent reading and parsing it.

-------------------------------------------------------------------------------
Subject: 76) My application is running too slowly. How can I speed it up?

Answer: Use the R4 rather than R3 server.  It is much faster.

Answer: The standard memory allocator is not well tuned to Motif, and can
degrade performance.  Use a better allocator.  e.g. with SCO Unix, link with
libmalloc.a; use the allocator from GNU emacs; use the allocator from Perl.

Answer: Avoid lots of widget creation and destruction.  It fragments memory and
slows everything down.  Popup/popdown, manage/unmanage instead.

Answer: Set mappedWhenManaged to FALSE, and then call XtMapWidget()
XtUnmapWidget() rather than managing.

Answer: Get more memory - your application, the server and the Operating System
may be spending a lot of time being swapped.

Answer: If you are doing much XmString work yourself, such as heavy use of
XmStringCompare, speed may deteriorate due to the large amount of internal
conversions and malloc'ing.  Try using XmStringByteCompare if appropriate or
ordinary Ascii strings if you can.



-------------------------------------------------------------------------------
Subject: 77) TOPIC: XMSTRING

-------------------------------------------------------------------------------
Subject: 78) 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: 79) 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: 80) 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: 81) TOPIC: DIALOGS

-------------------------------------------------------------------------------
Subject: 82) 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: 83) 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: 84) 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: 85) 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: 86)* 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 warrantee 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: 87) TOPIC: LANGUAGE BINDINGS

-------------------------------------------------------------------------------
Subject: 88)* 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: 89) 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: 90)* 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 is reported to be in the process of negotiating an agreement to license
and distribute OSF/Motif Ada bindings with delivieries beginning in June
(anticipated). The person to contact is:

      Bruce Sherman
      Vice President
      Corporate Communications for Telesoft
      5959 Conerstone Court West
      San Diego, CA  92121-9891
      (619)457-2700
      Fax (619)452-1334
      email: ucsd!telesoft!bds


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: 91) TOPIC: SPECIFIC PLATFORMS

-------------------------------------------------------------------------------
Subject: 92)* 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: 93) 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: 94) 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: 95) 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: 96) 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]

Instand 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: 97) TOPIC: KEYSYMS

-------------------------------------------------------------------------------
Subject: 98) 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.

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: 99) 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: 100) 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 pefectly 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 regrdless 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 implmentation 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