home *** CD-ROM | disk | FTP | other *** search
- Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
- Message-ID: <motif-faq/part6_1083675484@rtfm.mit.edu>
- Supersedes: <motif-faq/part6_1082292761@rtfm.mit.edu>
- Expires: 17 Jun 2004 12:58:04 GMT
- References: <motif-faq/part1_1083675484@rtfm.mit.edu>
- X-Last-Updated: 2002/01/31
- Organization: none
- Subject: Motif FAQ (Part 6 of 9)
- Newsgroups: comp.windows.x.motif,comp.answers,news.answers
- Keywords: FAQ question answer
- From: kenton@rahul.net (Ken Lee)
- Reply-To: kenton@rahul.net (Ken Lee)
- Approved: news-answers-request@MIT.EDU
- Followup-To: poster
- Summary: Motif Frequently Asked Questions (with answers).
- Originator: faqserv@penguin-lust.MIT.EDU
- Date: 04 May 2004 12:59:12 GMT
- Lines: 1460
- NNTP-Posting-Host: penguin-lust.mit.edu
- X-Trace: 1083675552 senator-bedfellow.mit.edu 565 18.181.0.29
- Xref: senator-bedfellow.mit.edu comp.windows.x.motif:75189 comp.answers:57054 news.answers:270858
-
- Archive-name: motif-faq/part6
- Last-modified: 1 FEB 2002
- Posting-Frequency: irregular
- Organization: Kenton Lee, X/Motif Consultant, http://www.rahul.net/kenton/
- URL: http://www.rahul.net/kenton/mfaq.html
- Version: 8.1
-
- -----------------------------------------------------------------------------
- Subject: 156) TOPIC: DRAWING AREA WIDGET
-
- -----------------------------------------------------------------------------
- Subject: 157) How can I send an expose event to a Drawing Area widget? (or
- any other, come to that). I want to send an expose event so that it will
- redraw itself.
- [Last modified: Nov 97]
-
- Answer: Use the Xlib call
-
- XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True)
-
- This clears the widget's window and generates an expose event in doing so.
- The widgets expose action will then redraw it. This uses a round trip
- request. An alternative, without the round trip is
-
- from orca!mesa!rthomson@uunet.uu.net (Rich Thomson):
-
- Widget da;
- XmDrawingAreaCallbackStruct da_struct;
-
- da_struct.reason = XmCR_EXPOSE;
- da_struct.event = (XEvent *) NULL;
- da_struct.window = XtWindow(da);
-
- XtCallCallbacks(da, XmNexposeCallback, (XtPointer) &da_struct);
-
- Thanks to rand@ling.umu.se (Ola Andersson) for a correction to the above.
-
-
- -----------------------------------------------------------------------------
- Subject: 158) How can I know when a DrawingArea has been resized? It
- generates an expose event whn it is enlarged, but not when it is shrunk.
-
- Answer: Use the resize callback.
-
- -----------------------------------------------------------------------------
- Subject: 159) How can I create a drawing area widget with a visual type
- different from its parent?
- [Last modified: Sep 97]
-
- Answer: The standard Motif drawing area does not support this. You can,
- however, easily create a subclass with a new Realize class method. You may
- want to create visual type, colormap, and depth resources so you can set these
- values at initialization time.
-
- In SGI's Motif, such a widget is called SgVisualDrawingArea. Other Motif
- implementations may have similar widgets.
-
- Ken Lee, http://www.rahul.net/kenton/
-
- -----------------------------------------------------------------------------
- Subject: 160) How can I display postscript in a Motif widget, such as
- XmDrawingArea?
- [Last modified: Sept 95]
-
- Answer: Richard M. Goldstein (rickg@Eng.Sun.COM) writes: If your system
- supports the Display PostScript extension (or NX agent), the newer revs of the
- dpstkXm library contains a type of drawing area widget designed specifically
- for use with DPS. Source for the latest DPS client-side is also ftp'able from
- contrib.
-
- Ramiro Estrugo (restrugo@fateware.com) writes: Have a look at ghostscript.
- [With] a little editting, you can extract the Ghostview widget and use it in
- your application...
-
- -----------------------------------------------------------------------------
- Subject: 161) TOPIC: MAIN WINDOW WIDGET
-
- -----------------------------------------------------------------------------
- Subject: 162) How can I create a message window in an XmMainWindow?
- [Last modified: Nov 95]
-
- Answer: XmMainWindow supports a message window, but you cannot specify it via
- XmMainWindowSetAreas(). Instead, create the widget as a child of the
- XmMainWindow, then specify to the XmMainWindow with XtSetValues() of
- XmNmessageWindow.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 163) TOPIC: SCROLLED WINDOW WIDGET
-
- -----------------------------------------------------------------------------
- Subject: 164) 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).
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 165) 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".
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 166) What widget does the XmScrolledWindow use for its clip window?
- [Last modified: Apr 98]
-
- Answer: In Motif 1.2, if the XmScrolledWindow is using the XmAUTOMATIC
- scrolling policy, it automatically creates an XmDrawingArea widget as its clip
- window. If you wish, you can retrieve the XmDrawingArea's widget ID by using
- XtGetValues on the XmNclipWindow resource and then set resources on that
- widget. Some useful resources are XmNbackground and XmNresizeCallback.
-
- Note that Motif 2.X uses a new XmClipWindow widget instead of the
- XmDrawingArea. Since XmClipWindow is subclassed from XmDrawingArea, the above
- resources should still work.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 167) How do I create a scrolled window with only one scrollbar?
- [Last modified: July 95]
-
- Answer: If you're using the default application-defined scrolling mode, you
- can just create one and specify NULL for the other. If, however, you're using
- automatic scrolling, retrieve the ID of the unwanted scrollbar with
- XmNhorizontalScrollBar or XmNverticalScrollBar and unmanage that widget:
-
-
- Widget hScroll;
- XtVaGetValues(scrollbar, XmNhorizontalScrollBar, &hScroll, NULL);
- XtUnmanageChild(hScroll);
-
-
- Thanks to Ken Lee, http://www.rahul.net/kenton/. Typo corrected by Paul
- Tomblin, ptomblin@canoe.com.
-
- -----------------------------------------------------------------------------
- Subject: 168) TOPIC: MENUS
-
- -----------------------------------------------------------------------------
- Subject: 169) How can I change the cursor used in Motif menus?
- [Last modified: Oct 95]
-
- Answer: Set XmNmenuCursor on XmScreen (Motif 1.2) or XmRowColumn (Motif 1.1).
- This should be set globally at start-up time, e.g., usually via an app-
- defaults file.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 170) How do I put my help menu on the far right of my menubar?
- [Last modified: Oct 95]
-
- Answer: Set the XmNmenuHelpWidget resource of the menu bar to the help menu's
- cascade button.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 171) Can I change or disable the menu bar accelerator from the
- default (F10)?
- [Last modified: May 97]
-
- Answer: Changing it will confuse some of your users. If you must, this
- accelerator is controlled by these resources on the menu bar's XmRowColumn:
- XmNpopupEnabled (enables accelerators) and XmNmenuAccelerator (specifies the
- accelerator key).
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 172) How do I set the current choice in a radio box or an option
- menu?
- [Last modified: May 95]
-
- Answer: Set the XmNmenuHistory resource on its XmRowColumn parent.
-
- Ken Lee
-
- buser@tartan.com (Mark) sent this code fragment:
-
- Widget menu;
- int num_buttons;
- WidgetList buttons;
-
- XtVaGetValues( simple_option_widget, XmNsubMenuId, &menu, NULL);
-
- XtVaGetValues( menu, XmNnumChildren, &num_buttons,
- XmNchildren, &buttons, NULL ) ;
-
- and change current selection with:
-
- XtVaSetValues( simple_option_widget, XmNmenuHistory, buttons[index], NULL ) ;
-
- /* where index is between 0 and num_buttons */
-
- Thanks to Phil Gehlich <pgehlich@hp7001.ecae.StorTek.COM> for a correction.
-
- -----------------------------------------------------------------------------
- Subject: 173) How can I determine the item selected in a a radio box or
- option menu?
-
- 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.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 174) How can I change the cascade indicator on an option menu?
- [Last modified: Dec 97]
-
- Answer: Set XmNcascadePixmap on the option menu's cascade button gadget.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 175) How do I unset an XmToggleButton in a radio box? If a radio-
- mode toggle button is set and I XtSetValues XmNset a different toggle button,
- the first radio button is not automatically unset. How do can I automatically
- unset the first button?
- [Last modified: Jun 98]
-
- Answer: There are two easy ways to do this. First, you can set the toggle
- with XmNmenuHistory on the radio box instead of XmNset on the toggle button.
- Second, you can use XmToggleButtonSetState() with True for the notify
- argument.
-
- Note that some people have reported that XmNmenuHistory correctly sets the
- toggle state but the toggle is not always redrawn to show the new state. This
- is a bug in their implementation of Motif. If you cannot get a patch, you
- should use the XmToggleButtonSetState() method.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 176) Can I place a radio box in a pulldown menu?
- [Last modified: May 97]
-
- Answer: You cannot place a XmRowColumn widget child in a menu pane. Since the
- menu pane itself is a XmRowColumn widget, however, you can enable
- XmNradioBehavior on it. This only works if all of the menu items are radio
- buttons.
-
- An alternative is to manage your radio behavior via your button callback
- functions. This is more work, but much more flexible.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 177) How do I make a menu choice insensitive if it was created with
- XmVaCreateSimplePulldownMenu?
- [Last modified: Sept 94]
-
- Answer: According to the Motif manual, the buttons are named "button_n", where
- "n" is an integer starting from 0. You can use XtNameToWidget() to convert
- these names to widget ID's.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 178) What widgets can I put inside a menubar?
- [Last modified: Oct 95]
-
- Answer: You can only put cascade buttons (widgets or gadgets) in the top level
- of menubars. However, the children of these cascade buttons can be pushbuttons
- with labels, pushbuttons with pixmaps, toggle buttons, separators, other
- cascade buttons.
-
- -----------------------------------------------------------------------------
- Subject: 179) Can I have a cascade button without a submenu in a pulldown
- menu?
-
- Answer: Yes you can. A cascade button has an activate callback which is called
- when you click on it and it doesn't have a submenu. It can have a mnemonic,
- but keyboard traversal using the arrow keys in the menu will skip over it.
-
- -----------------------------------------------------------------------------
- Subject: 180) Should I have a cascade button without a submenu in a pulldown
- menu?
-
- Answer: No. This is forbidden by the style guide. Technically you can do it
- (see previous question) but if you do it will not be Motif style compliant.
- This is unlikely to change - if a "button" is important enough to be in a
- pulldown menu bar with no pulldown, it should be a button elsewhere. (Mind
- you, you won't be able to put accelerators on it elsewhere though.)
-
- -----------------------------------------------------------------------------
- Subject: 181) What is the best way to create popup menus?
- [Last modified: August 92]
-
- Susan Murdock Thompson (from OSF): In general, create a popupMenu as the child
- from which you will be posting it from (ie: if you have a bulletinBoard with a
- PushButton in it and want MB2 on the pushButton to post the popupMenu, create
- the popupMenu as a child of the pushButton). [This parent-child relationship
- seems to make a big difference in the behavior of the popups.] Add an event
- handler to handle buttonPress events. You'll need to check for the correct
- button (what you've specified menuPost to be) before posting the menu.
-
- To create a popup that can be accessible from within an entire client window,
- create it as the child of the top-most widget (but not the shell) and add
- event handlers for the top-most widget and children widgets.
-
- ie:
-
-
- {
-
- XtManageChild(rc=XmCreateRowColumn(Shell1, "rc", NULL, 0));
- XtManageChild(label = XmCreateLabel(rc, "label", NULL, 0));
- XtManageChild(text = XmCreateText(rc, "text", NULL, 0));
- XtManageChild(pushbutton = XmCreatePushButton(rc, "pushbutton", NULL, 0));
-
- n = 0;
- XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); n++;
- popup = XmCreatePopupMenu(rc, "popup", args, n);
-
- XtAddEventHandler(rc, ButtonPressMask, False, PostMenu3, popup);
- XtAddEventHandler(text, ButtonPressMask, False, PostMenu3, popup);
- XtAddEventHandler(label, ButtonPressMask, False, PostMenu3, popup);
- XtAddEventHandler(pushbutton, ButtonPressMask, False, PostMenu3, popup);
-
- XtManageChild(m1 = XmCreatePushButton(popup, "m1", NULL, 0));
- XtManageChild(m2 = XmCreatePushButton(popup, "m2", NULL, 0));
- XtManageChild(m3 = XmCreatePushButton(popup, "m3", NULL, 0));
-
- XtAddCallback(m1, XmNactivateCallback, SayCB, "button M1");
- XtAddCallback(m2, XmNactivateCallback, SayCB, "button M2");
- XtAddCallback(m3, XmNactivateCallback, SayCB, "button M3");
- }
-
- /* where PostMenu3 is ... */
-
- PostMenu3 (w, popup, event)
- Widget w;
- Widget popup;
- XButtonEvent * event;
- {
- printf("menuPost = 3, button %d\n", event->button);
-
- if (event->button != Button3)
- return;
- XmMenuPosition(popup, event);
- XtManageChild(popup);
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 182) How do popup menus work?
- [Last modified: Feb 98]
-
- Answer:
-
- When a popup menu is created as the child of a widget the menu system installs
- a translation on the parent of the popup and descendants with an action which:
- (1) when 3-rd button (the default for the menuPost resource) is pressed the
- cursor changes and the mouse is grabbed for 3 seconds; (2) disables event
- handlers on the descendants and the handlers are never called; (3) an event
- handler installed on the parent works fine.
-
- It is done so that the correct event handler will (in fact) be called. There
- is a grab with owner_events true. The grab is released by a timer, but
- normally the posted menu shell puts up it's own grab.
-
- If you only have widgets then you can use the subwindow field in the event to
- identify the original widget. If you have gadgets or other data that you want
- to change the menu for (or use a specific menu for) then you must do a walk of
- the parent's children to find the best match.
-
- One thing to beware of is that even with the grab, because the menu system
- does a grab with owner events true, you must either have an event handler, or
- nothing that will use the event on each widget in the hierarchy of the menu's
- parent. If a child widget has another event handler for button down, it may
- swallow the event and do something else.
-
- -----------------------------------------------------------------------------
- Subject: 183) How can I disable the button 3 grab if I am not using popup
- menus?
- [Last modified: Nov 98]
-
- Answer: The menu system initiates the 3 second grab if XmNpopupEnabled is true
- (the default), whether or not you will actually be popping up a menu. You can
- avoid this grab by setting XmNpopupEnabled to False for widgets that do no
- have popup menus.
-
- -----------------------------------------------------------------------------
- Subject: 184) Should I use translation tables or actions for popup menus?
- [Last modified: August 92]
-
- Answer: The original goal of popupMenus was that the user would not have to
- specify an event handler to manage popupMenus; however, that did not become
- reality. Larry Rogers wrote:
-
- > There appear to be two ways to manage popup menus. I
- > am curious what the correct way would be:
-
- 1. Change the translation table of the widget with the
- popup child to popup the menu. Note that this does
- not currently working for many widgets, because aug-
- menting their translations, even for augment breaks
- the widget.
-
- 2. Add an event handler at creation to the widget; then
- determine if the event that caused the event handler
- to be called is the current button being used by the
- menu as its activation button.
-
- Susan Murdock Thompson (from OSF) replied: *Theoretically, you should be able
- to do both.* Our documentation says use event handlers. Our tests for the
- toolkit use event handlers and for UIL use translations. (Although I tried an
- event handler with a UIL test and it works).
-
- -----------------------------------------------------------------------------
- Subject: 185) What are the known bugs in popup menus?
- [Last modified: August 92]
-
- Answer: As at Motif 1.1.4, the bugs for which an OSF PIR exists are:
-
- (3) Menus not being sticky (ie: posted on a Btn CLICK) [ Note:this problem
- occurs with OptionMenus as well] (PIR 3435)
-
- (6) Destroying a widget with an associated popupMenu results in "Warning:
- Attempt to remove non-existant passive grab" (PIR 2972)
-
- (7) Current documentation insufficient regarding requirements for success in
- using PopupMenus. (PIR 3433)
-
-
- -----------------------------------------------------------------------------
- Subject: 186) Can I have multiple popup menus on the same widget?
- [Last modified: July 96]
-
- Answer: Ken Lee wrote that with Motif 1.2.*, you can have multiple popup menus
- on a single widget as long as you set the menu's XmNmenuPost correctly.
-
- The older answer for Motif 1.1.* was: If you want to have several popups
- (activated by different mouse buttons) on the same widget..., well, that
- doesn't work yet.
-
- If you want to have several popups on different children... that works. But
- don't put a popup on the parent (manager) widget, or it will rule!
-
- -----------------------------------------------------------------------------
- Subject: 187) How can I change the shell title of a tear-off menu?
- [Last modified: Dec 97]
-
- Answer: There is menu title resource to set this in Motif 2.0. In Motif 1.*,
- explicitly set XmNtitle and XmNtitleEncoding on the menu shell, possibly in
- your XmNtearOffMenuActivateCallback.
-
- Note: The shell that is about to be mapped is the parent of the widget passed
- to the XmNtearOffMenuActivateCallback.
-
- Thanks to Ken Lee (http://www.rahul.net/kenton/), Fernando D. Mato Mira
- (matomira@lig.di.epfl.ch), and Michael O'Keefe
- (Michael.OKeefe@LMC.Ericsson.SE)
-
- -----------------------------------------------------------------------------
- Subject: 188) Can I programmatically tear-off a menu?
- [Last modified: Dec 97]
-
- Answer: As far as I know, there is no supported (or easy and unsupported) way
- to do this.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 189) What widgets are valid within Motif menus?
- [Last modified: July 96]
-
- Answer: In Motif 1.*, menus may contain labels, push buttons, cascade buttons,
- toggle buttons, and separators (widgets or gadgets). RowColumn will complain
- if you use anything else within a menu. Note that drawn buttons and arrow
- buttons are not allowed.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 190) Can I create multi-column popup or pulldown menus?
- [Last modified: Nov 96]
-
- Answer: Yes. Menu panes are just XmRowColumn widgets. Set XmNpacking to
- XmPACK_COLUMN and XmNnumColumns to the number of columns you want.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 191) How can I keep my program from hanging if a user activates a
- popup that is a child of an insensitive push button?
- [Last modified: Nov 96]
-
- Answer: There are two workarounds for this problem. You need only use one.
-
- 1. Set XmNancestorSensitive to False on the XmMenuShell when its parent is
- insensitive.
-
- 2. Set XmNpopupEnabled on the menu pane (XmRowColumn widget) to False when
- the menu is insensitive.
-
- Reset the resource to True if you make your button sensitive again.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 192) TOPIC: DRAG AND DROP
-
- -----------------------------------------------------------------------------
- Subject: 193) Where can I find info and examples of the Motif drag and drop
- protocol?
- [Last modified: Jul 97]
-
- Answer: A technical specification is available over the Internet:
-
- OSF/Motif Drag and Drop Protocol
- ftp://ftp.red-bean.com/pub/teak/
-
- Thanks to Elliot Lee, sopwith@redhat.com
-
- OSF's "Motif Programmers Guide" includes complete source code for several drag
- and drop demos. Chapter 15 has simple examples demonstrating the basic
- behaviour. Appendix B has a more complex example. (The source code for some
- of the demos also appears on the OSF tape.)
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 194) 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 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: 195) Can I register client data for the Motif XmDropSite drop
- callback?
- [Last modified: Mar 96]
-
- Answer: Apparently not. You can, however, put your data in the drop site
- widget's XmNuserData. Or, you can use the Xlib context manager.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 196) Can unmanged widgets be valid (drag-and-drop) drop sites?
- [Last modified: Nov 96]
-
- Answer: Yes, the drop site stacking order is independent of the window
- stacking order. You can modify the active drop site order with
- XmDropSiteConfigureStackingOrder() or by using XmDropSiteUpdate() to change
- the drop site's XmNdropSiteActivity resource (to XmDROP_SITE_ACTIVE or
- XmDROP_SITE_INACTIVE).
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 197) TOPIC: INPUT FOCUS
-
- -----------------------------------------------------------------------------
- Subject: 198) How can I specify the widget that should have the keyboard
- focus when my application starts up?
- [Last modified: June 95]
-
- Answer: In Motif 1.2 or later, use XmNinitialFocus on the manager widget.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 199) How can I specify my own keyboard traversal order?
- [Last modified: May 97]
-
- Answer: In Motif 1.2 or later, set the XmNnavigationType resource for the
- widgets in your tab group. When any widget in a hierarchy has an
- XmNnavigationType of XmEXCLUSIVE_TAB_GROUP, traversal of tab groups in the
- hierarchy proceeds to widgets in the order in which their XmNnavigationType
- resources were specified as XmEXCLUSIVE_TAB_GROUP or XmSTICKY_TAB_GROUP.
-
- Earlier releases have a XmAddTabGroup(), but that is obsolete and has been
- replaced by XmNnavigationType.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 200) How can I determine which widget has keyboard focus?
- [Last modified: Sept 95]
-
- Answer: In Motif 1.2 or later, use XmGetFocusWidget().
-
- Ken Lee
-
- --------------------------------------------------------------------------
- Subject: 201) 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: 202) How can I have a modal dialog which has to be answered before
- the application can continue?
- [Last modified: Sep 97]
-
- Answer: Warning: the following answer relies on nested event loops. Use these
- with caution, as nested loops can affect the ordering of events and widget
- destruction, leading to several undesirable side effects.
-
- Ken Lee
-
-
- Note: J.-N. Meurisse (uunet!rc4.vub.ac.be!jnmeuris) sent a correction to the
- following code fragment. Change:
-
- XtAddCallback(dialog, XmNpopdownCallback, ...)
- to
- XtAddCallback(XtParent(dialog), XmNpopdownCallback, ...)
-
- 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 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.
- */
-
- /*
- * 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[];
- int argc;
- {
- Widget parent, button, toplevel;
- XmString label;
- void pushed();
-
- toplevel = XtAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL, 0);
-
- label = XmStringCreateLocalized("/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;
- extern void response();
-
- answer = 0;
- if (!dialog) {
- dialog = XmCreateQuestionDialog(parent, "dialog", NULL, 0);
- yes = XmStringCreateLocalized("Yes");
- no = XmStringCreateLocalized("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);
- /* if the user interacts via the system menu: */
- /* SEE CORRECTION ABOVE */
- XtAddCallback(dialog, XmNpopdownCallback, response, &answer);
- }
- text = XmStringCreateLocalized(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:
- *answer = NO;
- 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: 203) TOPIC: MEMORY AND SPEED
-
- -----------------------------------------------------------------------------
- Subject: 204) When can I free data structures passed to or retrieved from
- Motif?
-
- Answer: In most cases, especially for XmStrings and XmFontLists, Motif copies
- data passed to it or retrieved from it, so it may be freed immediately.
- Server-side resources, such as pixmaps and color cells, however, are not
- copied, so should not be freed. More recent versions of Motif are better than
- earlier versions and exceptions should be documented.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 205) What memory leaks are known? Why does my application grow in
- size?
- [Last modified: Jun 98]
-
- Answer: Detailed information about Motif-related memory leaks (and how you can
- avoid them) can be found in two great articles by Kenton Lee:
-
- http://www.rahul.net/kenton/txa/feb96.html
- http://www.rahul.net/kenton/txa/mar96.html
-
- Answer: Motif 1.0 has many memory leaks, particularly in XmString
- manipulation. Switch to Motif 1.1. 1.2, or 2.0.
-
- Answer: In Motif 1.2.x, if one is using XmStringGetNextSegment very often
- (several 100 times) you'll get very big memory leaks, because one has to
- XtFree() also the charset variable and not only the variable holding the text
- value. Thanks to Ingo Schulz (ing@bb-data.de).
-
- 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,
- XmStringCreateLocalized, 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.
-
- Answer: Josef Nelissen wrote: at least in Motif 1.1.4, X11R4 on a HP 720, the
- XmText/XmTextFieldSetString() functions have a memory leak. The old
- value/contents of the Widget isn't freed correctly. To work around this bug,
- one should use a XmText Widget (in single-line-mode) instead of a XmTextField
- Widget (the solution fails with XmTextField Widgets !) and replace any
-
- XmTextSetString(text_widget, str);
-
- by
-
- XmTextReplace(text_widget, (XmTextPosition) 0,
- XmTextGetLastPosition(text_widget), str);
-
-
- -----------------------------------------------------------------------------
- Subject: 206) Why do I get so many uninitilized memory read (UMR) errors when
- I run Purify[tm] on my Motif programs?
- [Last modified: July 96]
-
- Answer: Purify's reports are suggestions and do not always indicate real bugs.
- The X libraries frequently allocate dynamic memory, e.g., for attribute or
- event structures, but don't explicitly initialize all of the memory. X keeps
- track of which structure fields are valid via a union type or a mask. When X
- tries to copy or write the memory (part of which is uninitialized) as one
- block, Purify reports a UMR. This is not a bug and you can safely supress or
- ignore the report. Yes, X could initialize the unused field, but since this
- happens alot, the needless operation could negatively affect your performance.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 207) 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: 208) 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.
-
- Answer: There are some more hints at http://www.rahul.net/kenton/perf.html
-
- -----------------------------------------------------------------------------
- Subject: 209) Why is my application so huge?
-
- Answer: The typical size of a statically linked Motif app is in the megabytes.
- This is often caused by the size of libXm.a. A large part of this gets linked
- in to even trivial Motif programs. You can reduce the code size by linking
- against shared libraries if they are available. Running "strip" on the
- executable can often reduce size. Note that the size of the running program
- should be measured by "ps", not by the code size.
-
- -----------------------------------------------------------------------------
- Subject: 210) How can I improve performance when creating and deleting
- hundreds of text widgets?
- [Last modified: Feb 98]
-
- Answer: Ken Lee writes: This is mostly a problem with Motif 1.2.0 through
- 1.2.2. Later versions are much better. If you're stuck with an early version
- of Motif 1.2, you may be able to greatly improve performance by batching the
- drop site updates: surround the create or delete code with
- XmDropSiteStartUpdate and XmDropSiteEndUpdate. Alternatively, you can
- completely disable drag-and-drop for your application. See the subject: "How
- can I disable Drag and Drop in my Motif 1.2 client?"
-
- Mike Youell adds: Using XmDropSiteStartUpdate sped up destruction of widgets
- in Motif 1.2.5. Also it may be worthwhile reminding people that it is not as
- simple as "surround the create or delete code with XmDropSiteStartUpdate and
- XmDropSiteEndUpdate" because it doesn't destroy the widgets when you do a
- XtDestroy. X does it at a later time, hence you still need to be inside the
- drop-site update when these destroys are completed by X.
-
-
- -----------------------------------------------------------------------------
- Subject: 211) After I call XtSetValues, when will I see the changes in my
- GUI?
- [Last modified: Nov 97]
-
- Answer: For each change you make, the widget decides if it needs to redraw.
- If so, Xt calls XtClearArea to generate an expose event. You main loop
- dispatches the resulting expose event to your widget, causing a redisplay.
- Note that the redisplay may be delayed somewhat if you do not immediately
- return to the event loop after calling XtSetValues. You can often work around
- this by calling XmUpdateDisplay().
-
- Note also that you should try to make all your changes in one large
- XtSetValues changing several values at once. If you call XtSetValues
- individually for each change you need to make, you could generate several
- expose events and redraw several times.
-
- -----------------------------------------------------------------------------
- Subject: 212) TOPIC: XMSTRING
-
- -----------------------------------------------------------------------------
- Subject: 213) What string functions differ in Motif 1.1 and 1.2? Is
- XmStringCreateSimple obsolete? What should I use instead?
- [Last modified: Feb 95]
-
- Answer: XmStringCreateSimple is obsolete. Use XmStringCreateLocalized instead.
-
- Matthew B. Evans (Evans@EDFUA6.ctis.af.mil) writes:
-
- We just upgraded from Motif 1.1 to 1.2. When we went to compile, no problem,
- but our XmStringCreateSimple() and XmStringGetLtoR() seemed to have problems.
-
- As we found out, Motif 1.2 STRONGLY recommends to use the constant
- XmFONTLIST_DEFAULT_TAG instead of XmSTRING_DEFAULT_CHARSET in all of the
- XmStringXXX() functions, as XmSTRING_DEFAULT_CHARSET is maintained only for
- compatibility (not a whole lot in my opinion). I got this information from
- Book 6B from O'Reilly.
-
- You may want to take a look at this book if you can. Some XmString functions
- are outdated and maintained only for compatibility, whereas some don't
- function correctly when using XmSTRING_DEFAULT_CHARSET (from our in-depth
- tests).
-
- We have changed all our XmStringCreateSimple() to XmStringCreateLocalized()
- (as suggested in book 6B) and changed all XmSTRING_DEFAULT_CHARSET to
- XmFONTLIST_DEFAULT_TAG.
-
- [Thanks to John West (jwest@nas.nasa.gov) for fixing a typo in the above.]
-
- NOTE: All string answers in this FAQ now use XmStringCreateLocalized rather
- than XmStringCreateSimple. The documentaton makes it clear that
- XmStringCreateSimple is obsolete and is only kept for compatibility with Motif
- 1.1. New applications should not use this function since XmStringCreateSimple
- may disappear in a subsequent Motif release. (Thanks to Miguel Angel Chamochin
- (mangel@tid.es) for reminding me to fix this mess.)....ksall@cen.com.
-
- -----------------------------------------------------------------------------
- Subject: 214)* How can I get the ASCII text out of an XmString?
- [Last modified: Feb 02]
-
- Answer: In Motif 1.x, use XmStringGetLtoR:
-
- char *str;
- XmString xmstr;
- XmStringGetLtoR(xmstr, XmSTRING_DEFAULT_CHARSET, &str);
-
-
- In Motif 2.x, use XmStringUnparse:
-
- str = XmStringUnparse(xmstr, NULL, 0, XmCHARSET_TEXT, NULL, 0, NULL);
-
-
- In both cases, you should free the string to avoid a memory leak:
-
- XtFree(str);
-
-
- -----------------------------------------------------------------------------
- Subject: 215) 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: 216) 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: 217) Why does using XmStringDraw cause a BadFont error?
- [Last modified: Mar 96]
-
- Answer: Thomas Berlage (berlage@gmdzi.gmd.de) wrote: You could call this a bug
- in Motif. You pass a GC to XmStringDraw, however, Motif wants to use the fonts
- from the font list to draw the string. Therefore it replaces the font of the
- GC temporarily with some fonts of its own as specified in the font list. In
- the end it tries to restore the old font of the GC. There comes the problem:
-
- If a GC uses the default font, the client side GC structure does not have a
- valid font id (that is the 0xffffffff you may see in the error message). Motif
- tries to restore this invalid id at the end.
-
- The workaround is: Before drawing with XmStringDraw, set the font id of the GC
- to any valid font id, for example using
-
- XSetFont (display, gc, XLoadFont (display, "fixed"));
-
- Another solution is available from "Harry's Motif Programming Corner", Harald
- Albrecht, albrecht@igpm.rwth-aachen.de, who writes:
-
- "It's somewhat longer but doesn't rely on a font named "fixed" installed on
- your platform. Instead it takes a fontlist and then uses the first font listed
- there. You'll find this source together with a short demo program (which
- creates a DrawingArea and then paints some text in it) on: ftp.igpm.rwth-
- aachen.de (134.130.161.30) in: /arc/pub/unix/motif/RenderXmString.tar.gz
-
- There's also a html page available: Harry's Motif Programming Corner
- http://www.igpm.rwth-aachen.de/~albrecht/motifcorner.html
-
- Thanks to Harald Albrecht (albrecht@igpm.rwth-aachen.de). URL corrected by
- irca (irca@zip.cra.enel.it).
-
- -----------------------------------------------------------------------------
- Subject: 218) How can I control color of individual strings to show status,
- etc.?
- [Last modified: June 95]
-
- Answer: This is difficult to do with Motif 1.X. If you can, upgrade to Motif
- 2.0, which supports colored XmStrings.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 219) TOPIC: DIALOGS
-
- -----------------------------------------------------------------------------
- Subject: 220) 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: 221) 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);
-
- another Answer:
-
- I had a some people asking about my xmSmartMessageBoxWidget
-
- It's public domain, and needs Motif-1.2 and is available at
- ftp.x.org:/contrib/widget/SmartMB.tar.Z.
-
- The basic idea behind it is that it allows the programmer to specify the
- management of child widgets in 4 areas: Label, Control, Separator and Action.
- You can have up to 1 Label, 1 Control, 1 Separator and as many Action children
- as you want. It does not REQUIRE any of these, and there is no unmanaging of
- extra widgets, as the programmer creates what is needed.
-
- Thanks for the smart dialog info to: John L. Cwikla Wolfram Research, Inc.
- cwikla@wri.com
-
- -----------------------------------------------------------------------------
- Subject: 222) Why do dialog title bars 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: 223) 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?
- [Last modified: Dec '94]
-
- Answer: David Brooks <dbrooks@ics.com> writes: The dialog window won't get
- expose events until the window manager has fielded the map request, done the
- reparenting with all that entails, and finally convinced the server that the
- window is for real. The safe way of doing it is [below].
-
- 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: 224) 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?
- [Last modified: Feb 95]
-
- Answer: Set the resource XmNdefaultPosition for the popup to False. Set the
- position of the popup by the resource values of XmNx and XmNy. Do not use
- XtMoveWidget, as this is for widget writers only. Here's a demo program from
- Dan Heller:
-
- /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates.
- * This program is freely distributable without licensing fees and
- * is provided without guarantee or warranty expressed or implied.
- * This program is -not- in the public domain. This program is
- * taken from the Motif Programming Manual, O'Reilly Volume 6.
- */
-
- /* map_dlg.c -- Use the XmNmapCallback to automatically position
- * a dialog on the screen. Each time the dialog is displayed, it
- * is mapped down and to the right by 200 pixels in each direction.
- */
- #include <Xm/MessageB.h>
- #include <Xm/PushB.h>
-
- /* main() --create a pushbutton whose callback pops up a dialog box */
- main(argc, argv)
- char *argv[];
- {
- Widget toplevel, button;
- XtAppContext app;
- void pushed();
-
- toplevel = XtVaAppInitialize(&app, "Demos",
- NULL, 0, &argc, argv, NULL, NULL);
-
- button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
- toplevel, NULL, 0);
- XtAddCallback(button, XmNactivateCallback, pushed, "Hello World");
-
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app);
- }
-
- /* callback function for XmNmapCallback. Position dialog in 200 pixel
- * "steps". When the edge of the screen is hit, start over.
- */
- static void
- map_dialog(dialog, client_data, cbs)
- Widget dialog;
- XtPointer client_data;
- XmAnyCallbackStruct *cbs;
- {
- static Position x, y;
- Dimension w, h;
-
- XtVaGetValues(dialog, XmNwidth, &w, XmNheight, &h, NULL);
- if ((x + w) >= WidthOfScreen(XtScreen(dialog)))
- x = 0;
- if ((y + h) >= HeightOfScreen(XtScreen(dialog)))
- y = 0;
- XtVaSetValues(dialog, XmNx, x, XmNy, y, NULL);
- x += 200, y += 200;
- }
-
- /* pushed() --the callback routine for the main app's pushbutton.
- * Create and popup a dialog box that has callback functions for
- * the Ok, Cancel and Help buttons.
- */
- void
- pushed(w, message)
- Widget w;
- char *message; /* The client_data parameter passed by XtAddCallback */
- {
- Widget dialog;
- Arg arg[3];
- XmString t = XmStringCreateLocalized(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: 225) How can I set the dialog's default button?
- [Last modified: June 95]
-
- Answer: Use XmNdefaultButton on the bulletin board widget.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 226) How can I create a dialog that behaves like, but looks a little
- different from, XmMessageBox?
- [Last modified: June 95]
-
- Answer: Motif 1.2 provides a XmCreateTemplateDialog(), which allows you to
- specify any combination of child widgets.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 227) How can I use Motif's message dialog bitmaps in my own dialogs?
- [Last modified: Nov 95]
-
- Answer: The bitmaps are normally stored in /usr/include/X11/bitmaps (or the
- equivalent bitmaps directory, which is vendor specific) and are cached if you
- create a XmMessageBox. You can retrieve them by name with XmGetPixmap() or
- XmGetPixmapByDepth(). The names of the bitmap files are in the XmMessageBox
- man page.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- END OF PART SIX
-