home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1997 December / Internet_Info_CD-ROM_Walnut_Creek_December_1997.iso / faqs / comp / answers / motif-faq / part6 < prev    next >
Encoding:
Internet Message Format  |  1997-10-19  |  55.1 KB

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