home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-25 | 59.1 KB | 1,653 lines |
- Subject: Motif FAQ (Part 6 of 6)
- Newsgroups: comp.windows.x.motif,comp.answers,news.answers
- From: ksall@cen.com (Ken Sall)
- Date: 11 Oct 1994 07:52:13 GMT
-
- Archive-name: motif-faq/part6
- Last-modified: OCT 10, 1994
- Posting-Frequency: monthly
- Organization: Century Computing, Inc.
- Version: 3.8
-
-
-
- -----------------------------------------------------------------------------
- Subject: 173) TOPIC: MISCELLANEOUS
-
- -----------------------------------------------------------------------------
- Subject: 174)* How can an application be informed of signals?
-
- Answer: blackman@hodgkin.med.upenn.edu (David Blackman) writes:
-
- According to comp.windows.x FAQ, you shouldn't make Xt/Xlib calls from a Unix
- signal handler:
-
- "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."
-
- Kaleb KEITHLEY (fedora.x.org!kaleb) adds:
-
- Xt is not reentrant and it is not safe to call any Xt functions from a signal
- handler... I think [the signaling] technique is covered in the [X] FAQ. On
- most POSIX-type systems write(2) is guaranteed to be reentrant and atomic. If
- you establish a simple pipe with the pipe(2) system call, and add it as an
- XtInput with XtAppAddInput(), then you can write to the pipe in the signal
- handler. Xt will notice that input is available and call the input-handler
- proc. This technique is inherently better than setting the flag because the
- write to the pipe will result in XtAppNextEvent returning immediately without
- the latency you observe in using the flag technique. In R6 you can use the
- XtAppAddSignal function.
-
- Ken Sall (ksall@cen.com) adds: See the "Signal Handling" chapter of "Motif
- Programming Manual" by Heller and Ferguson, listed in the BOOKS topic.
-
- Paul Davey (pd@uit.co.uk) adds: The write and XtAppAddInput input method is
- often the best - but be warned it does not work on some SVR3 based Unixes,
- where a pipe may not be selected on. SCO Unix exhibits this behaviour so here
- the external flag method should be used.
-
- -----------------------------------------------------------------------------
- Subject: 175) How do I control the repeat rate on a SUN keyboard ??
-
-
- Answer:
-
- [...]
-
- -ar1 milliseconds
- This option specifies amount of time in milliseconds
- before which a pressed key should begin to
- autorepeat.
-
- -ar2 milliseconds
- This option specifies the interval in milliseconds
- between autorepeats of pressed keys.
-
- Of course this presumes you're using a server based on the MIT sample server.
-
- Thanks to kaleb@x.org (Kaleb Keithley)
-
- -----------------------------------------------------------------------------
- Subject: 176) How can I identify the children of a manager widget?
-
- Answer: XmNnumChildren (number of widgets in array).
-
- -----------------------------------------------------------------------------
- Subject: 177) How do I tell if a scrolled window's scrollbars are visible?
-
- Answer: Use XtGetValues() to get the scrollbar widget ID's, then use
- XtIsManaged() to see if they are managed (visible).
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 178) How can I programatically scroll a XmScrolledWindow in
- XmAUTOMATIC mode?
-
- Answer: In Motif 1.2, use XmScrollVisible(). If you're using a scrolled text
- or scrolled list combination widget, use XmTextScroll() or XmListSet*()
- instead.
-
- The Motif manuals specifically forbid manipulating the scrollbars directly,
- but some people have reported success with XmScrollBarSetValues, with the
- "notify" parameter set to "True".
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 179) What functions can an application use to change the size or
- position of a widget?
-
- Answer: Applications should set the values of the XmNx, XmNy, XmNwidth, and
- XmNheight resources.
-
- Note that many manager widgets ignore the XmNx and XmNy resources of their
- children, relying instead on their internal layout algorithms. If you really
- want specific positions, you must use a manager widget that allows them, e.g.,
- XmBulletinBoard.
-
- Also note that some manager widgets reject size change requests from their
- children when certain resources are set (e.g., XmNresizable on XmForm).
- Others allow the the children to resize, but clip the results (e.g.,
- XmNallowShellResize on shell widgets). Make sure you have these resources set
- to the policy you want.
-
- Due to bugs, some widgets (third party widgets) do not respond to changes in
- their width and height. Sometimes, you can get them to respond correctly by
- unmanaging them, setting the resources, then managing them again.
-
- Under no circumstances should applications use routines like
- XtConfigureWidget() or XtResizeWidget(). These routines are reserved for
- widget internals and will seriously confuse many widgets.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 180) What widgets give the look of push buttons, but behavior of
- toggle buttons?
-
- Answer: Use the XmToggleButton widget, setting XmNindicatorOn to False and
- XmNshadowThickness to 2.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- Also set XmNfillOnSelect to True. Otherwise, the background color of the
- button will not stay in the "armed" state.
-
- thanks to Glenn McMillen, mcmillen@meadow.mdso.vf.ge.com
-
- In Motif 1.2 (and later), if you specify a XmNselectColor and set
- XmNindicatorOn to False, then you need to set XmNfillOnSelect to True.
- XmNfillOnSelect is not necessary if you are not setting a XmNselectColor.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
-
- -----------------------------------------------------------------------------
- Subject: 181) How do I obtain the size of a unmanaged shell widget?
-
- Answer: In the code below, use getsize() for widgets which have been managed,
- and getsize2() for newly created shell widgets which have not yet been
- managed.
-
- getsize2() takes two widget parameters because popup dialogs etc. _consist_
- of two separate widgets - the parent shell and the child bulletin board, form,
- whatever. This important distinction (somewhat glossed over in the Motif
- manuals) is the cause of a large number of queries in comp.windows.x.motif.
- XmCreate...Dialog() functions return the (bulletin board, form, whatever)
- _child_ of the pair, not the parent shell.
-
- getsize2() takes the _shell_ widget as it's first parameter, and the shell's
- _child_ (the bulletin board, form, whatever) as it's second. Thus, if you are
- using code like widget = XmCreate...Dialog() to create your popup dialogs, use
- code like getsize2(XtParent(widget),widget,&width,&height) to get the width
- and height. If you use e.g. XmCreateDialogShell() or XtCreatePopupShell(),
- then you are creating the the shell widget and it's child explicitly, and can
- just pass them into getsize2() with no problem.
-
- Note: getsize2() calls getsize().
-
- /* getsize(widget,width,height);
- * Widget widget;
- * int *width,*height;
- *
- * returns the width and height of a managed widget */
-
-
- void getsize(l,w,h) Widget l; int *w,*h; { Dimension w_,h_,b_;
-
- static Arg size_args[] =
- {
- { XmNwidth,0 },
- { XmNheight,0 },
- { XmNborderWidth,0 },
- };
-
- size_args[0].value = (XtArgVal)&w_; size_args[1].value = (XtArgVal)&h_;
- size_args[2].value = (XtArgVal)&b_;
-
- XtGetValues(l,size_args,3);
-
- if (w) *w = w_ + b_; if (h) *h = h_ + b_; } /*
- getsize2(shell,child,width,height);
- * Widget shell,child;
- * int *width,*height;
- *
- * returns the width, height of an unmanaged shell widget */
-
- void getsize2(p,c,w,h) Widget p,c; int *w,*h; { XtSetMappedWhenManaged(p,0);
-
- XtManageChild(c);
-
- getsize(p,w,h);
-
- XtUnmanageChild(c);
-
- XtSetMappedWhenManaged(p,-1); } submitted by: [ Huw Rogers Communications
- Software Engineer, NEC Corporation, Tokyo, Japan ] [ Email:
- rogersh@ccs.mt.nec.co.jp Fax: +81-3-5476-1005 Tel: +81-3-5476-1096 ]
-
- -----------------------------------------------------------------------------
- Subject: 182) Can I use XtAddTimeOut, XtAddWorkProc, and XtAddInput with
- XtAppMainLoop?
-
- Answer: On many systems, the obsolete XtAdd*() functions are not compatible
- with the XtAppMainLoop(). Instead, you should use newer XtAppAddTimeOut(),
- XtAppAddWorkProc(), and XtAppAddInput() functions with XtAppMainLoop()
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 183) Why does XtGetValues for XmNx and XmNwidth return extremely
- large values?
-
- Answer: You must use the 16 bit "Dimension" and "Position" data types for your
- arguments. If you use 32 bit integers, some implementations will fill the
- remaining 16 bits with invalid data, causing incorrect return values. The
- *Motif Programmer's Manual* and the widget man pages specify the correct data
- type for each resource.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 184) XtGetValues() on XmNx and XmNy of my top level shell don't
- return the correct root window coordinates. How do I compute these?
-
- Answer: XmNx and XmNy are the coordinates relative to your shell's parent
- window, which is usually a window manager's frame window. To translate to the
- root coordinate space, use XtTranslateCoords() or XTranslateCoordinates().
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 185) Can I use XmGetPixmap() with widgets that have non-default
- visual types?
-
- Answer: If you're using a different depth, use XmGetPixmapByDepth() instead.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 186) How can I determine the item selected in a option menu or a
- RadioBox?
-
- Answer: The value of the XmNmenuHistory resource of the XmRowColumn parent is
- the widget ID of the last selected item. It works the same way for all menus
- and radio boxes.
-
- Thanks to Ken Lee, kenton@allegro.esd.sgi.com
-
- -----------------------------------------------------------------------------
- Subject: 187) What is the matter with Frame in Motif 1.2?
-
- [Last modified: November 92]
-
- Answer: This announcement has been made by OSF:
-
- "IMPORTANT NOTICE
-
- We have discovered two problems in the new 1.2 child alignment resources in
- XmFrame. Because some vendors may have committed, or are soon to commit to
- field releases of Motif 1.2 and 1.2.1, OSF's options for fixing them are
- limited. We are trying to deal with these in a way that does not cause
- hardship for application developers who will develop applications against
- various point versions of Motif. OSF's future actions for correction are
- summarized.
-
- WHAT YOU SHOULD DO AND KNOW
-
- 1. Mark the following change in your documentation.
-
- On page 1-512 of the OSF/Motif Programmer's Reference, change the descriptions
- under XmNchildVerticalAlignment as follows (what follows is the CORRECT
- wording to match the current implementation):
-
- XmALIGNMENT_WIDGET_TOP
- Causes the BOTTOM edge of the title area to align
- vertically with the top shadow of the Frame.
-
- XmALIGNMENT_WIDGET_BOTTOM
- Causes the TOP edge of the title area to align
- vertically with the top shadow of the Frame.
-
- 2. Note the following limitation on resource converters for Motif 1.2 and
- 1.2.1 implementations.
-
- The rep types for XmFrame's XmNentryVerticalAlignment resource were
- incorrected implemented, which means that converters will not work properly.
- The following resource settings will not work from a resource file in 1.2 and
- 1.2.1:
-
- *childVerticalAlignment: alignment_baseline_bottom
- *childVerticalAlignment: alignment_baseline_top
- *childVerticalAlignment: alignment_widget_bottom
- *childVerticalAlignment: alignment_widget_top
-
- If you wish to set these values for these resources (note they are new
- constraint resources in XmFrame) you will have to set them directly in C or
- via uil.
-
- WHAT WE WILL DO
-
- The problem described in note #1 above will not be fixed in the OSF/Motif
- implementation until the next MAJOR release of Motif. At that time we will
- correct the documentation and modify the code to match those new descriptions,
- but we will preserve the existing enumerated values and their behavior for
- backward compatibility for that release.
-
- The fix for the problem described in note #2 will be shipped by OSF in Motif
- 1.2.2.
-
- SUMMARY
-
- We are sorry for any difficulty this causes Motif users. If you have any
- questions or flames (I suppose I deserve it) please send them directly to me.
- We sincerely hope this proactive response is better for our customers than you
- having to figure it out yourselves!
-
- Libby
-
-
- -----------------------------------------------------------------------------
- Subject: 188) What is IMUG and how do I join it?
-
- Answer: IMUG is the International Motif User Group founded by Quest Windows
- Corporation and co-sponsored by FedUNIX. IMUG is a non-profit organization
- working to keep users informed on technical and standards issues, to
- strengthen user groups on a local level, to increase communication among users
- internationally, and to promote the use of an international conference as a
- forum for sharing and learning more about Motif. You can join it by
-
- 1. Pay the annual membership fee of $20 USD directly to IMUG. Contact
-
- IMUG
- 5200 Great America Parkway
- Santa Clara, CA 95054
- (408) 496-1900
- imug@quest.com
-
- 2. Register at the International Motif User Conference, and automatically
- become an IMUG member.
-
- 3. Donate a pd widget, widget tool or widget builder to the IMUG Widget
- Depository and receive a free one year IMUG membership.
-
-
- -----------------------------------------------------------------------------
- Subject: 189) How do I set the title of a top level window?
-
- [Last modified: September 92]
-
- Answer: Set XmNtitle (and optionally XmNtitleEncoding) for TopLevelShells.
- (Note that this is of type String rather than XmStrin.) Ypu can also set
- XmNiconName if you want its icon to show this title. For XmDialogShells, set
- the XmNdialogTitle of its immediate child, assuming it's a BulletinBoard
- subclass. These can also be set in resource files.
-
-
- -----------------------------------------------------------------------------
- Subject: 190) Can I use editres with Motif?
-
- [Last modified: Sept 94]
-
- Answer: Editres, part of the MIT delivery, is a powerful widget tree analysis
- tool and is highly recommended. There's negligible overhead in making editres
- available to an application and many projects keep the editres "hook" active
- even for operational programs.
-
- It isn't built in to Motif (at 1.2.0), but you can do this in your application
-
- extern void _XEditResCheckMessages();
- ...
- XtAddEventHandler(shell_widget, (EventMask)0, True,
- _XEditResCheckMessages, NULL);
-
- once for each shell widget that you want to react to the "click to select
- client" protocol. Then link your client with the R5 libXmu.
-
- David Brooks, OSF
-
- From Marc Quinton (quinton@stna7.stna7.stna.dgac.fr):
-
- With X11R4 see the Editres package which is a port of the X11R5 Editres
- protocol and client. You can find it at :
-
- ftp.stna7.stna.dgac.fr(143.196.9.83):/pub/dist/Editres.tar.Z
-
- -----------------------------------------------------------------------------
- Subject: 191) How can I put decorations on transient windows using olwm?
-
- Answer: From Jean-Philippe Martin-Flatin <syj@ecmwf.co.uk>
-
- /**********************************************************************
- ** WindowDecorations.c
- **
- ** Manages window decorations under the OpenLook window manager (OLWM).
- **
- ** Adapted from a C++ program posted to comp.windows.x.motif by:
- **
- ** +--------------------------------------------------------------+
- ** | Ron Edmark User Interface Group |
- ** | Tel: (408) 980-1500 x282 Integrated Systems, Inc. |
- ** | Internet: edmark@isi.com 3260 Jay St. |
- ** | Voice mail: (408) 980-1590 x282 Santa Clara, CA 95054 |
- ** +--------------------------------------------------------------+
- ***********************************************************************/
-
- #include <X11/X.h>
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Protocols.h>
- #include <Xm/Xm.h>
- #include <Xm/AtomMgr.h>
-
- /*
- ** Decorations for OpenLook:
- ** The caller can OR different mask options to change the frame decoration.
- */
- #define OLWM_Header (long)(1<<0)
- #define OLWM_Resize (long)(1<<1)
- #define OLWM_Close (long)(1<<2)
-
- /*
- ** Prototypes
- */
- static void InstallOLWMAtoms (Widget w);
- static void AddOLWMDialogFrame(Widget widget, long decorationMask);
-
-
- /*
- ** Global variables
- */
- static Atom AtomWinAttr;
- static Atom AtomWTOther;
- static Atom AtomDecor;
- static Atom AtomResize;
- static Atom AtomHeader;
- static Atom AtomClose;
- static int not_installed_yet = TRUE;
-
-
- static void InstallOLWMAtoms(Widget w)
- {
- AtomWinAttr = XInternAtom(XtDisplay(w), "_OL_WIN_ATTR" , FALSE);
- AtomWTOther = XInternAtom(XtDisplay(w), "_OL_WT_OTHER", FALSE);
- AtomDecor = XInternAtom(XtDisplay(w), "_OL_DECOR_ADD", FALSE);
- AtomResize = XInternAtom(XtDisplay(w), "_OL_DECOR_RESIZE", FALSE);
- AtomHeader = XInternAtom(XtDisplay(w), "_OL_DECOR_HEADER", FALSE);
- AtomClose = XInternAtom(XtDisplay(w), "_OL_DECOR_CLOSE", FALSE);
-
- not_installed_yet = FALSE;
- }
-
- static void AddOLWMDialogFrame(Widget widget, long decorationMask)
- {
- Atom winAttrs[2];
- Atom winDecor[3];
- Widget shell = widget;
- Window win;
- int numberOfDecorations = 0;
-
- /*
- ** Make sure atoms for OpenLook are installed only once
- */
- if (not_installed_yet) InstallOLWMAtoms(widget);
-
- while (!XtIsShell(shell)) shell = XtParent(shell);
-
- win = XtWindow(shell);
-
- /*
- ** Tell Open Look that our window is not one of the standard OLWM window ** types. See OLIT Widget Set Programmer's Guide pp.70-73.
- */
-
- winAttrs[0] = AtomWTOther;
-
- XChangeProperty(XtDisplay(shell),
- win,
- AtomWinAttr,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char*)winAttrs,
- 1);
-
- /*
- ** Tell Open Look to add some decorations to our window
- */
- numberOfDecorations = 0;
- if (decorationMask & OLWM_Header)
- winDecor[numberOfDecorations++] = AtomHeader;
- if (decorationMask & OLWM_Resize)
- winDecor[numberOfDecorations++] = AtomResize;
- if (decorationMask & OLWM_Close)
- {
- winDecor[numberOfDecorations++] = AtomClose;
-
- /*
- ** If the close button is specified, the header must be
- ** specified. If the header bit is not set, set it.
- */
- if (!(decorationMask & OLWM_Header))
- winDecor[numberOfDecorations++] = AtomHeader;
- }
-
- XChangeProperty(XtDisplay(shell),
- win,
- AtomDecor,
- XA_ATOM,
- 32,
- PropModeReplace,
- (unsigned char*)winDecor,
- numberOfDecorations);
- }
-
-
- /*
- ** Example of use of AddOLWMDialogFrame, with a bit of extra stuff
- */
- void register_dialog_to_WM(Widget shell, XtCallbackProc Cbk_func)
- {
- Atom atom;
-
- /*
- ** Alias the "Close" item in system menu attached to dialog shell
- ** to the activate callback of "Exit" in the menubar
- */
- if (Cbk_func)
- {
- atom = XmInternAtom(XtDisplay(shell),"WM_DELETE_WINDOW",TRUE);
- XmAddWMProtocolCallback(shell,atom, Cbk_func,NULL);
- }
-
- /*
- ** If Motif is the window manager, skip OpenLook specific stuff
- */
- if (XmIsMotifWMRunning(shell)) return;
-
- /*
- ** Register dialog shell to OpenLook.
- **
- ** WARNING: on some systems, adding the "Close" button allows the title
- ** to be properly centered in the title bar. On others, activating
- ** "Close" crashes OpenLook. The reason is not clear yet, but it seems
- ** the first case occurs with OpenWindows 2 while the second occurs with
- ** Openwindows 3. Thus, comment out one of the two following lines as
- ** suitable for your site, and send e-mail to syj@ecmwf.co.uk if you
- ** find out what is going on !
- */
- AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize));
- /* AddOLWMDialogFrame(shell,(OLWM_Header | OLWM_Resize | OLWM_Close)); */
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 192) Why does an augment translation appear to act as replace for
- some widgets? When I use either augment or override translations in
- .Xdefaults it seems to act as replace in both Motif 1.0 and 1.1
-
- Answer: By default, the translation table is NULL. If there is nothing
- specified (either in resource file, or in args), the widget's Initialize
- finds: Oh, there is NULL in translations, lets use our default ones. If,
- however, the translations have become non-NULL, the default translations are
- NOT used at all. Thus, using #augment, #override or a new table has identical
- effect: defines the new translations. The only way you can augment/override
- Motif's default translations is AFTER Initialize, using XtSetValues. Note,
- however, that Motif managers do play with translation tables as well ... so
- that results are not always easy to predict.
-
- From OSF: A number of people have complained about not being able to
- augment/override translations from the .Xdefaults. This is due to the
- complexity of the menu system/keyboard traversal and the necessary
- translations changes required to support the Motif Style Guide in menus. It
- cannot be fixed in a simple way. Fixing it requires re-design of the
- menus/buttons and it is planned to be fixed in 1.2.
-
- -----------------------------------------------------------------------------
- Subject: 193) How do you "grey" out a widget so that it cannot be activated?
-
- Answer: Use XtSetSensitive(widget, False). Do not set the XmNsensitive
- resource directly yourself (by XtSetValues) since the widget may need to talk
- to parents first.
-
- -----------------------------------------------------------------------------
- Subject: 194)* Why doesn't the Help callback work on some widgets?
-
- [Last modified: Oct 94]
-
- Answer: If you press the help key the help callback of the widget with the
- keyboard focus is called (not the one containing the mouse). You can't get
- the help callback of a non-keyboard-selectable widget called. To get `context
- sensitive' help on these, you have to find the mouse, associate its position
- with a widget and then do the help.
-
- The X Resource, Issue 6, has an article on implementing context help in
- Motif in this manner, that is, using the mouse position to indicate the
- widget for which context help is desired, as well as using resources to
- specify the help. Example source code is available at
-
- ftp://ora.com/pub/examples/xresource/issue6/helpdemo.tar.Z
-
- The demo program lets you toggle between using the method described in
- the article and XmTrackingLocate() for comparision purposes.
-
- contributed by: Jay Schmidgall jay@vnet.ibm.com (author of the article
- mentioned above) --
-
- -----------------------------------------------------------------------------
- Subject: 195) Can I specify a widget in a resource file?
-
- Answer: This answer, which uses the Xmu library, is due to David Elliott. If
- the converter is added, then the name of a widget (a string) can be used in
- resource files, and will be converted to the appropriate widget.
-
- This code, which was basically stolen from the Athena Form widget, adds a
- String to Widget converter. I wrote it as a general routine that I call at
- the beginning of all of my programs, and made it so I could add other
- converters as needed (like String to Unit Type ;-).
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <Xm/Xm.h>
- #include <X11/Xmu/Converters.h>
- #include <X11/IntrinsicP.h>
- #include <X11/CoreP.h>
-
- void
- setupConverters()
- {
- static XtConvertArgRec parentCvtArgs[] = {
- {XtBaseOffset, (caddr_t)XtOffset(Widget, core.parent),
- sizeof(Widget)}
- };
-
- XtAddConverter(XmRString, XmRWindow, XmuCvtStringToWidget,
- parentCvtArgs, XtNumber(parentCvtArgs));
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 196) Why are only some of my translations are being installed? I
- have a translation table like the following, but only the first ones are
- getting installed and the rest are ignored.
-
- *Text.translations: #override \
- Ctrl<Key>a: beginning-of-line() \n\
- Ctrl<Key>e: end-of-line() \n\
- Ctrl<Key>f: forward-character() \n\
-
-
- Answer: Most likely, you have a space at the end of one of the lines (the
- first in this case).
-
- Ctrl<Key>a: beginning-of-line() \n\
- ^ space here
-
- The second backslash in each line is there to protect the real newline
- character and so you must not follow it with anything other than the newline
- itself. Otherwise it acts as the end of the resource definition and the
- remaining lines are not added.
-
-
- -----------------------------------------------------------------------------
- Subject: 197) Where can I get the PanHandler code?
-
- Answer: It is available by email from Chuck Ocheret: chuck@IMSI.COM.
-
- -----------------------------------------------------------------------------
- Subject: 198) What are these passive grab warnings? When I destroy certain
- widgets I get a stream of messages
-
- Warning: Attempt to remove non-existant passive grab
-
-
- Answer: They are meaningless, and you want to ignore them. Do this (from Kee
- Hinckley) by installing an XtWarning handler that explicitly looks for them
- and discards them:
-
- static void xtWarnCB(String message) {
- if (asi_strstr(message, "non-existant passive grab", TRUE)) return;
- ...
-
- They come from Xt, and (W. Scott Meeks): "it's something that the designers of
- Xt decided the toolkit should do. Unfortunately, Motif winds up putting
- passive grabs all over the place for the menu system. On the one hand, we
- want to remove all these grabs when menus get destroyed so that they don't
- leak memory; on the other hand, it's almost impossible to keep track of all
- the grabs, so we have a conservative strategy of ungrabbing any place where a
- grab could have been made and we don't explicitly know that there is no grab.
- The unfortunate side effect is the little passive grab warning messages.
- We're trying to clean these up where possible, but there are some new places
- where the warning is generated. Until we get this completely cleaned up (1.2
- maybe), your best bet is probably to use a warning handler."
-
- -----------------------------------------------------------------------------
- Subject: 199) How do I have more buttons than three in a box? I want to have
- something like a MessageBox (or other widget) with more than three buttons,
- but with the same nice appearance.
-
- [Last modified: May 93]
-
- Answer: The Motif 1.2 MessageBox widget allows extra buttons to be added after
- the OK button. Just create the extra buttons as children of the MessageBox.
- Similarly with the SelectionBox.
-
- Pre-Motif 1.2, you have to do one of the following methods.
-
- A SelectionBox is created with four buttons, but the fourth (the Apply button)
- is unmanaged. To manage it get its widget ID via
- XmSelectionBoxGetChild(parent, XmDIALOG_APPLY_BUTTON) and then XtManage it.
- Unmanage all of the other bits in the SelectionBox that you don't want. If
- you want more than four buttons, try two SelectionBoxes (or similar) together
- in a container, where all of the unwanted parts of the widgets are unmanaged.
-
- Alternatively, build your own dialog:
-
- /* 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.
- */
-
- /* action_area.c -- demonstrate how CreateActionArea() can be used
- * in a real application. Create what would otherwise be identified
- * as a PromptDialog, only this is of our own creation. As such,
- * we provide a TextField widget for input. When the user presses
- * Return, the Ok button is activated.
- */
- #include <Xm/DialogS.h>
- #include <Xm/PushBG.h>
- #include <Xm/PushB.h>
- #include <Xm/LabelG.h>
- #include <Xm/PanedW.h>
- #include <Xm/Form.h>
- #include <Xm/RowColumn.h>
- #include <Xm/TextF.h>
-
- typedef struct {
- char *label;
- void (*callback)();
- caddr_t data;
- } ActionAreaItem;
-
- static void
- do_dialog(), close_dialog(), activate_cb(),
- ok_pushed(), cancel_pushed(), help();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- Widget toplevel, button;
- XtAppContext app;
-
- toplevel = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- button = XtVaCreateManagedWidget("Push Me",
- xmPushButtonWidgetClass, toplevel, NULL);
- XtAddCallback(button, XmNactivateCallback, do_dialog, NULL);
-
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app);
- }
-
- /* callback routine for "Push Me" button. Actually, this represents
- * a function that could be invoked by any arbitrary callback. Here,
- * we demonstrate how one can build a standard customized dialog box.
- * The control area is created here and the action area is created in
- * a separate, generic routine: CreateActionArea().
- */
- static void
- do_dialog(w, file)
- Widget w; /* will act as dialog's parent */
- char *file;
- {
- Widget dialog, pane, rc, label, text_w, action_a;
- XmString string;
- extern Widget CreateActionArea();
- Arg args[10];
- static ActionAreaItem action_items[] = {
- { "Ok", ok_pushed, NULL },
- { "Cancel", cancel_pushed, NULL },
- { "Close", close_dialog, NULL },
- { "Help", help, "Help Button" },
- };
-
- /* The DialogShell is the Shell for this dialog. Set it up so
- * that the "Close" button in the window manager's system menu
- * destroys the shell (it only unmaps it by default).
- */
- dialog = XtVaCreatePopupShell("dialog",
- xmDialogShellWidgetClass, XtParent(w),
- XmNtitle, "Dialog Shell", /* give arbitrary title in wm */
- XmNdeleteResponse, XmDESTROY, /* system menu "Close" action */
- NULL);
-
- /* now that the dialog is created, set the Close button's
- * client data, so close_dialog() will know what to destroy.
- */
- action_items[2].data = (caddr_t)dialog;
-
- /* Create the paned window as a child of the dialog. This will
- * contain the control area (a Form widget) and the action area
- * (created by CreateActionArea() using the action_items above).
- */
- pane = XtVaCreateWidget("pane", xmPanedWindowWidgetClass, dialog,
- XmNsashWidth, 1,
- XmNsashHeight, 1,
- NULL);
-
- /* create the control area (Form) which contains a
- * Label gadget and a List widget.
- */
- rc = XtVaCreateWidget("control_area", xmRowColumnWidgetClass, pane, NULL);
- string = XmStringCreateSimple("Type Something:");
- XtVaCreateManagedWidget("label", xmLabelGadgetClass, rc,
- XmNlabelString, string,
- XmNleftAttachment, XmATTACH_FORM,
- XmNtopAttachment, XmATTACH_FORM,
- NULL);
- XmStringFree(string);
-
- text_w = XtVaCreateManagedWidget("text-field",
- xmTextFieldWidgetClass, rc, NULL);
-
- /* RowColumn is full -- now manage */
- XtManageChild(rc);
-
- /* Set the client data "Ok" and "Cancel" button's callbacks. */
- action_items[0].data = (caddr_t)text_w;
- action_items[1].data = (caddr_t)text_w;
-
- /* Create the action area -- we don't need the widget it returns. */
- action_a = CreateActionArea(pane, action_items, XtNumber(action_items));
-
- /* callback for Return in TextField. Use action_a as client data */
- XtAddCallback(text_w, XmNactivateCallback, activate_cb, action_a);
-
- XtManageChild(pane);
- XtPopup(dialog, XtGrabNone);
- }
-
- /*--------------*/
- /* The next four functions are the callback routines for the buttons
- * in the action area for the dialog created above. Again, they are
- * simple examples, yet they demonstrate the fundamental design approach.
- */
- static void
- close_dialog(w, shell)
- Widget w, shell;
- {
- XtDestroyWidget(shell);
- }
-
- /* The "ok" button was pushed or the user pressed Return */
- static void
- ok_pushed(w, text_w, cbs)
- Widget w, text_w; /* the text widget is the client data */
- XmAnyCallbackStruct *cbs;
- {
- char *text = XmTextFieldGetString(text_w);
-
- printf("String = %s0, text);
- XtFree(text);
- }
-
- static void
- cancel_pushed(w, text_w, cbs)
- Widget w, text_w; /* the text field is the client data */
- XmAnyCallbackStruct *cbs;
- {
- /* cancel the whole operation; reset to NULL. */
- XmTextFieldSetString(text_w, "");
- }
-
- static void
- help(w, string)
- Widget w;
- String string;
- {
- puts(string);
- }
- /*--------------*/
-
- /* When Return is pressed in TextField widget, respond by getting
- * the designated "default button" in the action area and activate
- * it as if the user had selected it.
- */
- static void
- activate_cb(text_w, client_data, cbs)
- Widget text_w; /* user pressed Return in this widget */
- XtPointer client_data; /* action_area passed as client data */
- XmAnyCallbackStruct *cbs; /* borrow the "event" field from this */
- {
- Widget dflt, action_area = (Widget)client_data;
-
- XtVaGetValues(action_area, XmNdefaultButton, &dflt, NULL);
- if (dflt) /* sanity check -- this better work */
- /* make the default button think it got pushed. This causes
- * "ok_pushed" to be called, but XtCallActionProc() causes
- * the button appear to be activated as if the user selected it.
- */
- XtCallActionProc(dflt, "ArmAndActivate", cbs->event, NULL, 0);
- }
-
- #define TIGHTNESS 20
-
- Widget
- CreateActionArea(parent, actions, num_actions)
- Widget parent;
- ActionAreaItem *actions;
- int num_actions;
- {
- Widget action_area, widget;
- int i;
-
- action_area = XtVaCreateWidget("action_area", xmFormWidgetClass, parent,
- XmNfractionBase, TIGHTNESS*num_actions - 1,
- XmNleftOffset, 10,
- XmNrightOffset, 10,
- NULL);
-
- for (i = 0; i < num_actions; i++) {
- widget = XtVaCreateManagedWidget(actions[i].label,
- xmPushButtonWidgetClass, action_area,
- XmNleftAttachment, i? XmATTACH_POSITION : XmATTACH_FORM,
- XmNleftPosition, TIGHTNESS*i,
- XmNtopAttachment, XmATTACH_FORM,
- XmNbottomAttachment, XmATTACH_FORM,
- XmNrightAttachment,
- i != num_actions-1? XmATTACH_POSITION : XmATTACH_FORM,
- XmNrightPosition, TIGHTNESS*i + (TIGHTNESS-1),
- XmNshowAsDefault, i == 0,
- XmNdefaultButtonShadowThickness, 1,
- NULL);
- if (actions[i].callback)
- XtAddCallback(widget, XmNactivateCallback,
- actions[i].callback, actions[i].data);
- if (i == 0) {
- /* Set the action_area's default button to the first widget
- * created (or, make the index a parameter to the function
- * or have it be part of the data structure). Also, set the
- * pane window constraint for max and min heights so this
- * particular pane in the PanedWindow is not resizable.
- */
- Dimension height, h;
- XtVaGetValues(action_area, XmNmarginHeight, &h, NULL);
- XtVaGetValues(widget, XmNheight, &height, NULL);
- height += 2 * h;
- XtVaSetValues(action_area,
- XmNdefaultButton, widget,
- XmNpaneMaximum, height,
- XmNpaneMinimum, height,
- NULL);
- }
- }
-
- XtManageChild(action_area);
-
- return action_area;
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 200) How do I create a "busy working cursor"?
-
- Answer: - in Baudouin's code (following), the idea is to keep in an array an
- up-to-date list of all shells used in the application, and set for all of them
- the cursor to a watch or to the default cursor, with the 2 functions provided.
-
- - in Dan Heller's code (later), the idea is to turn on the watch cursor for
- the top-level shell only, popup a working window to possibly abort the
- callback, and manage some expose events during the callback.
-
- - in the FAQ for comp.windows.x (#113), the idea is to bring a large window on
- top of the application, hide all windows below it, and turn on the watch
- cursor on this large window. Unmapping the large window resets the default
- cursor, mapping it turns on the watch cursor.
-
- From Baudouin Raoult (mab@ecmwf.co.uk)
-
- void my_SetWatchCursor(w)
- Widget w;
- {
- static Cursor watch = NULL;
-
- if(!watch)
- watch = XCreateFontCursor(XtDisplay(w),XC_watch);
-
- XDefineCursor(XtDisplay(w),XtWindow(w),watch);
- XmUpdateDisplay(w);
- }
-
- void my_ResetCursor(w)
- Widget w;
- {
- XUndefineCursor(XtDisplay(w),XtWindow(w));
- XmUpdateDisplay(w);
- }
-
-
- Answer: A solution with lots of bells and whistles is
-
-
- /* 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.
- */
-
- /* busy.c -- demonstrate how to use a WorkingDialog and to process
- * only "important" events. e.g., those that may interrupt the
- * task or to repaint widgets for exposure. Set up a simple shell
- * and a widget that, when pressed, immediately goes into its own
- * loop. First, "lock" the shell so that a timeout cursor is set on
- * the shell and pop up a WorkingDialog. Then enter loop ... sleep
- * for one second ten times, checking between each interval to see
- * if the user clicked the Stop button or if any widgets need to be
- * refreshed. Ignore all other events.
- *
- * main() and get_busy() are stubs that would be replaced by a real
- * application; all other functions can be used "as is."
- */
- #include <Xm/MessageB.h>
- #include <Xm/PushB.h>
- #include <X11/cursorfont.h>
-
- Widget shell;
- void TimeoutCursors();
- Boolean CheckForInterrupt();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- XtAppContext app;
- Widget button;
- XmString label;
- void get_busy();
-
- shell = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- label = XmStringCreateSimple(
- "Boy, is *this* going to take a long time.");
- button = XtVaCreateManagedWidget("button",
- xmPushButtonWidgetClass, shell,
- XmNlabelString, label,
- NULL);
- XmStringFree(label);
- XtAddCallback(button, XmNactivateCallback, get_busy, argv[1]);
-
- XtRealizeWidget(shell);
- XtAppMainLoop(app);
- }
-
- void
- get_busy(widget)
- Widget widget;
- {
- int n;
-
- TimeoutCursors(True, True);
- for (n = 0; n < 10; n++) {
- sleep(1);
- if (CheckForInterrupt()) {
- puts("Interrupt!");
- break;
- }
- }
- if (n == 10)
- puts("done.");
- TimeoutCursors(False, NULL);
- }
-
- /* The interesting part of the program -- extract and use at will */
- static Boolean stopped; /* True when user wants to stop processing */
- static Widget dialog; /* WorkingDialog displayed when timed out */
-
- /* timeout_cursors() turns on the "watch" cursor over the application
- * to provide feedback for the user that he's going to be waiting
- * a while before he can interact with the appliation again.
- */
- void
- TimeoutCursors(on, interruptable)
- int on, interruptable;
- {
- static int locked;
- static Cursor cursor;
- extern Widget shell;
- XSetWindowAttributes attrs;
- Display *dpy = XtDisplay(shell);
- XEvent event;
- Arg args[1];
- XmString str;
- extern void stop();
-
- /* "locked" keeps track if we've already called the function.
- * This allows recursion and is necessary for most situations.
- */
- on? locked++ : locked--;
- if (locked > 1 || locked == 1 && on == 0)
- return; /* already locked and we're not unlocking */
-
- stopped = False; /* doesn't matter at this point; initialize */
- if (!cursor) /* make sure the timeout cursor is initialized */
- cursor = XCreateFontCursor(dpy, XC_watch);
-
- /* if "on" is true, then turn on watch cursor, otherwise, return
- * the shell's cursor to normal.
- */
- attrs.cursor = on? cursor : None;
-
- /* change the main application shell's cursor to be the timeout
- * cursor (or to reset it to normal). If other shells exist in
- * this application, they will have to be listed here in order
- * for them to have timeout cursors too.
- */
- XChangeWindowAttributes(dpy, XtWindow(shell), CWCursor, &attrs);
-
- XFlush(dpy);
-
- if (on) {
- /* we're timing out, put up a WorkingDialog. If the process
- * is interruptable, allow a "Stop" button. Otherwise, remove
- * all actions so the user can't stop the processing.
- */
- str = XmStringCreateSimple("Busy. Please Wait.");
- XtSetArg(args[0], XmNmessageString, str);
- dialog = XmCreateWorkingDialog(shell, "Busy", args, 1);
- XmStringFree(str);
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
- if (interruptable) {
- str = XmStringCreateSimple("Stop");
- XtVaSetValues(dialog, XmNcancelLabelString, str, NULL);
- XmStringFree(str);
- XtAddCallback(dialog, XmNcancelCallback, stop, NULL);
- } else
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
- XtUnmanageChild(
- XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
- XtManageChild(dialog);
- } else {
- /* get rid of all button and keyboard events that occured
- * during the time out. The user shouldn't have done anything
- * during this time, so flush for button and keypress events.
- * KeyRelease events are not discarded because accelerators
- * require the corresponding release event before normal input
- * can continue.
- */
- while (XCheckMaskEvent(dpy,
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
- | PointerMotionMask | KeyPressMask, &event)) {
- /* do nothing */;
- }
- XtDestroyWidget(dialog);
- }
- }
-
- /* User Pressed the "Stop" button in dialog. */
- void
- stop(dialog)
- Widget dialog;
- {
- stopped = True;
- }
-
- Boolean
- CheckForInterrupt()
- {
- extern Widget shell;
- Display *dpy = XtDisplay(shell);
- Window win = XtWindow(dialog);
- XEvent event;
-
- /* Make sure all our requests get to the server */
- XFlush(dpy);
-
- /* Let motif process all pending exposure events for us. */
- XmUpdateDisplay(shell);
-
- /* Check the event loop for events in the dialog ("Stop"?) */
- while (XCheckMaskEvent(dpy,
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
- PointerMotionMask | KeyPressMask | KeyReleaseMask,
- &event)) {
- /* got an "interesting" event. */
- if (event.xany.window == win)
- XtDispatchEvent(&event); /* it's in our dialog.. */
- else /* uninteresting event--throw it away and sound bell */
- XBell(dpy, 50);
- }
- return stopped;
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 201) Can I use the hourglass that mwm uses?
-
- [Last modified: March 93]
-
- Answer: The hourglass used by mwm is hard-coded into code that is subject to
- OSF copyright. In Motif 1.2 though, the bitmaps for this and other things
- (information, no_enter, question, warning, working) were made available. The
- install process will probably add them to /usr/include/X11/bitmaps.
- Otherwise, just use the watch cursor XC_watch of the previous question,
- because that has the same semantics.
-
-
- -----------------------------------------------------------------------------
- Subject: 202) What order should the libraries be linked in?
-
- [Last modified: August 92]
-
- Answer: At link time, use the library order -lXm -lXt -lX11. There are two
- reasons for this (dbrooks@osf.org):
-
- On most systems, the order matters because the linker won't re-scan a library
- once it is done with it. Thus any references to Xlib calls from Xm will
- probably be unresolved.
-
- The [other] problem is that there are two VendorShell widgets. A dummy is
- provided in the Xt library, but a widget set will rely on its own being
- referenced. If you mention Xt first, the linker will choose the wrong one.
-
- Motif code will wrongly assume the Motif VendorShell has been class-
- initialized [and will probably crash].
- Xaw has a similar problem, but a softer landing; it only complains about
- unregistered converters.
-
-
- -----------------------------------------------------------------------------
- Subject: 203) How do I use xmkmf for Motif clients?
-
- [Last modified: October 1992]
-
- Answer: This advice comes from dbrooks@osf.org:
-
- There are a number of intractable problems with using X configuration files
- and xmkmf, while trying to make it easy to build Motif. Not the least of
- these, but one I've never heard mentioned yet, is that the rules for
- contructing the names of shared library macros are machine-dependent, and in
- the various xxxLib.tmpl files. Do we edit all those files to add definitions
- for XMLIB, DEPXMLIB, etc., or do we put a maze of #ifdefs into the Motif.tmpl
- file?
-
- Please note that, if you install Motif, it overwrites your installed
- Imake.tmpl with one that includes Motif.tmpl and Motif.rules.
-
- With those caveats, I think the following guidelines will help.
-
- David Brooks OSF
-
- Clients in the X11R5 release use the xmkmf command to build Makefiles. In
- general, the xmkmf command cannot be used for Motif clients, because of the
- need to consider the UseInstalledMotif flag separately. Since xmkmf is a
- simple script that calls imake, it is easy to construct the proper call to
- imake using the following rules.
-
- In the following, replace {MTOP} by the toplevel directory with the Motif
- source tree, and {XTOP} by the toplevel ("mit") directory with the X source.
- It is assumed that the directory containing your installed imake is in your
- PATH.
-
- When needed, the imake variables XTop and MTop are normally set in your
- site.def (to {XTOP} amd {MTOP} respectively); however they may also be set
- with additional -D arguments to imake.
-
- 1. With both X and Motif in their source trees, ensure the imake variables
- XTop and MTop are set, and use:
-
- ${XTOP}/config/imake -I{MTOP}/config
-
- 2. With Motif in its source tree, and X installed, ensure MTop is set, and
- use:
-
- imake -I{MTOP}/config -DUseInstalled
-
- 3. With both Motif and X installed, and a nonstandard ProjectRoot (see
- site.def for an explanation of this), use:
-
- imake -DUseInstalled -DUseInstalledMotif -I{ProjectRoot}/lib/X11/config
-
- or, if the configuration files are in /usr/lib/X11/config:
-
- imake -DUseInstalled -DUseInstalledMotif
-
-
- To build a simple Imakefile, remember to include lines like this:
-
- LOCAL_LIBRARIES = XmClientLibs
- DEPLIBS = XmClientDepLibs
-
- Or, for a client that uses uil/mrm, replace these by MrmClientLibs and
- MrmClientDepLibs, and also use:
-
- MSimpleUilTarget(program)
-
- to build the client and uid file. Look at the demos for more examples.
-
-
- And Paul Howell <grue@engin.umich.edu> added:
-
- i did this, calling the new script "xmmkmf". It passes both -DUseInstalled
- and -DUseInstalledMotif.
-
- and i modified the stock R5 Imake.tmpl to do this:
-
- #include <Project.tmpl>
- #ifdef UseInstalledMotif
- #include <Motif.tmpl>
- #endif
-
- #include <Imake.rules>
- #ifdef UseInstalledMotif
- #include <Motif.rules>
- #endif
-
- the result was something that does both athena and motif rules. and it really
- works, just that easy!
-
-
- -----------------------------------------------------------------------------
- Subject: 204) How do I make context sensitive help? The Motif Style Guide
- says that an application must initiate context-sensitive help by changing the
- shape of the pointer to the question pointer. When the user moves the pointer
- to the component help is wanted on and presses BSelect, any available context
- sensitive help for the component must be presented, and the pointer reverts
- from the question pointer.
- [Last modified: August 92]
-
- Answer: A widget that gives context sensitive help would place this help in
- the XmNhelpCallback function. To trigger this function: (from Martin G C
- Davies, mgcd@se.alcbel.be)
-
- I use the following callback that is called when the "On Context" help
- pulldown menu is selected. It does the arrow bit and calls the help callbacks
- for the widget. It also zips up the widget tree looking for help if needs be.
- I don't restrict the arrows motion so I can get help on dialog boxes. No
- prizes for guessing what "popup_message" does.
-
-
- static void ContextHelp(
- Widget w ,
- Opaque * tag ,
- XmAnyCallbackStruct * callback_struct
- )
- {
- static Cursor context_cursor = NULL ;
- Widget context_widget ;
-
- if ( context_cursor == NULL )
- context_cursor = XCreateFontCursor( display, XC_question_arrow ) ;
-
- context_widget = XmTrackingLocate( top_level_widget,
- context_cursor, FALSE ) ;
-
- if ( context_widget != NULL ) /* otherwise its not a widget */
- {
- XmAnyCallbackStruct cb ;
-
- cb.reason = XmCR_HELP ;
- cb.event = callback_struct->event ;
-
- /*
- * If there's no help at this widget we'll track back
- up the hierarchy trying to find some.
- */
-
- do
- {
- if ( ( XtHasCallbacks( context_widget, XmNhelpCallback ) ==
- XtCallbackHasSome ) )
- {
- XtCallCallbacks( context_widget, XmNhelpCallback, & cb ) ;
- return ;
- }
- else
- context_widget = XtParent( context_widget ) ;
- } while ( context_widget != NULL ) ;
- }
-
- popup_message( "No context-sensitive help found\n\
- for the selected object." ) ;
- }
-
-
- Dave Bonnett suggested, to use the following translations for XmText (and
- XmTextField) widgets to get the same help with key strokes, and to provide an
- accelerator label in the Context help menu entry.
-
- MyApp*XmText*translations: #override\n\
- <Key>F1: Help()
-
- MyApp*Help_menu*Contextual Help.acceleratorText: F1
-
- MyApp*defaultVirtualBindings: osfBackSpace : <Key>Delete\n\
- osfRight : <Key>Right\n\
- osfLeft : <Key>Left\n\
- osfUp : <Key>Up\n\
- osfHelp : <Key>F1\n\
- osfDown : <Key>Down
-
-
- -----------------------------------------------------------------------------
- Subject: 205) How do I debug a modal interaction?
-
- When an application crashes in a modal section (such as in a modal dialog, a
- menu or when a drag and drop is in action), I cannot access the debugger.
-
- [Last modified: January 1993]
-
- Answer: Run the debugger on one display while the application writes to
- another display.
-
- -----------------------------------------------------------------------------
- Subject: 206)* How can I disable Drag and Drop in my Motif 1.2 client ?
-
- [Last modified: Oct 94]
-
- Answer: Several people have reported that for complex hierarchies of widgets,
- drag and drop can slow down an application considerably. If you do not need
- drag and drop's significant power, you can disable it in your application.
-
- Set the XmDisplay drag-protocol resources to XmDRAG_NONE. The following code
- fragment demonstrates this:
-
- #include <Xm/Display.h>
-
-
- dw = XmGetXmDisplay(XtDisplay(shell));
- /* where "shell" is your client's top-level shell. */
-
- XtVaSetValues(dw, XmNdragInitiatorProtocolStyle, XmDRAG_NONE, NULL);
- XtVaSetValues(dw, XmNdragReceiverProtocolStyle, XmDRAG_NONE, NULL);
-
-
- thanks to Lance Purple (purple@austin.ibm.com)
-
- Ken Lee (kenton@esd.sgi.com) and Christoph Widmer
- (widmer@einsteinium.SLCS.SLB.COM) describe how to disable drag and drop from a
- resource file:
-
- *dragInitiatorProtocolStyle: XmDRAG_NONE
- *dragReceiverProtocolStyle: XmDRAG_NONE
-
- Ken Lee also notes that as of Motif 1.2, the "Xm" prefix is required for all
- token constants in resource files. (Which is why specifying "DRAG_NONE" won't
- work but "XmDRAG_NONE" will.)
-
- -----------------------------------------------------------------------------
- Subject: 207) Where can I get info on the Motif drag and drop protocol?
-
- [Last modified: Sept 94]
-
- Answer: The drag and drop protocol implemented by OSF is not stable, so they
- have not published it yet. The API should remain stable though. The OSF
- protocol is not compatable with the OpenLook protocol. OSF and Sun are
- working on a joint protocol for publication.
-
- For programming examples on Motif drag and drop, see the Motif 1.2 Programmers
- Guide.
-
- For a third alternative, try Roger Reynolds drag and drop protocol, available
- from netcom.com in /pub/rogerr.
-
- Ken Lee, kenton@esd.sgi.com writes: OSF's "Motif Programmers Guide" includes
- complete source code for several drag and drop demos. There are some simple
- programs demonstrating the basic behaviour, as well as complex programs
- demonstrating more sophisticated options. I think the source code for some of
- the demos also appears on the OSF tape.
-
-
- -----------------------------------------------------------------------------
- Subject: 208) Why can't I install my own colormap using XInstallColormap?
-
- [Last modified: Sept 94]
-
- Answer: You shouldn't install the colormap yourself using XInstallColormap.
- See the ICCCM document for all the reasons. Instead put the colormap as an
- argument on the Shell widget and the window manager will take care of this.
-
- When the colormap is installed, unless you have a display with multiple
- colormaps, the other windows will go "technicolor" and there is no way around
- this problem.
-
- Thanks to Doug Rand <drand@osf.org>
-
- -----------------------------------------------------------------------------
- Subject: 209) How do I get correct shadow colors to match other color
- changes?
-
- [Last modified: Sept 94]
-
- Answer:
-
- Thanks to Craig MacFarlane (craigm@chateau-rouge.ICS.UCI.EDU) for the
- following explanation and code:
-
- You have to make a call to calculate the new shadow colors. The trick is
- actually getting a value of type Pixel when all you have is the string "Blue".
- I use the XtConvertAndStore() function to convert from a char * to a Pixel.
- For example:
-
-
- char *color = "blue";
- XrmValue color_value, pixel_value;
- Pixel background;
-
- color_value.size = strlen(color);
- color_value.addr = (XtPointer) color;
- pixel_value.size = sizeof(Pixel);
- pixel_value.addr = (XtPointer) 0;
-
- result = XtConvertAndStore(widget,
- XtRString, &color_value,
- XtRPixel, &pixel_value);
-
- background = (*(Pixel *)pixel_value.addr);
-
-
- You can then use the pixel value obtained by XtConvertAndStore() in the
- XmGetColors call. XmGetColors calculates appropriate foreground, topshadow,
- bottomshadow, and select colors for the given background. e.g.
-
-
- XmGetColors(screen,
- DefaultColormap(display_id, DefaultScreen(display_id)),
- background,
- &foreground, &topshadow, &bottomshadow, &select);
-
-
- From here it's trivial to set the shadow colors at the same time you set the
- foreground and background colors. For example:
-
-
- XtVaSetValues(widget,
- XmNforeground, foreground,
- XmNbackground, background,
- XmNarmColor, select,
- XmNtopShadowColor, topshadow,
- XmNbottomShadowColor, bottomshadow,
- NULL);
-
-
- You'll get asthetically pleasing colors every time. :)
-
- -----------------------------------------------------------------------------
- Subject: 210)+ What color algorithm does Motif use? I am told that Motif uses
- some sort of algorithm that will take a single color that is defined for the
- "background" and scale it so that the widget remains discriminable from the
- background, etc. What is the algorithm?
-
- [Last modified: Oct 94]
-
- Answer: Chris Flatters (cflatter@nrao.edu) writes: Shiz Kobara's book "Visual
- Design with OSF/Motif", Addison Wesley, 1991, ISBN 0-201-56320-7) is a good
- source for information of this sort. I haven't seen it in bookshops for a
- while so it may have gone out of print (which would be a pity). In essence
- each widget has 4 colours which, to first order, are
-
- background
- select (background * 85%)
- top shadow (background * 150%)
- bottom shadow (background * 50%)
-
- An additional correction may be applied to the hues of the calculated colours
- if any of the RGB values saturates. The algorithm works best if the brightest
- of the RGB components lies in the range 155-175 (on a scale of 0-255). The
- top shadow becomes darker than the background for light background colours
- which does not lead to a particularly pleasing effect.
-
- -----------------------------------------------------------------------------
- Subject: 211)+ How can you access the superclass widget from which Motif
- convenience dialogs are subclassed?
-
- [Last modified: Oct 94]
-
- Answer: From Kim Frei (uunet!ask.uniras.dk!kimf): If you are using Motif 1.2,
- read about XmTemplateDialog.
-
- -----------------------------------------------------------------------------
- Subject: 212) TOPIC: HISTORY and ACKNOWLEDGEMENTS
-
- Answer:
-
- History:
- -------
- November 89 to July 93: FAQ was maintained by Jan Newmarch
- (jan@ise.canberra.edu.au)
-
- July 93 to August 94: FAQ was maintained by Brian Dealy
- (dealy@c3i.saic.com)
-
- Acknowledgments:
- ----------------
- This list was compiled using questions and answers posed to
- comp.windows.x.motif and motif-talk. Some information was excerpted from the
- comp.windows.x FAQ. To all who contributed one way or the other, thanks! We
- haven't often given individual references, but you may recognize
- contributions. If weve mangled them too much, let the current maintainer know.
-
-
- Jan Newmarch, Information Science and Engineering,
- University of Canberra, PO Box 1, Belconnen, Act 2616
- Australia. Tel: (Aust) 6-2522422. Fax: (Aust) 6-2522999
-
- ACSnet: jan@ise.canberra.edu.au
- ARPA: jan%ise.canberra.edu.au@uunet.uu.net
- UUCP: {uunet,ukc}!munnari!ise.canberra.edu.au!jan
- JANET: jan%au.edu.canberra.ise@EAN-RELAY
-
-
- Jan Newmarch maintained this FAQ for a long time and has really helped a great
- many of us by providing this valuable service. He deserves a big round of
- applause for his efforts. I use this resource all the time and it has saved
- me countless hours with manuals and source code trying to relearn what others
- have already discovered. Jan`s efforts are gratefully acknowledged here.
-
-
- Brian Dealy, SAIC
- dealy@c3i.saic.com
-
-
- Likewise, Brian Dealy of SAIC did an admirable job taking over the Motif FAQ
- from Jan. A considerable amount of information was added during his tenure and
- we greatly appreciate Brian's work on the FAQ, as well as his efforts in
- maintaining the comp.windows.x.motif newsgroup reflector, for the good of all
- Motif-dom.
-
-
- Ken Sall, Century Computing, Inc.
- ksall@cen.com
-
-
-
-