home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / motif-faq / part6 < prev    next >
Encoding:
Internet Message Format  |  2004-05-05  |  55.1 KB

  1. Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
  2. Message-ID: <motif-faq/part6_1083675484@rtfm.mit.edu>
  3. Supersedes: <motif-faq/part6_1082292761@rtfm.mit.edu>
  4. Expires: 17 Jun 2004 12:58:04 GMT
  5. References: <motif-faq/part1_1083675484@rtfm.mit.edu>
  6. X-Last-Updated: 2002/01/31
  7. Organization: none
  8. Subject: Motif FAQ (Part 6 of 9)
  9. Newsgroups: comp.windows.x.motif,comp.answers,news.answers
  10. Keywords: FAQ question answer
  11. From: kenton@rahul.net (Ken Lee)
  12. Reply-To: kenton@rahul.net (Ken Lee)
  13. Approved: news-answers-request@MIT.EDU
  14. Followup-To: poster
  15. Summary: Motif Frequently Asked Questions (with answers).
  16. Originator: faqserv@penguin-lust.MIT.EDU
  17. Date: 04 May 2004 12:59:12 GMT
  18. Lines: 1460
  19. NNTP-Posting-Host: penguin-lust.mit.edu
  20. X-Trace: 1083675552 senator-bedfellow.mit.edu 565 18.181.0.29
  21. Xref: senator-bedfellow.mit.edu comp.windows.x.motif:75189 comp.answers:57054 news.answers:270858
  22.  
  23. Archive-name: motif-faq/part6
  24. Last-modified: 1 FEB 2002
  25. Posting-Frequency: irregular
  26. Organization: Kenton Lee, X/Motif Consultant, http://www.rahul.net/kenton/
  27. URL:  http://www.rahul.net/kenton/mfaq.html
  28. Version: 8.1
  29.  
  30. -----------------------------------------------------------------------------
  31. Subject: 156)  TOPIC: DRAWING AREA WIDGET
  32.  
  33. -----------------------------------------------------------------------------
  34. Subject: 157)  How can I send an expose event to a Drawing Area widget?  (or
  35. any other, come to that). I want to send an expose event so that it will
  36. redraw itself.
  37. [Last modified: Nov 97]
  38.  
  39. Answer: Use the Xlib call
  40.  
  41. XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True)
  42.  
  43. This clears the widget's window and generates an expose event in doing so.
  44. The widgets expose action will then redraw it.  This uses a round trip
  45. request.  An alternative, without the round trip is
  46.  
  47. from orca!mesa!rthomson@uunet.uu.net  (Rich Thomson):
  48.  
  49. Widget da;
  50. XmDrawingAreaCallbackStruct da_struct;
  51.  
  52. da_struct.reason = XmCR_EXPOSE;
  53. da_struct.event = (XEvent *) NULL;
  54. da_struct.window = XtWindow(da);
  55.  
  56. XtCallCallbacks(da, XmNexposeCallback, (XtPointer) &da_struct);
  57.  
  58. Thanks to rand@ling.umu.se (Ola Andersson) for a correction to the above.
  59.  
  60.  
  61. -----------------------------------------------------------------------------
  62. Subject: 158)  How can I know when a DrawingArea has been resized?  It
  63. generates an expose event whn it is enlarged, but not when it is shrunk.
  64.  
  65. Answer: Use the resize callback.
  66.  
  67. -----------------------------------------------------------------------------
  68. Subject: 159)  How can I create a drawing area widget with a visual type
  69. different from its parent?
  70. [Last modified: Sep 97]
  71.  
  72. Answer: The standard Motif drawing area does not support this.  You can,
  73. however, easily create a subclass with a new Realize class method.  You may
  74. want to create visual type, colormap, and depth resources so you can set these
  75. values at initialization time.
  76.  
  77. In SGI's Motif, such a widget is called SgVisualDrawingArea.  Other Motif
  78. implementations may have similar widgets.
  79.  
  80. Ken Lee, http://www.rahul.net/kenton/
  81.  
  82. -----------------------------------------------------------------------------
  83. Subject: 160)  How can I display postscript in a Motif widget, such as
  84. XmDrawingArea?
  85. [Last modified: Sept 95]
  86.  
  87. Answer: Richard M. Goldstein (rickg@Eng.Sun.COM) writes: If your system
  88. supports the Display PostScript extension (or NX agent), the newer revs of the
  89. dpstkXm library contains a type of drawing area widget designed specifically
  90. for use with DPS.  Source for the latest DPS client-side is also ftp'able from
  91. contrib.
  92.  
  93. Ramiro Estrugo (restrugo@fateware.com) writes: Have a look at ghostscript.
  94. [With] a little editting, you can extract the Ghostview widget and use it in
  95. your application...
  96.  
  97. -----------------------------------------------------------------------------
  98. Subject: 161)  TOPIC: MAIN WINDOW WIDGET
  99.  
  100. -----------------------------------------------------------------------------
  101. Subject: 162)  How can I create a message window in an XmMainWindow?
  102. [Last modified: Nov 95]
  103.  
  104. Answer: XmMainWindow supports a message window, but you cannot specify it via
  105. XmMainWindowSetAreas().  Instead, create the widget as a child of the
  106. XmMainWindow, then specify to the XmMainWindow with XtSetValues() of
  107. XmNmessageWindow.
  108.  
  109. Ken Lee
  110.  
  111. -----------------------------------------------------------------------------
  112. Subject: 163)  TOPIC: SCROLLED WINDOW WIDGET
  113.  
  114. -----------------------------------------------------------------------------
  115. Subject: 164)  How do I tell if a scrolled window's scrollbars are visible?
  116.  
  117. Answer: Use XtGetValues() to get the scrollbar widget ID's, then use
  118. XtIsManaged() to see if they are managed (visible).
  119.  
  120. Ken Lee
  121.  
  122. -----------------------------------------------------------------------------
  123. Subject: 165)  How can I programatically scroll a XmScrolledWindow in
  124. XmAUTOMATIC mode?
  125.  
  126. Answer: In Motif 1.2, use XmScrollVisible().  If you're using a scrolled text
  127. or scrolled list combination widget, use XmTextScroll() or XmListSet*()
  128. instead.
  129.  
  130. The Motif manuals specifically forbid manipulating the scrollbars directly,
  131. but some people have reported success with XmScrollBarSetValues, with the
  132. "notify" parameter set to "True".
  133.  
  134. Ken Lee
  135.  
  136. -----------------------------------------------------------------------------
  137. Subject: 166)  What widget does the XmScrolledWindow use for its clip window?
  138. [Last modified: Apr 98]
  139.  
  140. Answer: In Motif 1.2, if the XmScrolledWindow is using the XmAUTOMATIC
  141. scrolling policy, it automatically creates an XmDrawingArea widget as its clip
  142. window.  If you wish, you can retrieve the XmDrawingArea's widget ID by using
  143. XtGetValues on the XmNclipWindow resource and then set resources on that
  144. widget.  Some useful resources are XmNbackground and XmNresizeCallback.
  145.  
  146. Note that Motif 2.X uses a new XmClipWindow widget instead of the
  147. XmDrawingArea.  Since XmClipWindow is subclassed from XmDrawingArea, the above
  148. resources should still work.
  149.  
  150. Ken Lee
  151.  
  152. -----------------------------------------------------------------------------
  153. Subject: 167)  How do I create a scrolled window with only one scrollbar?
  154. [Last modified: July 95]
  155.  
  156. Answer: If you're using the default application-defined scrolling mode, you
  157. can just create one and specify NULL for the other.  If, however, you're using
  158. automatic scrolling, retrieve the ID of the unwanted scrollbar with
  159. XmNhorizontalScrollBar or XmNverticalScrollBar and unmanage that widget:
  160.  
  161.  
  162. Widget hScroll;
  163. XtVaGetValues(scrollbar, XmNhorizontalScrollBar, &hScroll, NULL);
  164. XtUnmanageChild(hScroll);
  165.  
  166.  
  167. Thanks to Ken Lee, http://www.rahul.net/kenton/.  Typo corrected by Paul
  168. Tomblin, ptomblin@canoe.com.
  169.  
  170. -----------------------------------------------------------------------------
  171. Subject: 168)  TOPIC: MENUS
  172.  
  173. -----------------------------------------------------------------------------
  174. Subject: 169)  How can I change the cursor used in Motif menus?
  175. [Last modified: Oct 95]
  176.  
  177. Answer: Set XmNmenuCursor on XmScreen (Motif 1.2) or XmRowColumn (Motif 1.1).
  178. This should be set globally at start-up time, e.g., usually via an app-
  179. defaults file.
  180.  
  181. Ken Lee
  182.  
  183. -----------------------------------------------------------------------------
  184. Subject: 170)  How do I put my help menu on the far right of my menubar?
  185. [Last modified: Oct 95]
  186.  
  187. Answer: Set the XmNmenuHelpWidget resource of the menu bar to the help menu's
  188. cascade button.
  189.  
  190. Ken Lee
  191.  
  192. -----------------------------------------------------------------------------
  193. Subject: 171)  Can I change or disable the menu bar accelerator from the
  194. default (F10)?
  195. [Last modified: May 97]
  196.  
  197. Answer: Changing it will confuse some of your users.  If you must, this
  198. accelerator is controlled by these resources on the menu bar's XmRowColumn:
  199. XmNpopupEnabled (enables accelerators) and XmNmenuAccelerator (specifies the
  200. accelerator key).
  201.  
  202. Ken Lee
  203.  
  204. -----------------------------------------------------------------------------
  205. Subject: 172)  How do I set the current choice in a radio box or an option
  206. menu?
  207. [Last modified: May 95]
  208.  
  209. Answer: Set the XmNmenuHistory resource on its XmRowColumn parent.
  210.  
  211. Ken Lee
  212.  
  213. buser@tartan.com (Mark) sent this code fragment:
  214.  
  215. Widget      menu;
  216. int         num_buttons;
  217. WidgetList  buttons;
  218.  
  219. XtVaGetValues( simple_option_widget, XmNsubMenuId, &menu, NULL);
  220.  
  221. XtVaGetValues( menu, XmNnumChildren, &num_buttons,
  222.         XmNchildren, &buttons, NULL ) ;
  223.  
  224. and change current selection with:
  225.  
  226. XtVaSetValues( simple_option_widget, XmNmenuHistory, buttons[index], NULL ) ;
  227.  
  228. /* where index is between 0 and num_buttons */
  229.  
  230. Thanks to Phil Gehlich <pgehlich@hp7001.ecae.StorTek.COM> for a correction.
  231.  
  232. -----------------------------------------------------------------------------
  233. Subject: 173)  How can I determine the item selected in a a radio box or
  234. option menu?
  235.  
  236. Answer: The value of the XmNmenuHistory resource of the XmRowColumn parent is
  237. the widget ID of the last selected item.  It works the same way for all menus
  238. and radio boxes.
  239.  
  240. Ken Lee
  241.  
  242. -----------------------------------------------------------------------------
  243. Subject: 174)  How can I change the cascade indicator on an option menu?
  244. [Last modified: Dec 97]
  245.  
  246. Answer: Set XmNcascadePixmap on the option menu's cascade button gadget.
  247.  
  248. Ken Lee
  249.  
  250. -----------------------------------------------------------------------------
  251. Subject: 175)  How do I unset an XmToggleButton in a radio box?  If a radio-
  252. mode toggle button is set and I XtSetValues XmNset a different toggle button,
  253. the first radio button is not automatically unset.  How do can I automatically
  254. unset the first button?
  255. [Last modified: Jun 98]
  256.  
  257. Answer: There are two easy ways to do this.  First, you can set the toggle
  258. with  XmNmenuHistory on the radio box instead of XmNset on the toggle button.
  259. Second, you can use XmToggleButtonSetState() with True for the notify
  260. argument.
  261.  
  262. Note that some people have reported that XmNmenuHistory correctly sets the
  263. toggle state but the toggle is not always redrawn to show the new state.  This
  264. is a bug in their implementation of Motif.  If you cannot get a patch, you
  265. should use the XmToggleButtonSetState() method.
  266.  
  267. Ken Lee
  268.  
  269. -----------------------------------------------------------------------------
  270. Subject: 176)  Can I place a radio box in a pulldown menu?
  271. [Last modified: May 97]
  272.  
  273. Answer: You cannot place a XmRowColumn widget child in a menu pane.  Since the
  274. menu pane itself is a XmRowColumn widget, however, you can enable
  275. XmNradioBehavior on it.  This only works if all of the menu items are radio
  276. buttons.
  277.  
  278. An alternative is to manage your radio behavior via your button callback
  279. functions.  This is more work, but much more flexible.
  280.  
  281. Ken Lee
  282.  
  283. -----------------------------------------------------------------------------
  284. Subject: 177)  How do I make a menu choice insensitive if it was created with
  285. XmVaCreateSimplePulldownMenu?
  286. [Last modified: Sept 94]
  287.  
  288. Answer: According to the Motif manual, the buttons are named "button_n", where
  289. "n" is an integer starting from 0.  You can use XtNameToWidget() to convert
  290. these names to widget ID's.
  291.  
  292. Ken Lee
  293.  
  294. -----------------------------------------------------------------------------
  295. Subject: 178)  What widgets can I put inside a menubar?
  296. [Last modified: Oct 95]
  297.  
  298. Answer: You can only put cascade buttons (widgets or gadgets) in the top level
  299. of menubars. However, the children of these cascade buttons can be pushbuttons
  300. with labels, pushbuttons with pixmaps, toggle buttons, separators, other
  301. cascade buttons.
  302.  
  303. -----------------------------------------------------------------------------
  304. Subject: 179)  Can I have a cascade button without a submenu in a pulldown
  305. menu?
  306.  
  307. Answer: Yes you can. A cascade button has an activate callback which is called
  308. when you click on it and it doesn't have a submenu. It can have a mnemonic,
  309. but keyboard traversal using the arrow keys in the menu will skip over it.
  310.  
  311. -----------------------------------------------------------------------------
  312. Subject: 180)  Should I have a cascade button without a submenu in a pulldown
  313. menu?
  314.  
  315. Answer: No. This is forbidden by the style guide. Technically you can do it
  316. (see previous question) but if you do it will not be Motif style compliant.
  317. This is unlikely to change - if a "button" is important enough to be in a
  318. pulldown menu bar with no pulldown, it should be a button elsewhere.  (Mind
  319. you, you won't be able to put accelerators on it elsewhere though.)
  320.  
  321. -----------------------------------------------------------------------------
  322. Subject: 181)  What is the best way to create popup menus?
  323. [Last modified: August 92]
  324.  
  325. Susan Murdock Thompson (from OSF): In general, create a popupMenu as the child
  326. from which you will be posting it from (ie: if you have a bulletinBoard with a
  327. PushButton in it and want MB2 on the pushButton to post the popupMenu, create
  328. the popupMenu as a child of the pushButton).  [This parent-child relationship
  329. seems to make a big difference in the behavior of the popups.]  Add an event
  330. handler to handle buttonPress events.  You'll need to check for the correct
  331. button (what you've specified menuPost to be) before posting the menu.
  332.  
  333. To create a popup that can be accessible from within an entire client window,
  334. create it as the child of the top-most widget (but not the shell) and add
  335. event handlers for the top-most widget and children widgets.
  336.  
  337. ie:
  338.  
  339.  
  340. {
  341.  
  342. XtManageChild(rc=XmCreateRowColumn(Shell1, "rc", NULL, 0));
  343. XtManageChild(label = XmCreateLabel(rc, "label", NULL, 0));
  344. XtManageChild(text = XmCreateText(rc, "text", NULL, 0));
  345. XtManageChild(pushbutton = XmCreatePushButton(rc, "pushbutton", NULL, 0));
  346.  
  347. n = 0;
  348. XtSetArg(args[n], XmNmenuPost, "<Btn3Down>"); n++;
  349. popup = XmCreatePopupMenu(rc, "popup", args, n);
  350.  
  351. XtAddEventHandler(rc, ButtonPressMask, False, PostMenu3, popup);
  352. XtAddEventHandler(text, ButtonPressMask, False, PostMenu3, popup);
  353. XtAddEventHandler(label, ButtonPressMask, False, PostMenu3, popup);
  354. XtAddEventHandler(pushbutton, ButtonPressMask, False, PostMenu3, popup);
  355.  
  356. XtManageChild(m1 = XmCreatePushButton(popup, "m1", NULL, 0));
  357. XtManageChild(m2 = XmCreatePushButton(popup, "m2", NULL, 0));
  358. XtManageChild(m3 = XmCreatePushButton(popup, "m3", NULL, 0));
  359.  
  360. XtAddCallback(m1, XmNactivateCallback, SayCB, "button M1");
  361. XtAddCallback(m2, XmNactivateCallback, SayCB, "button M2");
  362. XtAddCallback(m3, XmNactivateCallback, SayCB, "button M3");
  363. }
  364.  
  365. /* where PostMenu3 is ... */
  366.  
  367. PostMenu3 (w, popup, event)
  368. Widget w;
  369. Widget popup;
  370. XButtonEvent * event;
  371. {
  372. printf("menuPost = 3, button %d\n", event->button);
  373.  
  374. if (event->button != Button3)
  375. return;
  376. XmMenuPosition(popup, event);
  377. XtManageChild(popup);
  378. }
  379.  
  380.  
  381. -----------------------------------------------------------------------------
  382. Subject: 182)  How do popup menus work?
  383. [Last modified: Feb 98]
  384.  
  385. Answer:
  386.  
  387. When a popup menu is created as the child of a widget the menu system installs
  388. a translation on the parent of the popup and descendants with an action which:
  389. (1) when 3-rd button (the default for the menuPost resource) is pressed the
  390. cursor changes and the mouse is grabbed for 3 seconds; (2) disables event
  391. handlers on the descendants and the handlers are never called; (3) an event
  392. handler installed on the parent works fine.
  393.  
  394. It is done so that the correct event handler will (in fact) be called.  There
  395. is a grab with owner_events true.  The grab is released by a timer, but
  396. normally the posted menu shell puts up it's own grab.
  397.  
  398. If you only have widgets then you can use the subwindow field in the event to
  399. identify the original widget.  If you have gadgets or other data that you want
  400. to change the menu for (or use a specific menu for) then you must do a walk of
  401. the parent's children to find the best match.
  402.  
  403. One thing to beware of is that even with the grab,  because the menu system
  404. does a grab with owner events true, you must either have an event handler, or
  405. nothing that will use the event on each widget in the hierarchy of the menu's
  406. parent.  If a child widget has another event handler for button down, it may
  407. swallow the event and do something else.
  408.  
  409. -----------------------------------------------------------------------------
  410. Subject: 183)  How can I disable the button 3 grab if I am not using popup
  411. menus?
  412. [Last modified: Nov 98]
  413.  
  414. Answer: The menu system initiates the 3 second grab if XmNpopupEnabled is true
  415. (the default), whether or not you will actually be popping up a menu.  You can
  416. avoid this grab by setting XmNpopupEnabled to False for widgets that do no
  417. have popup menus.
  418.  
  419. -----------------------------------------------------------------------------
  420. Subject: 184)  Should I use translation tables or actions for popup menus?
  421. [Last modified: August 92]
  422.  
  423. Answer: The original goal of popupMenus was that the user would not have to
  424. specify an event handler to manage popupMenus; however, that did not become
  425. reality.  Larry Rogers wrote:
  426.  
  427. > There appear to be two ways to manage popup menus.  I
  428. > am curious what the correct way would be:
  429.  
  430. 1.  Change the translation table of the widget with the
  431.     popup child to popup the menu.  Note that this does
  432.     not currently working for many widgets, because aug-
  433.     menting their translations, even for augment breaks
  434.     the widget.
  435.  
  436. 2.  Add an event handler at creation to the widget; then
  437.     determine if the event that caused the event handler
  438.     to be called is the current button being used by the
  439.     menu as its activation button.
  440.  
  441. Susan Murdock Thompson (from OSF) replied: *Theoretically, you should be able
  442. to do both.*  Our documentation says use event handlers.  Our tests for the
  443. toolkit use event handlers and for UIL use translations.  (Although I tried an
  444. event handler with a UIL test and it works).
  445.  
  446. -----------------------------------------------------------------------------
  447. Subject: 185)  What are the known bugs in popup menus?
  448. [Last modified: August 92]
  449.  
  450. Answer: As at Motif 1.1.4, the bugs for which an OSF PIR exists are:
  451.  
  452. (3)  Menus not being sticky (ie: posted on a Btn CLICK)  [ Note:this problem
  453. occurs with OptionMenus as well]  (PIR 3435)
  454.  
  455. (6)  Destroying a widget with an associated popupMenu results in "Warning:
  456. Attempt to remove non-existant passive grab" (PIR 2972)
  457.  
  458. (7)  Current documentation insufficient regarding requirements for success in
  459. using PopupMenus.  (PIR 3433)
  460.  
  461.  
  462. -----------------------------------------------------------------------------
  463. Subject: 186)  Can I have multiple popup menus on the same widget?
  464. [Last modified: July 96]
  465.  
  466. Answer: Ken Lee wrote that with Motif 1.2.*, you can have multiple popup menus
  467. on a single widget as long as you set the menu's XmNmenuPost correctly.
  468.  
  469. The older answer for Motif 1.1.* was: If you want to have several popups
  470. (activated by different mouse buttons) on the same widget..., well, that
  471. doesn't work yet.
  472.  
  473. If you want to have several popups on different children... that works.  But
  474. don't put a popup on the parent (manager) widget, or it will rule!
  475.  
  476. -----------------------------------------------------------------------------
  477. Subject: 187)  How can I change the shell title of a tear-off menu?
  478. [Last modified: Dec 97]
  479.  
  480. Answer: There is menu title resource to set this in Motif 2.0.  In Motif 1.*,
  481. explicitly set XmNtitle and XmNtitleEncoding on the menu shell, possibly in
  482. your XmNtearOffMenuActivateCallback.
  483.  
  484. Note: The shell that is about to be mapped is the parent of the widget passed
  485. to the XmNtearOffMenuActivateCallback.
  486.  
  487. Thanks to Ken Lee (http://www.rahul.net/kenton/), Fernando D. Mato Mira
  488. (matomira@lig.di.epfl.ch), and Michael O'Keefe
  489. (Michael.OKeefe@LMC.Ericsson.SE)
  490.  
  491. -----------------------------------------------------------------------------
  492. Subject: 188)  Can I programmatically tear-off a menu?
  493. [Last modified: Dec 97]
  494.  
  495. Answer: As far as I know, there is no supported (or easy and unsupported) way
  496. to do this.
  497.  
  498. Ken Lee
  499.  
  500. -----------------------------------------------------------------------------
  501. Subject: 189)  What widgets are valid within Motif menus?
  502. [Last modified: July 96]
  503.  
  504. Answer: In Motif 1.*, menus may contain labels, push buttons, cascade buttons,
  505. toggle buttons, and separators (widgets or gadgets). RowColumn will complain
  506. if you use anything else within a menu.  Note that drawn buttons and arrow
  507. buttons are not allowed.
  508.  
  509. Ken Lee
  510.  
  511. -----------------------------------------------------------------------------
  512. Subject: 190)  Can I create multi-column popup or pulldown menus?
  513. [Last modified: Nov 96]
  514.  
  515. Answer: Yes.  Menu panes are just XmRowColumn widgets.  Set XmNpacking to
  516. XmPACK_COLUMN and XmNnumColumns to the number of columns you want.
  517.  
  518. Ken Lee
  519.  
  520. -----------------------------------------------------------------------------
  521. Subject: 191)  How can I keep my program from hanging if a user activates a
  522. popup that is a child of an insensitive push button?
  523. [Last modified: Nov 96]
  524.  
  525. Answer: There are two workarounds for this problem.  You need only use one.
  526.  
  527. 1.  Set XmNancestorSensitive to False on the XmMenuShell when its parent is
  528. insensitive.
  529.  
  530. 2.  Set XmNpopupEnabled on the menu pane (XmRowColumn widget) to False when
  531. the menu is insensitive.
  532.  
  533. Reset the resource to True if you make your button sensitive again.
  534.  
  535. Ken Lee
  536.  
  537. -----------------------------------------------------------------------------
  538. Subject: 192)  TOPIC: DRAG AND DROP
  539.  
  540. -----------------------------------------------------------------------------
  541. Subject: 193)  Where can I find info and examples of the Motif drag and drop
  542. protocol?
  543. [Last modified: Jul 97]
  544.  
  545. Answer: A technical specification is available over the Internet:
  546.  
  547. OSF/Motif Drag and Drop Protocol
  548. ftp://ftp.red-bean.com/pub/teak/
  549.  
  550. Thanks to Elliot Lee, sopwith@redhat.com
  551.  
  552. OSF's "Motif Programmers Guide" includes complete source code for several drag
  553. and drop demos.  Chapter 15 has simple examples demonstrating the basic
  554. behaviour.  Appendix B has a more complex example.  (The source code for some
  555. of the demos also appears on the OSF tape.)
  556.  
  557. Ken Lee
  558.  
  559. -----------------------------------------------------------------------------
  560. Subject: 194)  How can I disable Drag and Drop in my Motif 1.2 client ?
  561. [Last modified: Oct 94]
  562.  
  563. Answer: Several people have reported that for complex hierarchies of widgets,
  564. drag and drop can slow down an application considerably. If you do not need
  565. drag and drop's significant power, you can disable it in your application.
  566.  
  567. Set the XmDisplay drag-protocol resources to XmDRAG_NONE.  The following code
  568. fragment demonstrates this:
  569.  
  570. #include <Xm/Display.h>
  571.  
  572.  
  573. dw = XmGetXmDisplay(XtDisplay(shell)); /* where "shell" is your client's top-
  574. level shell. */
  575.  
  576. XtVaSetValues(dw, XmNdragInitiatorProtocolStyle, XmDRAG_NONE, NULL);
  577. XtVaSetValues(dw, XmNdragReceiverProtocolStyle,  XmDRAG_NONE, NULL);
  578.  
  579.  
  580. Thanks to Lance Purple (purple@austin.ibm.com)
  581.  
  582. Ken Lee and Christoph Widmer (widmer@einsteinium.SLCS.SLB.COM) describe how to
  583. disable drag and drop from a resource file:
  584.  
  585. *dragInitiatorProtocolStyle: XmDRAG_NONE
  586. *dragReceiverProtocolStyle:  XmDRAG_NONE
  587.  
  588. Ken Lee also notes that as of Motif 1.2, the "Xm" prefix is required for all
  589. token constants in resource files. (Which is why specifying "DRAG_NONE" won't
  590. work but "XmDRAG_NONE" will.)
  591.  
  592. -----------------------------------------------------------------------------
  593. Subject: 195)  Can I register client data for the Motif XmDropSite drop
  594. callback?
  595. [Last modified: Mar 96]
  596.  
  597. Answer: Apparently not.  You can, however, put your data in the drop site
  598. widget's XmNuserData.  Or, you can use the Xlib context manager.
  599.  
  600. Ken Lee
  601.  
  602. -----------------------------------------------------------------------------
  603. Subject: 196)  Can unmanged widgets be valid (drag-and-drop) drop sites?
  604. [Last modified: Nov 96]
  605.  
  606. Answer: Yes, the drop site stacking order is independent of the window
  607. stacking order.  You can modify the active drop site order with
  608. XmDropSiteConfigureStackingOrder() or by using XmDropSiteUpdate() to change
  609. the drop site's XmNdropSiteActivity resource (to XmDROP_SITE_ACTIVE or
  610. XmDROP_SITE_INACTIVE).
  611.  
  612. Ken Lee
  613.  
  614. -----------------------------------------------------------------------------
  615. Subject: 197)  TOPIC: INPUT FOCUS
  616.  
  617. -----------------------------------------------------------------------------
  618. Subject: 198)  How can I specify the widget that should have the keyboard
  619. focus when my application starts up?
  620. [Last modified: June 95]
  621.  
  622. Answer: In Motif 1.2 or later, use XmNinitialFocus on the manager widget.
  623.  
  624. Ken Lee
  625.  
  626. -----------------------------------------------------------------------------
  627. Subject: 199)  How can I specify my own keyboard traversal order?
  628. [Last modified: May 97]
  629.  
  630. Answer: In Motif 1.2 or later, set the XmNnavigationType resource for the
  631. widgets in your tab group.  When any widget in a hierarchy has an
  632. XmNnavigationType of XmEXCLUSIVE_TAB_GROUP, traversal of tab groups in the
  633. hierarchy proceeds to widgets in the order in which their XmNnavigationType
  634. resources were specified as XmEXCLUSIVE_TAB_GROUP or XmSTICKY_TAB_GROUP.
  635.  
  636. Earlier releases have a XmAddTabGroup(), but that is obsolete and has been
  637. replaced by XmNnavigationType.
  638.  
  639. Ken Lee
  640.  
  641. -----------------------------------------------------------------------------
  642. Subject: 200)  How can I determine which widget has keyboard focus?
  643. [Last modified: Sept 95]
  644.  
  645. Answer: In Motif 1.2 or later, use XmGetFocusWidget().
  646.  
  647. Ken Lee
  648.  
  649. --------------------------------------------------------------------------
  650. Subject: 201)  How can I direct the keyboard input to a particular widget?
  651.  
  652. Answer: In Motif 1.1 call XmProcessTraversal(target, XmTRAVERSE_CURRENT).  The
  653. widget (and all of its ancestors) does need to be realized BEFORE you call
  654. this. Otherwise it has no effect.  XmProcessTraversal is reported to have many
  655. bugs, so it may not work right.  A common occurrence is that it doesn't move
  656. to the widget, but if you call XmProcessTraversal *twice* in a row, it will.
  657. If you can't get it to work, try this from Kee Hinckley:
  658.  
  659. // This insane sequence is as follows:
  660. //      On manage set up a focus callback
  661. //      On focus callback set up a timer (and get rid of focus callback!)
  662. //      On timer set the focus (which only works if the parent
  663. //      has the focus,
  664. //      which is why we went through all of this garbage)
  665. // There may be a better way, but I haven't time to try it now.
  666. //
  667. static void focusTO(void *data, XtIntervalId *) {
  668. XmProcessTraversal((Widget) data, XmTRAVERSE_CURRENT);
  669. }
  670.  
  671. static void focusCB(Widget w, XtPointer data, XtPointer) {
  672. XtRemoveCallback(w, XmNfocusCallback, focusCB, data);
  673. XtAppAddTimeOut(XtWidgetToApplicationContext(w), 0, focusTO, data);
  674. }
  675.  
  676. void OmXSetFocus(Widget parent, Widget w) {
  677. XtAddCallback(parent, XmNfocusCallback, focusCB, w);
  678. }
  679.  
  680.  
  681. In Motif 1.0 call the undocumented _XmGrabTheFocus(target).
  682.  
  683. Do not use the X or Xt calls such as XtSetKeyboardFocus since this bypasses
  684. the Motif traversal layer and can cause it to get confused.  This can lead to
  685. odd keyboard behaviour elsewhere in your application.
  686.  
  687. -----------------------------------------------------------------------------
  688. Subject: 202)  How can I have a modal dialog which has to be answered before
  689. the application can continue?
  690. [Last modified: Sep 97]
  691.  
  692. Answer: Warning: the following answer relies on nested event loops.  Use these
  693. with caution, as nested loops can affect the ordering of events and widget
  694. destruction, leading to several undesirable side effects.
  695.  
  696. Ken Lee
  697.  
  698.  
  699. Note: J.-N. Meurisse (uunet!rc4.vub.ac.be!jnmeuris) sent a correction to the
  700. following code fragment. Change:
  701.  
  702. XtAddCallback(dialog, XmNpopdownCallback, ...)
  703. to
  704. XtAddCallback(XtParent(dialog), XmNpopdownCallback, ...)
  705.  
  706. The answer depends on whether you are using the Motif window manager mwm or
  707. not.  Test for this by XmIsMotifWMRunning.
  708.  
  709. The window manager mwm knows how to control event passing to dialog widgets
  710. declared as modal. If the dialog is set to application modal, then no
  711. interaction with the rest of the application can occur until the dialog is
  712. destroyed or unmanaged.
  713.  
  714. Use the appropriate code in the following program.  There is followup
  715. discussion after the program.
  716.  
  717.  
  718. /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
  719. * This program is freely distributable without licensing fees and
  720. * is provided without guarantee or warranty expressed or implied.
  721. * This program is -not- in the public domain.  This program is
  722. * taken from the Motif Programming Manual, O'Reilly Volume 6.
  723. */
  724.  
  725. /*
  726. * ask_user.c -- create a pushbutton that posts a dialog box
  727. * that asks the user a question that requires an immediate
  728. * response.  The function that asks the question actually
  729. * posts the dialog that displays the question, waits for and
  730. * returns the result.
  731. */
  732. #include <X11/Intrinsic.h>
  733. #include <Xm/DialogS.h>
  734. #include <Xm/SelectioB.h>
  735. #include <Xm/RowColumn.h>
  736. #include <Xm/MessageB.h>
  737. #include <Xm/PushBG.h>
  738. #include <Xm/PushB.h>
  739.  
  740. XtAppContext app;
  741.  
  742. #define YES 1
  743. #define NO  2
  744.  
  745. /* main() --create a pushbutton whose callback pops up a dialog box */
  746. main(argc, argv)
  747. char *argv[];
  748. int argc;
  749. {
  750. Widget parent, button, toplevel;
  751. XmString label;
  752. void pushed();
  753.  
  754. toplevel = XtAppInitialize(&app, "Demos",
  755. NULL, 0, &argc, argv, NULL, NULL, 0);
  756.  
  757. label = XmStringCreateLocalized("/bin/rm *");
  758. button = XtVaCreateManagedWidget("button",
  759. xmPushButtonWidgetClass, toplevel,
  760. XmNlabelString,          label,
  761. NULL);
  762. XtAddCallback(button, XmNactivateCallback,
  763. pushed, "Remove Everything?");
  764. XmStringFree(label);
  765.  
  766. XtRealizeWidget(toplevel);
  767. XtAppMainLoop(app);
  768. }
  769.  
  770. /* pushed() --the callback routine for the main app's pushbutton. */
  771. void
  772. pushed(w, question)
  773. Widget w;
  774. char *question;
  775. {
  776. if (AskUser(w, question) == YES)
  777. puts("Yes");
  778. else
  779. puts("No");
  780. }
  781.  
  782. /*
  783. * AskUser() -- a generalized routine that asks the user a question
  784. * and returns the response.
  785. */
  786. AskUser(parent, question)
  787. char *question;
  788. {
  789. static Widget dialog;
  790. XmString text, yes, no;
  791. static int answer;
  792. extern void response();
  793.  
  794. answer = 0;
  795. if (!dialog) {
  796. dialog = XmCreateQuestionDialog(parent, "dialog", NULL, 0);
  797. yes = XmStringCreateLocalized("Yes");
  798. no = XmStringCreateLocalized("No");
  799. XtVaSetValues(dialog,
  800.     XmNdialogStyle,        XmDIALOG_APPLICATION_MODAL,
  801.     XmNokLabelString,      yes,
  802.     XmNcancelLabelString,  no,
  803.     NULL);
  804. XtSetSensitive(
  805.     XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False);
  806. XtAddCallback(dialog, XmNokCallback, response, &answer);
  807. XtAddCallback(dialog, XmNcancelCallback, response, &answer);
  808. /* if the user interacts via the system menu: */
  809. /* SEE CORRECTION ABOVE */
  810. XtAddCallback(dialog, XmNpopdownCallback, response, &answer);
  811. }
  812. text = XmStringCreateLocalized(question);
  813. XtVaSetValues(dialog,
  814. XmNmessageString,      text,
  815. NULL);
  816. XmStringFree(text);
  817. XtManageChild(dialog);
  818. XtPopup(XtParent(dialog), XtGrabNone);
  819.  
  820. /* while the user hasn't provided an answer, simulate XtMainLoop.
  821. * The answer changes as soon as the user selects one of the
  822. * buttons and the callback routine changes its value.  Don't
  823. * break loop until XtPending() also returns False to assure
  824. * widget destruction.
  825. */
  826. while (answer == 0 || XtAppPending(app))
  827. XtAppProcessEvent(app, XtIMAll);
  828. return answer;
  829. }
  830.  
  831. /* response() --The user made some sort of response to the
  832. * question posed in AskUser().  Set the answer (client_data)
  833. * accordingly and destroy the dialog.
  834. */
  835. void
  836. response(w, answer, reason)
  837. Widget w;
  838. int *answer;
  839. XmAnyCallbackStruct *reason;
  840. {
  841. switch (reason->reason) {
  842. case XmCR_OK:
  843.     *answer = YES;
  844.     break;
  845. case XmCR_CANCEL:
  846.     *answer = NO;
  847.     break;
  848. default:
  849.     *answer = NO;
  850.     return;
  851. }
  852. }
  853.  
  854.  
  855. If you aren't running a window manager that acknowledges this hint, then you
  856. may have to grab the pointer (and keyboard) yourself to make sure the user
  857. doesn't interact with any other widget.  Change the grab flag in XtPopup to
  858. XtGrabExclusive, and XtRemoveGrab(XtParent(w)) to the response() function.
  859.  
  860. -----------------------------------------------------------------------------
  861. Subject: 203)  TOPIC: MEMORY AND SPEED
  862.  
  863. -----------------------------------------------------------------------------
  864. Subject: 204)  When can I free data structures passed to or retrieved from
  865. Motif?
  866.  
  867. Answer: In most cases, especially for XmStrings and XmFontLists, Motif copies
  868. data passed to it or retrieved from it, so it may be freed immediately.
  869. Server-side resources, such as pixmaps and color cells, however, are not
  870. copied, so should not be freed.  More recent versions of Motif are better than
  871. earlier versions and exceptions should be documented.
  872.  
  873. Ken Lee
  874.  
  875. -----------------------------------------------------------------------------
  876. Subject: 205)  What memory leaks are known? Why does my application grow in
  877. size?
  878. [Last modified: Jun 98]
  879.  
  880. Answer: Detailed information about Motif-related memory leaks (and how you can
  881. avoid them) can be found in two great articles by Kenton Lee:
  882.  
  883. http://www.rahul.net/kenton/txa/feb96.html
  884. http://www.rahul.net/kenton/txa/mar96.html
  885.  
  886. Answer: Motif 1.0 has many memory leaks, particularly in XmString
  887. manipulation.  Switch to Motif 1.1. 1.2, or 2.0.
  888.  
  889. Answer: In Motif 1.2.x, if one is using XmStringGetNextSegment very often
  890. (several 100 times) you'll get very big memory leaks, because one has to
  891. XtFree() also the charset variable and not only the variable holding the text
  892. value.  Thanks to Ingo Schulz (ing@bb-data.de).
  893.  
  894. Answer: The Intrinsics have a memory leak in accelerator table management, and
  895. Motif uses this heavily.  Avoid this by mapping/unmapping widgets rather than
  896. creating/destroying them, or get  X11R4 fix-15/16/17.
  897.  
  898. Answer: The server may grow in size due to its own memory leaks.  Switch to a
  899. later server.
  900.  
  901. Answer: You are responsible for garbage collection in `C'.  Some common cases
  902. where a piece of memory becomes garbage are
  903.  
  904.  a.  Memory is allocated by Motif for XmStrings by the functions
  905.      XmStringConcat, XmStringCopy, XmStringCreate, XmStringCreateLtoR,
  906.      XmStringCreateLocalized, XmStringDirectionCreate, XmStringNConcat,
  907.      XmStringNCopy, XmStringSegmentCreate, and XmStringSeparatorCreate.  The
  908.      values returned by these functions should be freed using XmStringFree
  909.      when they are no longer needed.
  910.  
  911.  b.  Memory is allocated by Motif for ordinary character strings (of type
  912.      String) by Motif in XmStringGetLtoR, XmStringGetNextComponent, and
  913.      XmStringGetNextSegment. After using the string, XtFree() it. [Note that
  914.      XmStrings and Strings are two different data types.  XmStrings are
  915.      XmStringFree'd, Strings are XtFree'd.]
  916.  
  917.  c.  If you have set the label (an XmString) in a label, pushbutton, etc
  918.      widget, free it after calling XtSetValues() or the widget creation
  919.      routine by XmStringFree().
  920.  
  921.  d.  If you have set text in a text widget, the text widget makes its own
  922.      copy.  Unless you have a use for it, there is no need to keep your own
  923.      copy.
  924.  
  925.  e.  If you have set the strings in a list widget the list widget makes its
  926.      own copy.  Unless you have a use for it, there is no need to keep your
  927.      own copy.
  928.  
  929.  f.  When you get the value of a single compound string from a Widget e.g.
  930.      XmNlabelString, XmNmessageString, ... Motif gives you a copy of its
  931.      internal value.  You should XmStringFree this when you have finished with
  932.      it.
  933.  
  934.  g.  On the other hand, when you get a value of a Table e.g. XmStringTable for
  935.      a List, you get a *pointer* to the internal Table, and should not free
  936.      it.
  937.  
  938.  h.  When you get the value of the text in a widget by XmTextGetString or from
  939.      the resource XmNvalue, you get a copy of the text.  You should XtFree
  940.      this when you have finished with it.
  941.  
  942. Answer: Josef Nelissen wrote: at least in Motif 1.1.4, X11R4 on a HP 720, the
  943. XmText/XmTextFieldSetString() functions have a memory leak.  The old
  944. value/contents of the Widget isn't freed correctly.  To work around this bug,
  945. one should use a XmText Widget (in single-line-mode) instead of a XmTextField
  946. Widget (the solution fails with XmTextField Widgets !) and replace any
  947.  
  948. XmTextSetString(text_widget, str);
  949.  
  950. by
  951.  
  952. XmTextReplace(text_widget, (XmTextPosition) 0,
  953.              XmTextGetLastPosition(text_widget), str);
  954.  
  955.  
  956. -----------------------------------------------------------------------------
  957. Subject: 206)  Why do I get so many uninitilized memory read (UMR) errors when
  958. I run Purify[tm] on my Motif programs?
  959. [Last modified: July 96]
  960.  
  961. Answer: Purify's reports are suggestions and do not always indicate real bugs.
  962. The X libraries frequently allocate dynamic memory, e.g., for attribute or
  963. event structures, but don't explicitly initialize all of the memory.  X keeps
  964. track of which structure fields are valid via a union type or a mask.  When X
  965. tries to copy or write the memory (part of which is uninitialized) as one
  966. block, Purify reports a UMR.  This is not a bug and you can safely supress or
  967. ignore the report.  Yes, X could initialize the unused field, but since this
  968. happens alot, the needless operation could negatively affect your performance.
  969.  
  970. Ken Lee
  971.  
  972. -----------------------------------------------------------------------------
  973. Subject: 207)  Why does my application take a long time to start up?
  974.  
  975. Answer: You are probably creating too many widgets at startup time.  Delay
  976. creating them until needed.  If you have a large number of resources in text
  977. files (such as in app-defaults), time may be spent reading and parsing it.
  978.  
  979. -----------------------------------------------------------------------------
  980. Subject: 208)  My application is running too slowly. How can I speed it up?
  981.  
  982. Answer: Use the R4 rather than R3 server.  It is much faster.
  983.  
  984. Answer: The standard memory allocator is not well tuned to Motif, and can
  985. degrade performance.  Use a better allocator.  e.g. with SCO Unix, link with
  986. libmalloc.a; use the allocator from GNU emacs; use the allocator from Perl.
  987.  
  988. Answer: Avoid lots of widget creation and destruction.  It fragments memory
  989. and slows everything down.  Popup/popdown, manage/unmanage instead.
  990.  
  991. Answer: Set mappedWhenManaged to FALSE, and then call XtMapWidget()
  992. XtUnmapWidget() rather than managing.
  993.  
  994. Answer: Get more memory - your application, the server and the Operating
  995. System may be spending a lot of time being swapped.
  996.  
  997. Answer: If you are doing much XmString work yourself, such as heavy use of
  998. XmStringCompare, speed may deteriorate due to the large amount of internal
  999. conversions and malloc'ing.  Try using XmStringByteCompare if appropriate or
  1000. ordinary Ascii strings if you can.
  1001.  
  1002. Answer: There are some more hints at http://www.rahul.net/kenton/perf.html
  1003.  
  1004. -----------------------------------------------------------------------------
  1005. Subject: 209)  Why is my application so huge?
  1006.  
  1007. Answer: The typical size of a statically linked Motif app is in the megabytes.
  1008. This is often caused by the size of libXm.a. A large part of this gets linked
  1009. in to even trivial Motif programs. You can reduce the code size by linking
  1010. against shared libraries if they are available.  Running "strip" on the
  1011. executable can often reduce size. Note that the size of the running program
  1012. should be measured by "ps", not by the code size.
  1013.  
  1014. -----------------------------------------------------------------------------
  1015. Subject: 210)  How can I improve performance when creating and deleting
  1016. hundreds of text widgets?
  1017. [Last modified: Feb 98]
  1018.  
  1019. Answer: Ken Lee writes: This is mostly a problem with Motif 1.2.0 through
  1020. 1.2.2.  Later versions are much better.  If you're stuck with an early version
  1021. of Motif 1.2, you may be able to greatly improve performance by batching the
  1022. drop site updates: surround the create or delete code with
  1023. XmDropSiteStartUpdate and XmDropSiteEndUpdate.  Alternatively, you can
  1024. completely disable drag-and-drop for your application. See the subject: "How
  1025. can I disable Drag and Drop in my Motif 1.2 client?"
  1026.  
  1027. Mike Youell adds: Using XmDropSiteStartUpdate sped up destruction of widgets
  1028. in Motif 1.2.5.  Also it may be worthwhile reminding people that it is not as
  1029. simple as "surround the create or delete code with XmDropSiteStartUpdate and
  1030. XmDropSiteEndUpdate" because it doesn't destroy the widgets when you do a
  1031. XtDestroy.  X does it at a later time, hence you still need to be inside the
  1032. drop-site update when these destroys are completed by X.
  1033.  
  1034.  
  1035. -----------------------------------------------------------------------------
  1036. Subject: 211)  After I call XtSetValues, when will I see the changes in my
  1037. GUI?
  1038. [Last modified: Nov 97]
  1039.  
  1040. Answer: For each change you make, the widget decides if it needs to redraw.
  1041. If so, Xt calls XtClearArea to generate an expose event.  You main loop
  1042. dispatches the resulting expose event to your widget, causing a redisplay.
  1043. Note that the redisplay may be delayed somewhat if you do not immediately
  1044. return to the event loop after calling XtSetValues.  You can often work around
  1045. this by calling XmUpdateDisplay().
  1046.  
  1047. Note also that you should try to make all your changes in one large
  1048. XtSetValues changing several values at once.  If you call XtSetValues
  1049. individually for each change you need to make, you could generate several
  1050. expose events and redraw several times.
  1051.  
  1052. -----------------------------------------------------------------------------
  1053. Subject: 212)  TOPIC: XMSTRING
  1054.  
  1055. -----------------------------------------------------------------------------
  1056. Subject: 213)  What string functions differ in Motif 1.1 and 1.2? Is
  1057. XmStringCreateSimple obsolete? What should I use instead?
  1058. [Last modified: Feb 95]
  1059.  
  1060. Answer: XmStringCreateSimple is obsolete. Use XmStringCreateLocalized instead.
  1061.  
  1062. Matthew B. Evans (Evans@EDFUA6.ctis.af.mil) writes:
  1063.  
  1064. We just upgraded from Motif 1.1 to 1.2.  When we went to compile, no problem,
  1065. but our XmStringCreateSimple() and XmStringGetLtoR() seemed to have problems.
  1066.  
  1067. As we found out, Motif 1.2 STRONGLY recommends to use the constant
  1068. XmFONTLIST_DEFAULT_TAG instead of XmSTRING_DEFAULT_CHARSET in all of the
  1069. XmStringXXX() functions, as XmSTRING_DEFAULT_CHARSET is maintained only for
  1070. compatibility (not a whole lot in my opinion).  I got this information from
  1071. Book 6B from O'Reilly.
  1072.  
  1073. You may want to take a look at this book if you can. Some XmString functions
  1074. are outdated and maintained only for compatibility, whereas some don't
  1075. function correctly when using XmSTRING_DEFAULT_CHARSET (from our in-depth
  1076. tests).
  1077.  
  1078. We have changed all our XmStringCreateSimple() to XmStringCreateLocalized()
  1079. (as suggested in book 6B) and changed all XmSTRING_DEFAULT_CHARSET to
  1080. XmFONTLIST_DEFAULT_TAG.
  1081.  
  1082. [Thanks to John West (jwest@nas.nasa.gov) for fixing a typo in the above.]
  1083.  
  1084. NOTE: All string answers in this FAQ now use XmStringCreateLocalized rather
  1085. than XmStringCreateSimple. The documentaton makes it clear that
  1086. XmStringCreateSimple is obsolete and is only kept for compatibility with Motif
  1087. 1.1. New applications should not use this function since XmStringCreateSimple
  1088. may disappear in a subsequent Motif release. (Thanks to Miguel Angel Chamochin
  1089. (mangel@tid.es) for reminding me to fix this mess.)....ksall@cen.com.
  1090.  
  1091. -----------------------------------------------------------------------------
  1092. Subject: 214)*  How can I get the ASCII text out of an XmString?
  1093. [Last modified: Feb 02]
  1094.  
  1095. Answer: In Motif 1.x, use XmStringGetLtoR:
  1096.  
  1097.     char *str;
  1098.     XmString xmstr;
  1099.     XmStringGetLtoR(xmstr, XmSTRING_DEFAULT_CHARSET, &str);
  1100.  
  1101.  
  1102. In Motif 2.x, use XmStringUnparse:
  1103.  
  1104.     str = XmStringUnparse(xmstr, NULL, 0, XmCHARSET_TEXT, NULL, 0, NULL);
  1105.  
  1106.  
  1107. In both cases, you should free the string to avoid a memory leak:
  1108.  
  1109.     XtFree(str);
  1110.  
  1111.  
  1112. -----------------------------------------------------------------------------
  1113. Subject: 215)  When can XmStrings used as resources be freed?
  1114.  
  1115. Answer: The policy OSF have been trying to enforce is that if you set an
  1116. XmString or XmStringTable resource, the application is responsible for freeing
  1117. the XmStrings used because the widget makes a copy.  If you get an XmString
  1118. resource, then the application must free the value gotten.  If you get an
  1119. XmStringTable, then the application should NOT free the value gotten.  If the
  1120. application wants to manipulate it, it should make a copy first. This policy
  1121. appears to be implemented progressively, so may be less true for Motif 1.0
  1122. than 1.1.
  1123.  
  1124. -----------------------------------------------------------------------------
  1125. Subject: 216)  Why doesn't XmStringGetNextSegment() work properly?
  1126.  
  1127. Answer: The documentation in Motif 1.0 is in error. Instead of
  1128.  
  1129. XmStringGetnextSegment(context, ...)
  1130. XmStringContext * context;
  1131.  
  1132. it should be
  1133.  
  1134. XmStringGetnextSegment(context, ...)
  1135. XmStringContext context;
  1136.  
  1137. i.e. with no indirection.
  1138.  
  1139.  
  1140. -----------------------------------------------------------------------------
  1141. Subject: 217)  Why does using XmStringDraw cause a BadFont error?
  1142. [Last modified: Mar 96]
  1143.  
  1144. Answer: Thomas Berlage (berlage@gmdzi.gmd.de) wrote: You could call this a bug
  1145. in Motif. You pass a GC to XmStringDraw, however, Motif wants to use the fonts
  1146. from the font list to draw the string.  Therefore it replaces the font of the
  1147. GC temporarily with some fonts of its own as specified in the font list. In
  1148. the end it tries to restore the old font of the GC. There comes the problem:
  1149.  
  1150. If a GC uses the default font, the client side GC structure does not have a
  1151. valid font id (that is the 0xffffffff you may see in the error message). Motif
  1152. tries to restore this invalid id at the end.
  1153.  
  1154. The workaround is: Before drawing with XmStringDraw, set the font id of the GC
  1155. to any valid font id, for example using
  1156.  
  1157. XSetFont (display, gc, XLoadFont (display, "fixed"));
  1158.  
  1159. Another solution is available from "Harry's Motif Programming Corner", Harald
  1160. Albrecht, albrecht@igpm.rwth-aachen.de, who writes:
  1161.  
  1162. "It's somewhat longer but doesn't rely on a font named "fixed" installed on
  1163. your platform. Instead it takes a fontlist and then uses the first font listed
  1164. there. You'll find this source together with a short demo program (which
  1165. creates a DrawingArea and then paints some text in it) on: ftp.igpm.rwth-
  1166. aachen.de (134.130.161.30) in: /arc/pub/unix/motif/RenderXmString.tar.gz
  1167.  
  1168. There's also a html page available: Harry's Motif Programming Corner
  1169. http://www.igpm.rwth-aachen.de/~albrecht/motifcorner.html
  1170.  
  1171. Thanks to Harald Albrecht (albrecht@igpm.rwth-aachen.de).  URL corrected by
  1172. irca (irca@zip.cra.enel.it).
  1173.  
  1174. -----------------------------------------------------------------------------
  1175. Subject: 218)  How can I control color of individual strings to show status,
  1176. etc.?
  1177. [Last modified: June 95]
  1178.  
  1179. Answer: This is difficult to do with Motif 1.X.  If you can, upgrade to Motif
  1180. 2.0, which supports colored XmStrings.
  1181.  
  1182. Ken Lee
  1183.  
  1184. -----------------------------------------------------------------------------
  1185. Subject: 219)  TOPIC: DIALOGS
  1186.  
  1187. -----------------------------------------------------------------------------
  1188. Subject: 220)  How do I stop my dialog disappearing when I press the help
  1189. button?
  1190.  
  1191. Answer: Bulletin board has the resource autoUnmanage which defaults to True.
  1192. This unmanages the widget when any button child is activated - including the
  1193. help button.  Set this to False to stop it disappearing. Note that you then
  1194. have to unmanage the bulletin board yourself when any other button is
  1195. activated.
  1196.  
  1197. -----------------------------------------------------------------------------
  1198. Subject: 221)  How do I make my own dialog?  I want a dialog with my own set
  1199. of buttons that stretch and shrink like the ones in e.g. PromptDialog and its
  1200. own contents.
  1201.  
  1202. Answer: Start off with say a PromptDialog. Unmanage the buttons you don't want
  1203. or manage the Apply button if you want another. Unmanage the other bits of the
  1204. selection box you don't want. You can add another WorkArea child to the
  1205. selection box for any extra stuff you want.
  1206.  
  1207.  
  1208. /* Copyright 1990, Kee Hinckley and Brian Holt Hawthorne */
  1209. /* Permission granted for any use, provided this copyright */
  1210. /* notice is maintained. */
  1211.  
  1212. /* Create a dialog box */
  1213. argcount = setArgs(&args, XmNautoUnmanage, False, NULL);
  1214. SomeDialog = XmCreatePromptDialog(mainShell, "someDialog", args, argcount);
  1215.  
  1216. /* Now get rid of the things we don't want */
  1217. child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_SELECTION_LABEL);
  1218. XtUnmanageChild(child);
  1219. child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_TEXT);
  1220. XtUnmanageChild(child);
  1221.  
  1222. /* set the callbacks, and make sure the buttons we want are there */
  1223. child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_OK_BUTTON);
  1224. XtAddCallback(child, XmNactivateCallback, callSomeFunc, someArg);
  1225. XtAddCallback(child, XmNactivateCallback, unManage, SomeDialog);
  1226. XtManageChild(child);
  1227. child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_APPLY_BUTTON);
  1228. XtAddCallback(child, XmNactivateCallback, callSomeFunc, someOtherArg);
  1229. XtManageChild(child);
  1230. child = XmSelectionBoxGetChild(SomeDialog, XmDIALOG_CANCEL_BUTTON);
  1231. XtAddCallback(child, XmNactivateCallback, dialogUnmanage, SomeDialog);
  1232. XtManageChild(child);
  1233.  
  1234. /* Add a new work area. This can be any manager. */
  1235. child = XmCreateForm(SomeDialog, "someForm", NULL, 0);
  1236. XtManageChild(child);
  1237.  
  1238. /* and fill it up... */
  1239. something = doYourStuff(child);
  1240.  
  1241. another Answer:
  1242.  
  1243. I had a some people asking about my xmSmartMessageBoxWidget
  1244.  
  1245. It's public domain, and needs Motif-1.2  and is available at
  1246. ftp.x.org:/contrib/widget/SmartMB.tar.Z.
  1247.  
  1248. The basic idea behind it is that it allows the programmer to specify the
  1249. management of child widgets in 4 areas: Label, Control, Separator and Action.
  1250. You can have up to 1 Label, 1 Control, 1 Separator and as many Action children
  1251. as you want.  It does not REQUIRE any of these, and there is no unmanaging of
  1252. extra widgets, as the programmer creates what is needed.
  1253.  
  1254. Thanks for the smart dialog info to: John L. Cwikla Wolfram Research, Inc.
  1255. cwikla@wri.com
  1256.  
  1257. -----------------------------------------------------------------------------
  1258. Subject: 222)  Why do dialog title bars have "_popup" or "<-popup"
  1259. concatenated onto the widget name?
  1260.  
  1261.  
  1262. Answer: Motif 1.0.3 (?) "fixed" things such that title bars without an
  1263. explicit dialogTitle setting use the widget name with "_popup" or whatever
  1264. added on.  Set the dialogTitle resource explicitly if you don't want this new
  1265. default naming scheme.
  1266.  
  1267. -----------------------------------------------------------------------------
  1268. Subject: 223)  How can I force a dialog window to display?
  1269.  
  1270. I manage a "working" dialog, and do some computing, but the dialog window
  1271. appears blank until the work has finished.  How can I force it to be
  1272. displayed?
  1273. [Last modified: Dec '94]
  1274.  
  1275. Answer: David Brooks <dbrooks@ics.com> writes: The dialog window won't get
  1276. expose events until the window manager has fielded the map request, done the
  1277. reparenting with all that entails, and finally convinced the server that the
  1278. window is for real.  The safe way of doing it is [below].
  1279.  
  1280. Use this.  (David Brooks, Systems Engineering, Open Software Foundation)
  1281.  
  1282. /*
  1283. * This procedure will ensure that, if a dialog window is being mapped,
  1284. * its contents become visible before returning.  It is intended to be
  1285. * used just before a bout of computing that doesn't service the display.
  1286. * You should still call XmUpdateDisplay() at intervals during this
  1287. * computing if possible.
  1288. *
  1289. * The monitoring of window states is necessary because attempts to map
  1290. * the dialog are redirected to the window manager (if there is one) and
  1291. * this introduces a significant delay before the window is actually mapped
  1292. * and exposed.  This code works under mwm, twm, uwm, and no-wm.  It
  1293. * doesn't work (but doesn't hang) with olwm if the mainwindow is iconified.
  1294. *
  1295. * The argument to ForceDialog is any widget in the dialog (often it
  1296. * will be the BulletinBoard child of a DialogShell).
  1297. */
  1298.  
  1299. ForceDialog(w)
  1300. Widget w;
  1301. {
  1302. Widget diashell, topshell;
  1303. Window diawindow, topwindow;
  1304. Display *dpy;
  1305. XWindowAttributes xwa;
  1306. XEvent event;
  1307. XtAppContext cxt;
  1308.  
  1309. /* Locate the shell we are interested in.  In a particular instance, you
  1310. * may know these shells already.
  1311. */
  1312.  
  1313. for (diashell = w;
  1314. !XtIsShell(diashell);
  1315. diashell = XtParent(diashell))
  1316. ;
  1317.  
  1318. /* Locate its primary window's shell (which may be the same) */
  1319.  
  1320. for (topshell = diashell;
  1321. !XtIsTopLevelShell(topshell);
  1322. topshell = XtParent(topshell))
  1323. ;
  1324.  
  1325. if (XtIsRealized(diashell) && XtIsRealized(topshell)) {
  1326. dpy = XtDisplay(topshell);
  1327. diawindow = XtWindow(diashell);
  1328. topwindow = XtWindow(topshell);
  1329. cxt = XtWidgetToApplicationContext(diashell);
  1330.  
  1331. /* Wait for the dialog to be mapped.  It's guaranteed to become so unless... */
  1332.  
  1333. while (XGetWindowAttributes(dpy, diawindow, &xwa),
  1334.    xwa.map_state != IsViewable) {
  1335.  
  1336. /* ...if the primary is (or becomes) unviewable or unmapped, it's
  1337. probably iconified, and nothing will happen. */
  1338.  
  1339. if (XGetWindowAttributes(dpy, topwindow, &xwa),
  1340.   xwa.map_state != IsViewable)
  1341. break;
  1342.  
  1343. /* At this stage, we are guaranteed there will be an event of some kind.
  1344. Beware; we are presumably in a callback, so this can recurse. */
  1345.  
  1346. XtAppNextEvent(cxt, &event);
  1347. XtDispatchEvent(&event);
  1348. }
  1349. }
  1350.  
  1351. /* The next XSync() will get an expose event if the dialog was unmapped. */
  1352.  
  1353. XmUpdateDisplay(topshell);
  1354. }
  1355.  
  1356.  
  1357. -----------------------------------------------------------------------------
  1358. Subject: 224)  How can I control placement of a popup widget?  Each time a
  1359. popup is created, it is placed in or over the middle of its parent.  How can I
  1360. make it obey the XmNx and XmNy values?
  1361. [Last modified: Feb 95]
  1362.  
  1363. Answer: Set the resource XmNdefaultPosition for the popup to False.  Set the
  1364. position of the popup by the resource values of XmNx and XmNy.  Do not use
  1365. XtMoveWidget, as this is for widget writers only.  Here's a demo program from
  1366. Dan Heller:
  1367.  
  1368. /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
  1369. * This program is freely distributable without licensing fees and
  1370. * is provided without guarantee or warranty expressed or implied.
  1371. * This program is -not- in the public domain.  This program is
  1372. * taken from the Motif Programming Manual, O'Reilly Volume 6.
  1373. */
  1374.  
  1375. /* map_dlg.c -- Use the XmNmapCallback to automatically position
  1376. * a dialog on the screen.  Each time the dialog is displayed, it
  1377. * is mapped down and to the right by 200 pixels in each direction.
  1378. */
  1379. #include <Xm/MessageB.h>
  1380. #include <Xm/PushB.h>
  1381.  
  1382. /* main() --create a pushbutton whose callback pops up a dialog box */
  1383. main(argc, argv)
  1384. char *argv[];
  1385. {
  1386. Widget toplevel, button;
  1387. XtAppContext app;
  1388. void pushed();
  1389.  
  1390. toplevel = XtVaAppInitialize(&app, "Demos",
  1391. NULL, 0, &argc, argv, NULL, NULL);
  1392.  
  1393. button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
  1394. toplevel, NULL, 0);
  1395. XtAddCallback(button, XmNactivateCallback, pushed, "Hello World");
  1396.  
  1397. XtRealizeWidget(toplevel);
  1398. XtAppMainLoop(app);
  1399. }
  1400.  
  1401. /* callback function for XmNmapCallback.  Position dialog in 200 pixel
  1402. * "steps".  When the edge of the screen is hit, start over.
  1403. */
  1404. static void
  1405. map_dialog(dialog, client_data, cbs)
  1406. Widget dialog;
  1407. XtPointer client_data;
  1408. XmAnyCallbackStruct *cbs;
  1409. {
  1410. static Position x, y;
  1411. Dimension w, h;
  1412.  
  1413. XtVaGetValues(dialog, XmNwidth, &w, XmNheight, &h, NULL);
  1414. if ((x + w) >= WidthOfScreen(XtScreen(dialog)))
  1415. x = 0;
  1416. if ((y + h) >= HeightOfScreen(XtScreen(dialog)))
  1417. y = 0;
  1418. XtVaSetValues(dialog, XmNx, x, XmNy, y, NULL);
  1419. x += 200, y += 200;
  1420. }
  1421.  
  1422. /* pushed() --the callback routine for the main app's pushbutton.
  1423. * Create and popup a dialog box that has callback functions for
  1424. * the Ok, Cancel and Help buttons.
  1425. */
  1426. void
  1427. pushed(w, message)
  1428. Widget w;
  1429. char *message; /* The client_data parameter passed by XtAddCallback */
  1430. {
  1431. Widget dialog;
  1432. Arg arg[3];
  1433. XmString t = XmStringCreateLocalized(message);
  1434. extern void response();
  1435.  
  1436. XtSetArg(arg[0], XmNautoUnmanage, False);
  1437. XtSetArg(arg[1], XmNmessageString, t);
  1438. XtSetArg(arg[2], XmNdefaultPosition, False);
  1439. dialog = XmCreateMessageDialog(w, "notice", arg, 3);
  1440. XmStringFree(t);
  1441.  
  1442. XtAddCallback(dialog, XmNmapCallback, map_dialog, NULL);
  1443.  
  1444. XtManageChild(dialog);
  1445. XtPopup(XtParent(dialog), XtGrabNone);
  1446. }
  1447.  
  1448.  
  1449. -----------------------------------------------------------------------------
  1450. Subject: 225)  How can I set the dialog's default button?
  1451. [Last modified: June 95]
  1452.  
  1453. Answer: Use XmNdefaultButton on the bulletin board widget.
  1454.  
  1455. Ken Lee
  1456.  
  1457. -----------------------------------------------------------------------------
  1458. Subject: 226)  How can I create a dialog that behaves like, but looks a little
  1459. different from, XmMessageBox?
  1460. [Last modified: June 95]
  1461.  
  1462. Answer: Motif 1.2 provides a XmCreateTemplateDialog(), which allows you to
  1463. specify any combination of child widgets.
  1464.  
  1465. Ken Lee
  1466.  
  1467. -----------------------------------------------------------------------------
  1468. Subject: 227)  How can I use Motif's message dialog bitmaps in my own dialogs?
  1469. [Last modified: Nov 95]
  1470.  
  1471. Answer: The bitmaps are normally stored in /usr/include/X11/bitmaps (or the
  1472. equivalent bitmaps directory, which is vendor specific) and are cached if you
  1473. create a XmMessageBox.  You can retrieve them by name with XmGetPixmap() or
  1474. XmGetPixmapByDepth().  The names of the bitmap files are in the XmMessageBox
  1475. man page.
  1476.  
  1477. Ken Lee
  1478.  
  1479. -----------------------------------------------------------------------------
  1480. END OF PART SIX
  1481.