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

  1. Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
  2. Message-ID: <motif-faq/part5_1083675484@rtfm.mit.edu>
  3. Supersedes: <motif-faq/part5_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 5 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:11 GMT
  18. Lines: 1465
  19. NNTP-Posting-Host: penguin-lust.mit.edu
  20. X-Trace: 1083675551 senator-bedfellow.mit.edu 562 18.181.0.29
  21. Xref: senator-bedfellow.mit.edu comp.windows.x.motif:75188 comp.answers:57053 news.answers:270857
  22.  
  23. Archive-name: motif-faq/part5
  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: 108)  TOPIC: LIST WIDGET
  32.  
  33. -----------------------------------------------------------------------------
  34. Subject: 109)  Should I create an XmList widget as a child of automatic
  35. XmScrolledWindow or use the XmCreateScrolledList() convenience function?
  36.  
  37. Answer: With most implementations, the convenience function use internal hooks
  38. to give somewhat better scrolling performance.
  39.  
  40. Ken Lee, http://www.rahul.net/kenton/
  41.  
  42. -----------------------------------------------------------------------------
  43. Subject: 110)  How do I best put a new set of items into a list?
  44.  
  45. Answer: Set the new list count and list by XtSetArgs and install them by
  46. XtSetValues.
  47.  
  48. XmString list[SIZE];
  49. int list_size;
  50.  
  51. XtSetArg (args[n], XmNitemCount, list_size); n++;
  52. XtSetArg (args[n], XmNitems, list); n++;
  53. XtSetValues (w, args, n);
  54.  
  55.  
  56. or similarly with XtVaSetValues:
  57.  
  58.  
  59. XtVaSetValues (w,
  60.     XmNitemCount, list_size,
  61.     XmNitems, list,
  62.     NULL);
  63.  
  64.  
  65. Each time the list is reset by this the old contents are freed by the widget
  66. and the new supplied list is copied.  Do *not* free the old list of items
  67. yourself as this would result in the space being freed twice.  It is not
  68. necessary to remove the items one at a time, nor to "zero" out the list first.
  69.  
  70. -----------------------------------------------------------------------------
  71. Subject: 111)  Can I have strings with different fonts in a list?
  72. [Last modified: Sept 95]
  73.  
  74. Answer: Yes. The strings are XmStrings. Each one can be created using a
  75. different character set using a different font.
  76.  
  77. However, arjav@caip.rutgers.edu (ARJAV PARIKH) wrote:
  78.  
  79. If a string is added to the listbox, the font in the listbox overrides the
  80. font set using XmCreateString.  The Command widget label retains the font set
  81. using XmCreateString.  I read in the MOTIF FAQ that it is possible to add
  82. strings with multiple fonts to the listbox.  I learned from one of the tech
  83. support persons that internal code of the listbox overrides the font.
  84.  
  85. Madhusudan Poolu (madhu@corp.sgi.com) replied:
  86.  
  87. You need to create a fontlist for your font and  add it to your listbox widget
  88. using XtVaSetValues ( wList, XmNfontList, yourFontList, NULL).  This technique
  89. can also be used to display multi-font strings in a list box.
  90.  
  91. -----------------------------------------------------------------------------
  92. Subject: 112)  Can I get a bitmap to show in a list item like I can in a
  93. Label?  I want to place a bitmap along with some normal text in my list items.
  94. [Last modified: Jun 2000]
  95.  
  96. Answer: Andrew Lister (lister@bain.oz.au) writes: The XbaeMatrix widget allows
  97. a bitmaps in a cell.  There will be support for colour pixmaps to be displayed
  98. in version 4.4 which should be available very soon. (The XbaeMatrix can be
  99. made to look and behave like a list widget.  The widget is compatible with
  100. Motif 1.2 and Motif 2.0.)
  101.  
  102. Beginning with version 4.7, XbaeMatrix is being maintained by the Lesstif
  103. project.  The current version is version 4.8.  Source code and a FAQ are
  104. available from:
  105.  
  106. http://www.lesstif.org/Xbae.html
  107. http://www.lesstif.org/Lessdox/XbaeFAQ.html
  108.  
  109.  
  110. Alan Peery (peery@isc.tamu.edu) writes: Motif 2.0 introduced the "container"
  111. widget, which offers 2-D icon and text layout similar to that found in many
  112. file management programs.  It could probably be used as a 1-D list widget
  113. also.
  114.  
  115. A previous source wrote: In Motif 1.x, you cannot do this.  The list contains
  116. XmStrings, and these only allow text in various character sets. The workaround
  117. is to define your font containing the icons you want. Then you can create a
  118. fontlist containing your icon font and the font you want the text in, and then
  119. make your items multi-segment XmStrings where the first segment contains the
  120. code of the icon you want with a charset that matches the icon font in your
  121. fontlist and the second segment with a charset matching the text font.
  122.  
  123.  
  124. -----------------------------------------------------------------------------
  125. Subject: 113)  Can I have items with different colors in a list widget?
  126. [Last modified: Jun 2000]
  127.  
  128. Answer: Andrew Lister (lister@bain.oz.au) writes: The XbaeMatrix widget can
  129. have a different foreground and background in each cell, row or column.  (The
  130. XbaeMatrix can be made to look and behave like a list widget.  The widget is
  131. compatible with Motif 1.2 and Motif 2.0.) You can get the latest version of
  132. XbaeMatrix from:
  133. http://www.lesstif.org/Xbae.html
  134.  
  135. Ken Lee wrote: Not in Motif 1.x.  The list contains XmStrings, and these only
  136. allow text in various character sets.
  137.  
  138. However, in Motif 2.0 you _can_ have multiple colors in the same list since
  139. colored XmStrings are supported.
  140.  
  141. Thanks to Ken Lee, http://www.rahul.net/kenton/, for the update.
  142.  
  143. If you're using Motif 1.2, another possibility is to use SCO Premier Motif
  144. (1.2) library has this extension built into the List widget, along with a few
  145. others. See http://www.premier.sco.com/
  146.  
  147. Thanks to Richard Offer (offer@sgi.com)
  148.  
  149. -----------------------------------------------------------------------------
  150. Subject: 114)  How can I line up columns in a list widget?
  151. [Last modified: Jun 2000]
  152.  
  153. Answer: The simplest answer is to use fixed-width fonts and spaces to line up
  154. columns.  There are also some more general solutions follow.
  155.  
  156. David Kaelbling <drk@sgi.com> writes:
  157.  
  158. Motif 2.x supports tab components in XmStrings.  Insert XmSTRING_COMPONENT_TAB
  159. segments into your XmStrings, either with XmStringComponentCreate() and
  160. XmStringConcatAndFree(), or with the XmStringParseText() api).  Then use
  161. XmStringTableProposeTabList() to get a default set of non-overlapping tabs.
  162. Put that XmNtabList into a rendition in the list's render table.
  163.  
  164. Andrew Lister (lister@bain.oz.au) writes:
  165.  
  166. The XbaeMatrix can do this too, for both fixed and non fixed width fonts.
  167. (The XbaeMatrix can be made to look and behave like a list widget.  The widget
  168. is compatible with Motif 1.2 and Motif 2.0.) You can get the latest version of
  169. XbaeMatrix from: http://www.lesstif.org/Xbae.html
  170.  
  171. Ken Lee writes:
  172.  
  173. Other Motif-compatible and matrix grid and matrix widgets are available.  See
  174. the widgets FAQ for pointers.
  175.  
  176. -----------------------------------------------------------------------------
  177. Subject: 115)  Can I grey out an item in a list widget?  I want to make
  178. insensitive items in a list so that they cannot be selected.
  179. [Last modified: Feb 98]
  180.  
  181. Answer: W. Scott Meeks of OSF wrote:
  182.  
  183. Unfortunately, you can't do it directly since the list items aren't individual
  184. widgets.  We've had other requests for this technology, but it didn't make the
  185. cut for 1.2; it should be in some future release.
  186.  
  187. However, you can probably fake it in your application with some difficulty.
  188. First, a list item is an XmString, so you can specify a different charset for
  189. the item than for other items in the list and then specify a font in the
  190. list's fontlist that matches the charset and gives you the visual you want.
  191. The next problem is making the item unselectable.  One idea would be to have
  192. the application keep track of the insensitive items and the items currently
  193. selected.  Then you would set up a selection callback that when called would
  194. check the item selected against the list of insensitive items and if the
  195. selected item matched would deselect that item and reselect the previously
  196. selected items.  Otherwise it would just update the application's list of
  197. selected items.  The major drawback with this approach is that you'll get
  198. flashing whenever the list selects an item and your application immediately
  199. de-selects.  Unfortunately I can't think of a way around this without mucking
  200. with the list internals.
  201.  
  202. Another alternative suggested is to use instead a column of say read only text
  203. widgets which you can make insensitive.
  204.  
  205. Ken Lee adds:  Motif 2.0 allows you to create multi-color XmStrings.  You can
  206. use this feature to grey out specific list items.
  207.  
  208. -----------------------------------------------------------------------------
  209. Subject: 116)  Can I have multi-line items in a list?
  210. [Last modified: August 92]
  211.  
  212. Answer: Motif 1.0 and 1.1 both have problems with multi-line items in a list.
  213. They should work okay in Motif 1.2.
  214.  
  215. -----------------------------------------------------------------------------
  216. Subject: 117)  How can I tell the position of selected items in a list?
  217. [Last modified: Oct 92]
  218.  
  219. Answer: W. Scott Meeks wrote:
  220.  
  221. 1) All XmList selection callbacks get an XmListCallbackStruct which includes
  222. the item selected and its position.  In addition, the multiple and extended
  223. selection callbacks also get a list of the selected items.  This approach
  224. requires that your application saves this information if you need it outside
  225. of the immediate callback.
  226.  
  227. 2) At any time you can XtGetValues the XmNselectedItems and
  228. XmNselectedItemCount resources.  The problem with this approach is that
  229. identical items may or may not show up in multiple times in this list and the
  230. position in the selectedItems list may not relate directly to the position in
  231. the items list.
  232.  
  233. 3) You can call XmListGetSelectedPos on the list widget.  This will return a
  234. list of the positions of all selected items.
  235.  
  236. -----------------------------------------------------------------------------
  237. Subject: 118)  How can I configure a scrolled list widget to show a horizontal
  238. scrollbar when some list items are wider than the window?
  239. [Last modified: May 97]
  240.  
  241. Answer: Set *XmList.listSizePolicy: XmCONSTANT
  242.  
  243. Ken Lee
  244.  
  245. -----------------------------------------------------------------------------
  246. Subject: 119)  How can I programatically select all of the items in an XmList?
  247. [Last modified: May 98]
  248.  
  249. Answer: Invoke the same action that "C-/" uses for selecting everything.  Try
  250. something like:
  251.  
  252. XtCallActionProc(list, "ListKbdSelectAll", event, NULL, 0);
  253.  
  254. If you don't have an event handy passing NULL for it will probably work too.
  255. The lack of an XmListSelectAllItems() api was just an oversight.
  256.  
  257. David KAELBLING <drk@sgi.com>
  258.  
  259. -----------------------------------------------------------------------------
  260. Subject: 120)  TOPIC: FILE SELECTION BOX WIDGET
  261.  
  262. -----------------------------------------------------------------------------
  263. Subject: 121)  What is libPW.a and do I need it?  My manual says I need to
  264. link in libPW.a to use the File Selection Box.  I can't find it on my system.
  265. [Last modified: Sept 94]
  266.  
  267. Answer: The libPW.a is the Programmers Workbench library which is an ATT
  268. product not included in Berkeley based systems, hence it is not found in SunOS
  269. or Ultrix, but is found on HP-UX (a Berkeley/ATT hybrid which chose ATT in
  270. this case).  It contains the regex(3) routines (regcmp, regex).  Some systems
  271. which don't have these in the libc.a need to link with -lPW.  Some systems
  272. which have the regex(3) routines in there also have the libPW.a.  If you have
  273. regex(3) in libc, and it works, don't link with libPW.  If you don't have
  274. regex(3) in libc, and you don't have a libPW, then check some sites on the net
  275. for public domain replacements (several exist), or call your vendor.
  276.  
  277. In most versions of Motif (see the doco), you can compile FileSB.c with
  278. -DNO_REGEX if you don't have it.
  279.  
  280.  
  281. Casper H.S. Dik (asper@fwi.uva.nl), Faculty of Mathematics & Computer Science,
  282. University of Amsterdam, sent this update for Solaris 2.x users:
  283.  
  284. The regex and regcmp function are part of libgen in SVR4.  Motif applications
  285. should be linked with -lgen. (However, some SVR4 implementations, especially
  286. those of vendors that once shipped SVR3 still contain libPW.)
  287.  
  288. On Solaris 2.x system, you'll need libgen which is located in /usr/ccs/lib.
  289.  
  290. -----------------------------------------------------------------------------
  291. Subject: 122)  What are these compile errors: Undefined symbol _regcmp and
  292. _regex?
  293. [Last modified: Sept 94]
  294.  
  295. Answer: You need to link in the libPW or libgen library - see previous
  296. question.
  297.  
  298. -----------------------------------------------------------------------------
  299. Subject: 123)  What's wrong with the Motif 1.0 File Selection Box?  I can't
  300. set the directory, change the directory or get the file mask to work.
  301.  
  302. Answer: The 1.0 File Selection Box is broken, and these don't work.  They
  303. weren't fixed until Motif 1.04.  Use these later versions of 1.0 or switch to
  304. Motif 1.1 where it changed a lot.
  305.  
  306. Joe Hildebrand has a work-around for some of this: Before popping up an
  307. XmFileSelectionDialog, change to the directory you want.  When a file is
  308. selected, check if it is a directory, so that we can change to it.  i.e.
  309.  
  310. static void show_file_box_CB(w, client_data, call_data)
  311. Widget               w;
  312. Widget               client_data;
  313. XmAnyCallbackStruct  *call_data;
  314. {
  315. chdir("/users/hildjj/files");
  316. XtManageChild(client_data);
  317. }
  318.  
  319. static void val_save(w, client_data, call_data)
  320. Widget       w;
  321. Widget       client_data;
  322. XmSelectionBoxCallbackStruct *call_data;
  323. {
  324. struct stat buf;  /* struct stat is defined in stat.h */
  325. char *filename;
  326.  
  327. /* get the file name from the FileSelectionBox */
  328. filename = SmX(call_data->value);
  329.  
  330. /* get the status of the file named filename, and put it into buf */
  331. if (!stat(filename, &buf))
  332. {
  333. /* if it's a directory */
  334. /* if it's a directory */
  335. if(S_ISDIR(buf.st_mode))
  336. {
  337.  /* change to that directory, and update the FileSelectionBox */
  338. chdir(filename);
  339. XmFileSelectionDoSearch(w, NULL);
  340. }
  341. else
  342.  /* if it's a regular file */
  343.  if(S_ISREG(buf.st_mode))
  344.     /* ask if it should be overwritten */
  345.     XtManageChild(valbox);
  346.  else
  347.     /* it's another kind of file.  What type, i can't think of,
  348.        but it might happen */
  349.     pop_up_error_box(client_data, "Error saving file");
  350. }
  351. else  /* we couldn't get the file status */
  352. {
  353. /* if it's because the file doesn't exist, we're golden */
  354. if (errno == ENOENT)
  355.  save_file();
  356. else   /* there is some other problem getting the status.
  357.         e.g. bad path */
  358.  pop_up_error_box(client_data, "Error saving file");
  359. }
  360. }
  361.  
  362. this still doesn't implement the file masking stuff.
  363.  
  364. -----------------------------------------------------------------------------
  365. Subject: 124)  How can I keep my file selection boxes from resizing when I
  366. change directories or filters?
  367. [Last modified: May 97]
  368.  
  369. Answer: Set XmNresizePolicy (XmFileSelectionDialog is a subclass of
  370. XmBulletinBoard) to XmRESIZE_NONE.
  371.  
  372. -----------------------------------------------------------------------------
  373. Subject: 125)  What's wrong with the FileSelectionBox under Solaris?
  374. [Last modified: May 97]
  375.  
  376. Answer: Jim Guyton (guyton@burton.cs.colorado.edu) writes:
  377.  
  378. While not strictly a Motif problem, this one had me confused for [awhile].
  379.  
  380. If under Solaris the entries in a FileSelectionBox look strange and seem to be
  381. missing the first two characters of many filenames, then be sure you're
  382. linking -lc before -lucb.
  383.  
  384. If on the other hand, the filenames look strange and seem to have two garbage
  385. characters in front of every filename, be sure to link -lucb before -lc.
  386.  
  387. There are two versions of readdir().  The one in -lucb returns a structure
  388. that has the filename at an offset of 8 bytes (which matches
  389. /usr/ucbinclude/sys/dir.h).
  390.  
  391. But the version in -lc returns the filename at an offset of 10 bytes (which
  392. matches /usr/include/dirent.h).
  393.  
  394. So depending on how Motif was built for your Solaris, vs. how you link your
  395. application, your filenames could be two bytes off in either direction.
  396.  
  397.  
  398. Harry Cohen (hbcohen@bell.tds-eagan.lmco.com) writes: I also had this problem
  399. (the missing horizontal scroll bar with Solaris 2.5.1 and 2.4) and have talked
  400. with Sun. This is a problem with the Sun Motif library in /usr/dt/lib.
  401.  
  402. You need to install the following Sun patches to correct this problem: For
  403. Solaris 2.5.1: patch 103461-03 For Solaris 2.4:   patch 102226-19
  404.  
  405. Note: For Solaris 2.4, the horizontal scroll problem existed in a previous
  406. patch release, so most people haven't seen it.
  407.  
  408.  
  409. Scott W. Sadler (sws@iti-oh.com) writes: We had this same problem, and it took
  410. a while to figure it out.  If you use the Motif libraries out of /usr/dt/lib,
  411. the file selection box gives the problem you indicate.  However, if you use
  412. the Motif libraries out of /opt/SUNWspro/Motif_Solaris24/dt/lib, all is fine.
  413.  
  414. Make sure your LD_LIBRARY_PATH, is set correctly to pick up the right shared
  415. libraries at run time.  Also check out the "-R" option to the linker to encode
  416. the library search paths.  Finally use the "ldd" program to make sure that you
  417. are picking up the correct libraries.
  418.  
  419.  
  420. -----------------------------------------------------------------------------
  421. Subject: 126)  TOPIC: FORM WIDGET
  422.  
  423.  
  424. -----------------------------------------------------------------------------
  425. Subject: 127)  Why don't labels in a Form resize when the label is changed?
  426. I've got some labels in a form. The labels don't resize whenever the label
  427. string resource is changed. As a result, the operator has to resize the window
  428. to see the new label contents. I am using Motif 1.1.
  429.  
  430. Answer: This problem may happen to any widget inside a Form widget. The
  431. problem was that the Form will resize itself when it gets geometry requests
  432. from its children. If its preferred size is not allowed, the Form will
  433. disallow all geometry requests from its children. The workaround is that you
  434. should set any ancestor of the Form to be resizable. For the shell which
  435. contains the Form you should set the shell resource XmNallowShellResize to be
  436. True (by default, it is set to FALSE).  There is currently an inconsistency on
  437. how resizing is being done, and it may get fixed in Motif 1.2.
  438.  
  439. db@sunbim.be (Danny Backx) wrote:
  440.  
  441. Basically what you have to do is set the XmNresizePolicy on the Form to
  442. XmRESIZE_NONE.  The facts seem to be that XmRESIZE_NONE does NOT mean "do not
  443. allow resizes".  You may also have to set XmNresizable on the form to True.
  444.  
  445. -----------------------------------------------------------------------------
  446. Subject: 128)  How can I center a widget in a form?
  447. [Last modified: Nov 96]
  448.  
  449. Answer: One of Motif's trickier questions.  The problems are that: Form gives
  450. no support for centering, only for edge attachments, and the widget must stay
  451. in the center if the form or the widget is resized.  Just looking at
  452. horizontal centering (vertical is similar) some solutions are:
  453.  
  454.  a.  Use the table widget instead of Form.  A hack free solution is from Dan
  455.      Heller:
  456.  
  457.      /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
  458.      * This program is freely distributable without licensing fees and
  459.      * is provided without guarantee or warranty expressed or implied.
  460.      * This program is -not- in the public domain.  This program is
  461.      * taken from the Motif Programming Manual, O'Reilly Volume 6.
  462.      */
  463.  
  464.      /* corners.c -- demonstrate widget layout management for a
  465.      * BulletinBoard widget.  There are four widgets each labeled
  466.      * top-left, top-right, bottom-left and bottom-right.  Their
  467.      * positions in the bulletin board correspond to their names.
  468.      * Only when the widget is resized does the geometry management
  469.      * kick in and position the children in their correct locations.
  470.      */
  471.      #include <Xm/BulletinB.h>
  472.      #include <Xm/PushBG.h>
  473.  
  474.      char *corners[] = {
  475.      "Top-Left", "Top-Right", "Bottom-Left", "Bottom-Right",
  476.      };
  477.  
  478.      static void resize();
  479.  
  480.      main(argc, argv)
  481.      int argc;
  482.      char *argv[];
  483.      {
  484.      Widget toplevel, bboard;
  485.      XtAppContext app;
  486.      XtActionsRec rec;
  487.      int i;
  488.  
  489.      /* Initialize toolkit and create toplevel shell */
  490.      toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0,
  491.      &argc, argv, NULL, NULL);
  492.  
  493.      /* Create your standard BulletinBoard widget */
  494.      bboard = XtVaCreateManagedWidget("bboard",
  495.      xmBulletinBoardWidgetClass, toplevel, NULL);
  496.  
  497.      /* Set up a translation table that captures "Resize" events
  498.      * (also called ConfigureNotify or Configure events).  If the
  499.      * event is generated, call the function resize().
  500.      */
  501.      rec.string = "resize";
  502.      rec.proc = resize;
  503.      XtAppAddActions(app, &rec, 1);
  504.  
  505.      /******** WARNING! Next statement is questionable in 1996. See
  506.      ******** "Can you reuse the return value from XtParseTranslationTable?"
  507.      ******** If someone corrects this code, send it to kenton@nojunk.rahul.net
  508.      ********/
  509.  
  510.      XtOverrideTranslations(bboard,
  511.      XtParseTranslationTable("<Configure>: resize()"));
  512.  
  513.      /* Create children of the dialog -- a PushButton in each corner. */
  514.      for (i = 0; i < XtNumber(corners); i++)
  515.      XtVaCreateManagedWidget(corners[i],
  516.          xmPushButtonGadgetClass, bboard, NULL);
  517.  
  518.      XtRealizeWidget(toplevel);
  519.      XtAppMainLoop(app);
  520.      }
  521.  
  522.      /* resize(), the routine that is automatically called by Xt upon the
  523.      * delivery of a Configure event.  This happens whenever the widget
  524.      * gets resized.
  525.      */
  526.      static void
  527.      resize(w, event, args, num_args)
  528.      CompositeWidget w;   /* The widget (BulletinBoard) that got resized */
  529.      XConfigureEvent *event;  /* The event struct associated with the event */
  530.      String args[]; /* unused */
  531.      int *num_args; /* unused */
  532.      {
  533.      WidgetList children;
  534.      int width = event->width;
  535.      int height = event->height;
  536.      Dimension w_width, w_height;
  537.      short margin_w, margin_h;
  538.  
  539.      /* get handle to BulletinBoard's children and marginal spacing */
  540.      XtVaGetValues(w,
  541.      XmNchildren, &children,
  542.      XmNmarginWidth, &margin_w,
  543.      XmNmarginHeight, &margin_h,
  544.      NULL);
  545.  
  546.      /* place the top left widget */
  547.      XtVaSetValues(children[0],
  548.      XmNx, margin_w,
  549.      XmNy, margin_h,
  550.      NULL);
  551.  
  552.      /* top right */
  553.      XtVaGetValues(children[1], XmNwidth, &w_width, NULL);
  554.  
  555.      /* To Center a widget in the middle of the BulletinBoard (or Form),
  556.      * simply call:
  557.      *   XtVaSetValues(widget,
  558.        XmNx,    (width - w_width)/2,
  559.        XmNy,    (height - w_height)/2,
  560.        NULL);
  561.      * and return.
  562.      */
  563.      XtVaSetValues(children[1],
  564.      XmNx, width - margin_w - w_width,
  565.      XmNy, margin_h,
  566.      NULL);
  567.  
  568.      /* bottom left */
  569.      XtVaGetValues(children[2], XmNheight, &w_height, NULL);
  570.      XtVaSetValues(children[2],
  571.      XmNx, margin_w,
  572.      XmNy, height - margin_h - w_height,
  573.      NULL);
  574.  
  575.      /* bottom right */
  576.      XtVaGetValues(children[3],
  577.      XmNheight, &w_height,
  578.      XmNwidth, &w_width,
  579.      NULL);
  580.      XtVaSetValues(children[3],
  581.      XmNx, width - margin_w - w_width,
  582.      XmNy, height - margin_h - w_height,
  583.      NULL);
  584.      }
  585.  
  586.  b.  No uil solution has been suggested, because of the widget size problem.
  587.  
  588.  c.  Cameron Hayne (hayne@crim.ca) suggests another solution:
  589.  
  590.      Attach the widget with XmATTACH_POSITION but offset it by half of its
  591.      width.  You will likely have to create the widget first and then query it
  592.      to find out its width. Thus the following function is useful - you can
  593.      call it immediately after the widget is created.
  594.  
  595.      void    center_it(Widget wgt)
  596.      {
  597.      Dimension       width;
  598.      XtVaGetValues(wgt, XmNwidth, &width, NULL);
  599.      XtVaSetValues(wgt, XmNleftAttachment, XmATTACH_POSITION,
  600.                      XmNleftPosition, 50,  /* assumes fractionBase is 100 */
  601.                      XmNleftOffset, -width/2, NULL);
  602.      }
  603.  
  604.      The idea is: get the size of the widget and then offset it by half that
  605.      much from position 50.  The above function will likely only work for
  606.      primitive widgets if you call it immediately after the widget is created.
  607.      For manager widgets you will likely have to wait to call the center_it()
  608.      function until after the widget has been realized since it is only then
  609.      that a manager widget's size is finally determined.  (Refer to discussion
  610.      by Daniel Dardailler "Application's Geometry Management Advanced
  611.      Guidelines" in this FAQ.)
  612.  
  613. -----------------------------------------------------------------------------
  614. Subject: 129)  How do I line up two columns of widgets of different types?  I
  615. have a column of say label widgets, and a column of text widgets and I want to
  616. have them lined up horizontally. The problem is that they are of different
  617. heights. Just putting them in a form or rowcolumn doesn't line them up
  618. properly because the label and text widgets are of different height.
  619.  
  620. If you want the geometry to look like this
  621.  
  622.   -------------------------------------
  623.  |          -------------------------- |
  624.  |a label  |Some text                 ||
  625.  |          -------------------------- |
  626.                    ------------------- |
  627.  |a longer label  |Some more text     ||
  628.  |                 ------------------- |
  629.  |                    ---------------- |
  630.  |a very long label  |Even more text  ||
  631.  |                    ---------------- |
  632.   -------------------------------------
  633.  
  634. try
  635.  
  636. /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
  637. * This program is freely distributable without licensing fees and
  638. * is provided without guarantee or warranty expressed or implied.
  639. * This program is -not- in the public domain.  This program is
  640. * taken from the Motif Programming Manual, O'Reilly Volume 6.
  641. */
  642.  
  643. /* text_form.c -- demonstrate how attachments work in Form widgets.
  644. * by creating a text-entry form type application.
  645. */
  646.  
  647. #include <Xm/PushB.h>
  648. #include <Xm/PushBG.h>
  649. #include <Xm/LabelG.h>
  650. #include <Xm/Text.h>
  651. #include <Xm/Form.h>
  652.  
  653. char *prompts[] = {
  654. "Name:", "Phone:", "Address:",
  655. "City:", "State:", "Zip:",
  656. };
  657.  
  658. main(argc, argv)
  659. int argc;
  660. char *argv[];
  661. {
  662. Widget toplevel, mainform, subform, label, text;
  663. XtAppContext app;
  664. char buf[32];
  665. int i;
  666.  
  667. toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0,
  668. &argc, argv, NULL, NULL);
  669.  
  670. mainform = XtVaCreateWidget("mainform",
  671. xmFormWidgetClass, toplevel,
  672. NULL);
  673.  
  674. for (i = 0; i < XtNumber(prompts); i++) {
  675. subform = XtVaCreateWidget("subform",
  676.     xmFormWidgetClass,   mainform,
  677.     /* first one should be attached for form */
  678.     XmNtopAttachment,    i? XmATTACH_WIDGET : XmATTACH_FORM,
  679.     /* others are attached to the previous subform */
  680.     XmNtopWidget,        subform,
  681.     XmNleftAttachment,   XmATTACH_FORM,
  682.     XmNrightAttachment,  XmATTACH_FORM,
  683.     NULL);
  684. label = XtVaCreateManagedWidget(prompts[i],
  685.     xmLabelGadgetClass,  subform,
  686.     XmNtopAttachment,    XmATTACH_FORM,
  687.     XmNbottomAttachment, XmATTACH_FORM,
  688.     XmNleftAttachment,   XmATTACH_FORM,
  689.     XmNalignment,        XmALIGNMENT_BEGINNING,
  690.     NULL);
  691. sprintf(buf, "text_%d", i);
  692. text = XtVaCreateManagedWidget(buf,
  693.     xmTextWidgetClass,   subform,
  694.     XmNtopAttachment,    XmATTACH_FORM,
  695.     XmNbottomAttachment, XmATTACH_FORM,
  696.     XmNrightAttachment,  XmATTACH_FORM,
  697.     XmNleftAttachment,   XmATTACH_WIDGET,
  698.     XmNleftWidget,       label,
  699.     NULL);
  700. XtManageChild(subform);
  701. }
  702. /* Now that all the forms are added, manage the main form */
  703. XtManageChild(mainform);
  704.  
  705. XtRealizeWidget(toplevel);
  706. XtAppMainLoop(app);
  707. }
  708.  
  709. If you resize horizontally it stretches the text widgets.  If you resize
  710. vertically it leaves space under the bottom (if you don't resize, this is not
  711. problem).
  712.  
  713. If you want the text widgets to be lined up on the left, as in
  714.  
  715.   ----------------------------------------
  716.  |                    ------------------- |
  717.  |          a label  |Some text          ||
  718.  |                    ------------------- |
  719.                       ------------------- |
  720.  |   a longer label  |Some more text     ||
  721.  |                    ------------------- |
  722.  |                    ------------------- |
  723.  |a very long label  |Even more text     ||
  724.  |                    ------------------- |
  725.   ----------------------------------------
  726.  
  727. try this
  728.  
  729. /* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
  730. * This program is freely distributable without licensing fees and
  731. * is provided without guarantee or warranty expressed or implied.
  732. * This program is -not- in the public domain.  This program is
  733. * taken from the Motif Programming Manual, O'Reilly Volume 6.
  734. */
  735.  
  736. /* text_entry.c -- This demo shows how the RowColumn widget can be
  737. * configured to build a text entry form.  It displays a table of
  738. * right-justified Labels and Text widgets that extend to the right
  739. * edge of the Form.
  740. */
  741. #include <Xm/LabelG.h>
  742. #include <Xm/RowColumn.h>
  743. #include <Xm/Text.h>
  744.  
  745. char *text_labels[] = {
  746. "Name:", "Phone:", "Address:", "City:", "State:", "Zip:",
  747. };
  748.  
  749. main(argc, argv)
  750. int argc;
  751. char *argv[];
  752. {
  753. Widget toplevel, rowcol;
  754. XtAppContext app;
  755. char buf[8];
  756. int i;
  757.  
  758. toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0,
  759. &argc, argv, NULL, NULL);
  760.  
  761. rowcol = XtVaCreateWidget("rowcolumn",
  762. xmRowColumnWidgetClass, toplevel,
  763. XmNpacking,        XmPACK_COLUMN,
  764. XmNnumColumns,     XtNumber(text_labels),
  765. XmNorientation,    XmHORIZONTAL,
  766. XmNisAligned,      True,
  767. XmNentryAlignment, XmALIGNMENT_END,
  768. NULL);
  769.  
  770. /* simply loop thru the strings creating a widget for each one */
  771. for (i = 0; i < XtNumber(text_labels); i++) {
  772. XtVaCreateManagedWidget(text_labels[i],
  773.     xmLabelGadgetClass, rowcol,
  774.     NULL);
  775. sprintf(buf, "text_%d", i);
  776. XtVaCreateManagedWidget(buf,
  777.     xmTextWidgetClass, rowcol,
  778.     NULL);
  779. }
  780.  
  781. XtManageChild(rowcol);
  782. XtRealizeWidget(toplevel);
  783. XtAppMainLoop(app);
  784. }
  785.  
  786. This makes all objects exactly the same size.  It does not resize in nice
  787. ways.
  788.  
  789. If you want the text widgets lined up on the left, and the labels to be the
  790. size of the longest string, resizing nicely both horizontally and vertically,
  791. as in
  792.  
  793.  -------------------------------------
  794. |                    ---------------- |
  795. |          a label  |Some text       ||
  796. |                    ---------------- |
  797.                      ---------------- |
  798. |   a longer label  |Some more text  ||
  799. |                    ---------------- |
  800. |                    ---------------- |
  801. |a very long label  |Even more text  ||
  802. |                    ---------------- |
  803.  -------------------------------------
  804.  
  805.  
  806. Answer: Do this: to get the widgets lined up horizontally, use a form but
  807. place the widgets using XmATTACH_POSITION.  In the example, attach the top of
  808. the first label to the form, the bottomPosition to 33 (33% of the height).
  809. Attach the topPosition of the second label to 33 and the bottomPosition to 66.
  810. Attach the topPosition of the third label to 66 and the bottom of the label to
  811. the form.  Do the same with the text widgets.
  812.  
  813. To get the label widgets lined up vertically, use the right attachment of
  814. XmATTACH_OPPOSITE_WIDGET: starting from the one with the longest label, attach
  815. widgets on the right to each other. In the example, attach the 2nd label to
  816. the third, and the first to the second.  To get the text widgets lined up,
  817. just attach them on the left to the labels.  To get the text in the labels
  818. aligned correctly, use XmALIGNMENT_END for the XmNalignment resource.
  819.  
  820. /* geometry for label 2
  821. */
  822. n = 0;
  823. XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  824. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  825. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  826. XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  827. XtSetArg (args[n], XmNtopPosition, 66); n++;
  828. XtSetValues (label[2], args, n);
  829.  
  830. /* geometry for label 1
  831. */
  832. n = 0;
  833. XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  834. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  835. XtSetArg (args[n], XmNbottomPosition, 66); n++;
  836. XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  837. XtSetArg (args[n], XmNtopPosition, 33); n++;
  838. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  839. XtSetArg (args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  840. XtSetArg (args[n], XmNrightWidget, label[2]); n++;
  841. XtSetValues (label[1], args, n);
  842.  
  843. /* geometry for label 0
  844. */
  845. n = 0;
  846. XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++;
  847. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  848. XtSetArg (args[n], XmNbottomPosition, 33); n++;
  849. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  850. XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
  851. XtSetArg (args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
  852. XtSetArg (args[n], XmNrightWidget, label[1]); n++;
  853. XtSetValues (label[0], args, n);
  854.  
  855. /* geometry for text 0
  856. */
  857. n = 0;
  858. XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
  859. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  860. XtSetArg (args[n], XmNbottomPosition, 33); n++;
  861. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  862. XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  863. XtSetArg (args[n], XmNleftWidget, label[0]); n++;
  864. XtSetValues (text[0], args, n);
  865.  
  866. /* geometry for text 1
  867. */
  868. XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  869. XtSetArg (args[n], XmNtopPosition, 33); n++;
  870. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
  871. XtSetArg (args[n], XmNbottomPosition, 66); n++;
  872. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  873. XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  874. XtSetArg (args[n], XmNleftWidget, label[1]); n++;
  875. XtSetValues (text[1], args, n);
  876.  
  877. /* geometry for text 2
  878. */
  879. XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
  880. XtSetArg (args[n], XmNtopPosition, 66); n++;
  881. XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
  882. XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  883. XtSetArg (args[n], XmNleftWidget, label[2]); n++;
  884. XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  885. XtSetValues (text[2], args, n);
  886.  
  887.  
  888. -----------------------------------------------------------------------------
  889. Subject: 130)  TOPIC: PUSHBUTTON WIDGET
  890.  
  891. -----------------------------------------------------------------------------
  892. Subject: 131)  Why doesn't the enter or return key activate the button with
  893. focus?
  894. [Last modified: Sep 98]
  895.  
  896. Answer: Motif uses the return key to activate the default button on dialogs,
  897. bulletin boards, and forms.  You can use the space key to activate the focus
  898. button.  These are they same keyboard shortcuts as MS-Windows.
  899.  
  900. -----------------------------------------------------------------------------
  901. Subject: 132)  Why can't I use accelerators on buttons not in a menu?
  902. [Last modified: Sept 94]
  903.  
  904. Answer: It is apparently a difficult feature to implement, but OSF are
  905. considering this for the future. It is problematic trying to use the Xt
  906. accelerators since the Motif method interferes with this.  one workaround
  907. suggested is to duplicate your non-menu button by a button in a menu
  908. somewhere, which does have a menu-accelerator installed.  When the user
  909. invokes what they think is the accelerator for the button they can see Motif
  910. actually invokes the button on the menu that they can't see at the time.
  911. Another method is described below and was contributed by Harald Albrecht of
  912. Institute of Geometry and Practical Mathematics Rhine Westphalia Technical
  913. University Aachen (RWTH Aachen), Germany
  914.  
  915.  
  916. albrecht@igpm.rwth-aachen.de wrote (Jul 8, 1993):
  917.  
  918. NOTE: Pointers to a more recent solution by the same author follow this code
  919. sample.
  920.  
  921. My work-around of this problem looks like this: (I've written that code for a
  922. Motif Object Library in C++ so please forgive me for being object orientated!)
  923. The hack consists of a rewritten message loop which checks for keypresses
  924. <MAlt>+<key>. If MessageLoop() finds such a keypress HandleAcc() ist called
  925. and the widget tree is searched for a suitable widget with the right mnemonic.
  926.  
  927.  
  928. // --------------------------------------------------------------------------
  929. // traverse the widget tree starting with the given widget.
  930. //
  931. BOOL TraverseWidgetTree(Widget w, char *pMnemonic, XKeyEvent *KeyEvent)
  932. {
  933. Widget               wChild;
  934. WidgetList               ChildList;
  935. int                      NumChilds, Child;
  936. KeySym               LabelMnemonic;
  937. char                 *pMnemonicString;
  938.  
  939. // Check if the widget is a subclass of label -- then it may have an
  940. // accelerator attached...
  941. if ( XtIsSubclass(w, xmLabelWidgetClass) ) {
  942. // ok. Now: get the widget's mnemonic, convert it to ASCII and compare
  943. // it with the Key we're looking for.
  944. XtVaGetValues(w, XmNmnemonic, &LabelMnemonic, NULL);
  945. pMnemonicString = XKeysymToString(LabelMnemonic);
  946. if ( pMnemonicString &&
  947.      (strcasecmp(pMnemonicString, pMnemonic) == 0) ) {
  948.     // stimulate the keypress
  949.     XmProcessTraversal((Widget)w, XmTRAVERSE_CURRENT);
  950.     KeyEvent->type      = KeyPress;
  951.     KeyEvent->window    = XtWindow(w);
  952.     KeyEvent->subwindow = XtWindow(w);
  953.     KeyEvent->state     = 0;
  954.     KeyEvent->keycode   =
  955.         XKeysymToKeycode(XtDisplay(w), XK_space);
  956.     XSendEvent(XtDisplay(w), XtWindow(w),
  957.                True,
  958.                ButtonPressMask, (XEvent*) KeyEvent);
  959.     KeyEvent->type      = KeyRelease;
  960.     XSendEvent(XtDisplay(w), XtWindow(w),
  961.                True,
  962.                ButtonReleaseMask, (XEvent*) KeyEvent);
  963.     return True;
  964. }
  965. }
  966. // if this widget is a subclass of Composite check all the widget's
  967. // childs.
  968. if ( XtIsSubclass(w, compositeWidgetClass) ) {
  969. // if we're in a menu (or something like that) forget this leaf of the
  970. // widget tree!
  971. if ( XtIsSubclass(w, xmRowColumnWidgetClass) ) {
  972.     unsigned char RowColumnType;
  973.     XtVaGetValues(w, XmNrowColumnType, &RowColumnType, NULL);
  974.     if ( RowColumnType != XmWORK_AREA ) return False;
  975. }
  976. XtVaGetValues(w, XmNchildren, &ChildList,
  977.                  XmNnumChildren, &NumChilds, NULL);
  978. for ( Child = 0; Child < NumChilds; ++Child ) {
  979.     wChild = ChildList[Child];
  980.     if ( TraverseWidgetTree(wChild, pMnemonic, KeyEvent) )
  981.         return True;
  982. }
  983. }
  984. return False;
  985. } // TraverseWidgetTree
  986. // --------------------------------------------------------------------------
  987. // handle accelerators (keypress MAlt + key)
  988. //
  989. #define MAX_MAPPING 10
  990. BOOL HandleAcc(Widget w, XEvent *event)
  991. {
  992.    Widget         widget, OldWidget;
  993. static char           keybuffer[MAX_MAPPING];
  994.    int            CharCount;
  995. static XComposeStatus composeStatus;
  996.  
  997. // convert KeyPress to ASCII
  998. CharCount = XLookupString((XKeyEvent*) event,
  999.                       keybuffer, sizeof(keybuffer),
  1000.                       NULL, &composeStatus);
  1001. keybuffer[CharCount] = 0;
  1002. // Only one char is alright -- then search the widget tree for a widget
  1003. // with the right mnemonic
  1004. if ( CharCount == 1 ) {
  1005. keybuffer[0] = tolower(keybuffer[0]);
  1006. widget = w;
  1007. while ( (widget != NULL) &&
  1008.         !XtIsSubclass(widget, shellWidgetClass) ) {
  1009.     OldWidget = widget; widget = XtParent(widget);
  1010. }
  1011. if ( !widget ) widget = OldWidget;
  1012. return TraverseWidgetTree(widget,
  1013.                           keybuffer, (XKeyEvent*) event);
  1014. }
  1015. return False; // no-one found.
  1016. } // HandleAcc
  1017. // --------------------------------------------------------------------------
  1018. // modified message loop
  1019. // loops until the Boolean pFlag points to is set to False
  1020. void MessageLoop(Boolean *pFlag)
  1021. {
  1022. XEvent nextEvent;
  1023.  
  1024. while ( *pFlag ) {
  1025. if ( XtAppPending(AppContext) ) {
  1026.     XtAppNextEvent(AppContext, &nextEvent);
  1027.     if ( nextEvent.type == KeyPress ) {
  1028. // Falls es ein Tastendruck ist, bei dem auch noch die ALT-Taste
  1029. // (=Modifier 1) gedrueckt ist, koennte es ein Accelerator sein!
  1030.         if ( nextEvent.xkey.state & Mod1Mask )
  1031.             if ( HandleAcc(XtWindowToWidget(nextEvent.xkey.display,
  1032.                                             nextEvent.xkey.window),
  1033.                            &nextEvent) )
  1034.                 continue; // Mitteilung konnte ausgeliefert werden
  1035.                           // und darf daher nicht den ueblichen
  1036.                           // Weg gehen!
  1037.     }
  1038.     XtDispatchEvent(&nextEvent);
  1039. }
  1040. }
  1041. } // TApplication::MessageLoop
  1042.  
  1043.  
  1044. Harald Albrecht albrecht@igpm.rwth-aachen.de Institute of Geometry and
  1045. Practical Mathematics Rhine Westphalia Technical University Aachen (RWTH
  1046. Aachen), Germany
  1047.  
  1048. NOTE: Harald Albrecht has re-designed his solution so that you can assign
  1049. hotkeys to *every* widget by placing a label near that widget. Get the code
  1050. from:
  1051.  
  1052. ftp.informatik.rwth-aachen.de (137.226.112.172) in:
  1053. /pub/packages/Mnemonic/Mnemonic.tar.gz
  1054.  
  1055. or from the WWW:
  1056.  
  1057. file://134.130.161.30/arc/pub/unix/html/motifcorner.html
  1058.  
  1059. -----------------------------------------------------------------------------
  1060. Subject: 133)  TOPIC: TOGGLEBUTTON WIDGET
  1061.  
  1062. -----------------------------------------------------------------------------
  1063. Subject: 134)  What widgets give the look of push buttons, but behavior of
  1064. toggle buttons?
  1065.  
  1066. Answer: Use the XmToggleButton widget, setting XmNindicatorOn to False and
  1067. XmNshadowThickness to 2.  Also set XmNfillOnSelect to True. Otherwise, the
  1068. background color of the button will not stay in the "armed" state.
  1069.  
  1070. In Motif 1.2 (and later), if you specify a XmNselectColor and set
  1071. XmNindicatorOn to False, then you need to set XmNfillOnSelect to True.
  1072. XmNfillOnSelect is not necessary if you are not setting a XmNselectColor.
  1073.  
  1074. Glenn McMillen, mcmillen@meadow.mdso.vf.ge.com and Ken Lee
  1075.  
  1076. -----------------------------------------------------------------------------
  1077. Subject: 135)  Can I customize XmToggleButton to use my own indicator graphic
  1078. (e.g., a check mark)?
  1079. [Last modified: Nov 96]
  1080.  
  1081. Answer: There is no direct resource for the graphic.  One way to work around
  1082. this is to disable the indicator (XmNindicatorOn False) and then install
  1083. selected/unselected pixmaps containing both your graphic and your text
  1084. (XmNselectPixmap and XmNselectPixmap).  Also disable the button shadows
  1085. (XmNshadowThickness 0) if you don't want those.
  1086.  
  1087. Ken Lee
  1088.  
  1089. -----------------------------------------------------------------------------
  1090. Subject: 136)  TOPIC: ICON WIDGET and PIXMAPS
  1091.  
  1092. -----------------------------------------------------------------------------
  1093. Subject: 137)  What is XPM?
  1094. [Last modified: Sept 98]
  1095.  
  1096. Answer: XPM is file format for color images.  A programming libary is also
  1097. available.  XPM is based on the standard XBM monochrome file format and Xlib
  1098. related convenience functions.
  1099.  
  1100. The XPM home page is: http://www.inria.fr/koala/lehors/xpm.html It has pointes
  1101. to the source code and detailed documentation.
  1102.  
  1103. Ken Lee
  1104.  
  1105. -----------------------------------------------------------------------------
  1106. Subject: 138)  How do I convert my XPM file into a Pixmap?
  1107. [Last modified: Sept 98]
  1108.  
  1109. Answer: Motif 2.0 and later contain an XPM-to-pixmap resource converter, so
  1110. you can specify your pixmaps as resources.
  1111.  
  1112. In Motif 1.2, you have to use the XPM library to load the XPM files.
  1113.  
  1114. Ken Lee
  1115.  
  1116. -----------------------------------------------------------------------------
  1117. Subject: 139)  How can I display a multi-color image in a widget?
  1118. [Last modified: Sept 95]
  1119.  
  1120. Answer: Get the XPM library and read the documentation.  Get xpaint from
  1121. ftp.x.org, also get the jpeg and tiff libraries on the internet.  From these
  1122. you can easily create the code to read in gif, jpeg, and tiff.
  1123.  
  1124. Read the images into and XpmImage format.  Then use one of the Xpm conveneince
  1125. functions to create wither an XImage or a Pixmap from your data.  The xpm lib
  1126. will take care of the color allocation and Pixmap/XImage creation, then you
  1127. can just use expose routines to copy the Pixmap into a dialog or any
  1128. window....
  1129.  
  1130. Thanks to Ramiro Estrugo (restrugo@fateware.com)
  1131.  
  1132. -----------------------------------------------------------------------------
  1133. Subject: 140)  Can I use XmGetPixmap in Motif 1.2 to create colored images?
  1134. [Last modified: Oct 95]
  1135.  
  1136. Answer: Doug Rand (drand@sgi.com) writes:
  1137.  
  1138. XmGetPixmap only converts XBM [X bitmap] files in 1.2.  In 2.0 it supports XPM
  1139. [X Pixmap] files.  You can register a more capable converter and set the
  1140. pixmap via resources as a workaround.  You can also use libXpm
  1141. directly...[Note that] even now there isn't a "standard" color pixmap file
  1142. format.  There are several.  It is relatively recently that many people have
  1143. settled on XPM.  But even so not everyone has done this.
  1144.  
  1145. -----------------------------------------------------------------------------
  1146. Subject: 141)  Why does XpmCreatePixmapFromData fail with a pixmap containing
  1147. a large number of colors?  XpmCreatePixmapFromData gives me a -4 errno (which
  1148. is XpmColorFailed) when I try using a pixmap with 242 colors
  1149. [Last modified: Oct 95]
  1150.  
  1151. Answer: Ramiro Estrugo (restrugo@fateware.com) writes:
  1152.  
  1153. If you are allocating 242 colors in an 8 bit display, then you are likely to
  1154. run out of colors.  If you carefully read the Xpm manual, you will notice that
  1155. one of the Xpm values that you can modify is the "closeness".  This value will
  1156. control the actual closness of the colors allocated by the Xpm library.
  1157. According to the Xpm manual:
  1158.  
  1159. o The "closeness" field(s) (when set) control if and how colors
  1160. are found when they failed to be allocated.  If the color cannot
  1161. be allocated, Xpm looks in the colormap for a color that matches
  1162. the desired closeness.
  1163.  
  1164. o The value is an integer in the range 0 (black) - 65535 (white)
  1165.  
  1166. o A closeness of less than 10000 will cause only "close" colors to
  1167. match.
  1168.  
  1169. o A cliseness of more than 50000 will allow quite disimilar colors
  1170. to match.
  1171.  
  1172. o A closeness of more than 65535 will allow any color to match.
  1173.  
  1174. o A value of 40000 seems reasonable for many situations requiring
  1175. reasonable but not perfect color matches.
  1176.  
  1177. Try it and your application is less likely to die or look "ugly" due to the
  1178. lack of colors.  The worst that can happed is that the colors you get are not
  1179. 100% what you wanted them to be.  Most of the time, you might not even notice
  1180. the difference.  This is usually due to badly designed icons or duplicate
  1181. color entries (close rgb values) in .xpm files.
  1182.  
  1183. NOTE: for even more control over Xpm color allocation, you can control the
  1184. closeness of each RGB color component individually.
  1185.  
  1186. For example:
  1187.  
  1188. XpmAttributes   attrib;
  1189. int             valuemask;
  1190. attrib.valuemask |= XpmCloseness;
  1191. attrib.closeness = 40000;
  1192.  
  1193. /* also */
  1194.  
  1195. attrib.valuemask |= XpmRGBCloseness;
  1196. attrib.red_closeness = RED_CLOSENESS;
  1197. attrib.green_closeness = GREEN_CLOSENESS;
  1198. attrib.blue_closeness = BLUE_CLOSENESS;
  1199. pix = XpmCreateXYZFromABC(...,&attrib);
  1200.  
  1201. Also, look in the Xpm documentation for more color control parameters.
  1202.  
  1203. -----------------------------------------------------------------------------
  1204. Subject: 142)  How can I convert a Sun/GIF/TIFF image to a pixmap?
  1205. [Last modified: Oct 94]
  1206.  
  1207. Answer: An application called "xv" (interactive image display for the X Window
  1208. System) is useful for displaying and converting many image formats. From the
  1209. man page:
  1210.  
  1211. xv is an X11 program that displays images in the GIF,  JPEG,
  1212. TIFF,  PBM, PGM, PPM, X11 bitmap, PDS/VICAR, Sun Rasterfile,
  1213. and PM formats on 1-, 2-, 4-, 6-, 8-, 16-, 24-, and 32-bit X
  1214. displays.   xv  will also read compress-ed versions of these
  1215. files.
  1216.  
  1217. You can get "xv" (shareware by John Bradley et al) from:
  1218.  
  1219. ftp://ftp.cis.upenn.edu/pub/xv
  1220. or:
  1221. ftp://ftp.x.org/R5contrib/xv-3.01.tar.gz
  1222.  
  1223. Another useful conversion package is "pbm" (portable bitmap file format) by
  1224. Jef Poskanzer et al, available from:
  1225.  
  1226. ftp://ftp.x.org/R5contrib/netpbm-1mar1994.tar.gz
  1227. or:
  1228. ftp://ftp.x.org/R5contrib/pbmplus10dec91.tar.Z (much older :-)
  1229.  
  1230. You might also want to check the X11 FAQ for additional conversion options:
  1231.  
  1232. ftp://ftp.x.org/contrib/faqs/FAQ
  1233.  
  1234.  
  1235. -----------------------------------------------------------------------------
  1236. Subject: 143)  How can I use Motif's pre-defined pixmaps?
  1237. [Last modified: May 97]
  1238.  
  1239. Answer: Motif 1.2 loads the following into its image cache: background,
  1240. 25_foreground, 50_foreground, 75_foreground, horizontal, vertical,
  1241. slant_right, and slant_left.  These are defined in "man XmInstallImage".  You
  1242. can retrieve them with XmGetPixmap or XmGetPixmapByDepth.
  1243.  
  1244. Ken Lee
  1245.  
  1246. -----------------------------------------------------------------------------
  1247. Subject: 144)  TOPIC: SCALE AND SCROLLBAR WIDGET
  1248.  
  1249. -----------------------------------------------------------------------------
  1250. Subject: 145)  Can the XmScale widget have arrows or tick marks in Motif 2.0?
  1251. [Last modified: Sep 97]
  1252.  
  1253. Answer: Daniel Dardailler (danield@w3.org) writes:
  1254.  
  1255. In 2.0 and 2.1, Scale gets arrows (on both sides or same side), thermometer
  1256. look, thumb slider option, tick marks, and editable resource.
  1257.  
  1258. -----------------------------------------------------------------------------
  1259. Subject: 146)  How can I set the color of a XmScale widget's trough?
  1260. [Last modified: May 95]
  1261.  
  1262. Answer: Ken Lee wrote: There is no direct API for setting this, but you can
  1263. set it through resource files with "*XmScale*troughColor: red".
  1264.  
  1265. Ken Sall, ksall@cen.com, adds: If you need to do this at runtime, you can use
  1266. XtGetValues to get the scale's children, find the scrollbar, and set the
  1267. XmNtroughColor:
  1268.  
  1269. #include <Xm/ScrollBar.h>  // for XmIsScrollBar
  1270.  
  1271. Pixel selectColor; // assume this is set to the desired color
  1272. WidgetList *kids;
  1273. int nkids;
  1274. Arg argList[1], tmpargs[2];
  1275. int i, s, t ;
  1276.  
  1277. i = 0;
  1278. XtSetArg ( argList[i], XmNtroughColor, selectColor ); i++;
  1279.  
  1280. // Unfortunately, scale does not have a direct way
  1281. // to get its scrollbar widget, so use Composite resources
  1282. s = 0;
  1283. XtSetArg (tmpargs[s], XmNnumChildren, &nkids ); s++ ;
  1284. XtSetArg (tmpargs[s], XmNchildren, &kids ); s++ ;
  1285. XtGetValues ( widgetId, tmpargs, s );
  1286. for ( t = 0; t < nkids; t++ )
  1287.     {
  1288.     if ( XmIsScrollBar ( (Widget) kids[t]) ) // from ScrollBar.h
  1289.         {
  1290.         XtSetValues ( (Widget) kids[t], argList, i );
  1291.         }
  1292.     }
  1293.  
  1294.  
  1295. -----------------------------------------------------------------------------
  1296. Subject: 147)  How does Motif implement mouse button auto-repeat on the
  1297. scrollbar's arrow buttons?
  1298. [Last modified: May 97]
  1299.  
  1300. Answer: It installs a timer and checks the button state at each timeout.  If
  1301. the button is still down, it repeats the action.  You can do this in your
  1302. application, too.
  1303.  
  1304. Ken Lee
  1305.  
  1306. -----------------------------------------------------------------------------
  1307. Subject: 148)  TOPIC: LABEL WIDGET
  1308.  
  1309. -----------------------------------------------------------------------------
  1310. Subject: 149)  How can I align the text in a label (button, etc) widget?
  1311.  
  1312. Answer: The alignment for the label widget is controlled by the resource
  1313. XmNalignment, and the default centers the text. Use this resource to change it
  1314. to left or right alignment.  However, when the label (or any descendant) is in
  1315. a XmRowColumn, and XmNisAligned is True (the default), the XmRowColumn aligns
  1316. text using its resource XmNentryAlignment. If you want simultaneous control
  1317. over all widgets use this, but otherwise turn XmNisAligned off and do it
  1318. individually.
  1319.  
  1320. -----------------------------------------------------------------------------
  1321. Subject: 150)  Why doesn't label alignment work in a XmRowColumn?
  1322.  
  1323. Answer: XmRowColumn has a resource XmNisAligned (default True) and and
  1324. XmNentryAlignment (default XmALIGNMENT_BEGINNING).  These control alignment of
  1325. the labelString in Labels and descendants. Set XmNisAligned to False to turn
  1326. this off.
  1327.  
  1328. -----------------------------------------------------------------------------
  1329. Subject: 151)  How can I set a multi-line label?
  1330. [Last modified: Mar 96]
  1331.  
  1332. Answer: In .Xdefaults
  1333.  
  1334. *XmLabel*labelString:              Here\nis\nthe\nLabel
  1335.  
  1336. This method does not seem to work in some of the older Motif 1.0 versions.
  1337.  
  1338. In code,
  1339.  
  1340. char buf[128];
  1341. XmString msg;
  1342. strcpy(buf, "Here\nis\nthe\nLabel");
  1343. msg = XmStringCreateLtoR(buf, XmSTRING_DEFAULT_CHARSET);
  1344. XtSetArg (args[n], XmNlabelString, msg);
  1345.  
  1346. Gives a four line label, using the escape sequence \n for a newline.  Here's
  1347. another approach from Jean-Philippe Martin-Flatin <syj@ecmwf.int>
  1348.  
  1349. #include <Xm/Xm.h>
  1350. #include <string.h>
  1351.  
  1352. /*-----------------------------------------------------
  1353. Create a new XmString from a char*
  1354.  
  1355. This function can deal with embedded 'newline' and
  1356. is equivalent to XmStringCreateLtoR,
  1357. except it does not use non AES compliant charset
  1358. XmSTRING_DEFAULT_CHARSET
  1359. ----------------------------------------------------*/
  1360. XmString xec_NewString(char *s)
  1361. {
  1362. XmString xms1;
  1363. XmString xms2;
  1364. XmString line;
  1365. XmString separator;
  1366. char     *p;
  1367. char     *t = XtNewString(s);   /* Make a copy for strtok not to */
  1368.                             /* damage the original string    */
  1369.  
  1370. separator = XmStringSeparatorCreate();
  1371. p         = strtok(t,"\n");
  1372. xms1      = XmStringCreateLocalized(p);
  1373.  
  1374. while (p = strtok(NULL,"\n"))
  1375. {
  1376. line = XmStringCreateLocalized(p);
  1377. xms2 = XmStringConcat(xms1,separator);
  1378. XmStringFree(xms1);
  1379. xms1 = XmStringConcat(xms2,line);
  1380. XmStringFree(xms2);
  1381. XmStringFree(line);
  1382. }
  1383.  
  1384. XmStringFree(separator);
  1385. XtFree(t);
  1386. return xms1;
  1387. }
  1388.  
  1389.  
  1390. Do not use XmStringCreateLocalized() - it does not process the newline
  1391. character in the way you want.   In Motif 1.x, XmStringCreateLocalized() does
  1392. NOT process newlines, but XmStringCreateLtoR() does.
  1393.  
  1394. Thanks to Paul Tomblin (ptomblin@xcski.com) for the newline clarification.
  1395.  
  1396. -----------------------------------------------------------------------------
  1397. Subject: 152)  How can I have a vertical label?
  1398.  
  1399. Answer: Make a multi-line label with one character per line, as in the last
  1400. question. There is no way to make the text rotated by 90 degrees though.
  1401.  
  1402.  
  1403. -----------------------------------------------------------------------------
  1404. Subject: 153)  How can I have a Pixmap in a Label?
  1405.  
  1406. Answer: Bob Hays (bobhays@spss.com) wrote:
  1407.  
  1408. Pixmap px_disarm, px_disarm_insens;
  1409.  
  1410. Widget Label1;
  1411. Pixel   foreground, background;
  1412. Arg     args[4];
  1413. Arg     arg[] = {
  1414.         { XmNforeground, &foreground },
  1415.         { XmNbackground, &background }
  1416. };
  1417.  
  1418. Label1 = XmCreateLabel ( Shell1, "Label1",
  1419.                                (Arg *) NULL, (Cardinal) 0 );
  1420. XtGetValues ( Label1, arg, XtNumber ( arg ) );
  1421. px_disarm =
  1422. XCreatePixmapFromBitmapData(display,
  1423.                         DefaultRootWindow(display),
  1424.                         mtn_bits, mtn_width, mtn_height,
  1425.                         foreground,
  1426.                         background,
  1427.                         DefaultDepth(display,DefaultScreen(display)));
  1428. px_disarm_insens =
  1429. XCreatePixmapFromBitmapData(display,
  1430.                         DefaultRootWindow(display),
  1431.                         mtn_ins_bits, mtn_ins_width, mtn_ins_height,
  1432.                         foreground,
  1433.                         background,
  1434.                         DefaultDepth(display,DefaultScreen(display)));
  1435.  
  1436. n = 0;
  1437. XtSetArg(args[n], XmNlabelType, XmPIXMAP);  n++;
  1438. XtSetArg(args[n], XmNlabelPixmap, px_disarm);  n++;
  1439. XtSetArg(args[n], XmNlabelInsensitivePixmap, px_disarm_insens ); n++;
  1440. XtSetValues ( Label1, args, n );
  1441. XtManageChild(Label1);
  1442.  
  1443. That will cause the foreground and background of your pixmap to be inherited
  1444. from the one that would be used by OSF/Motif when the label is displayed.  The
  1445. advantage is that this will utilize any resource values the user may have
  1446. requested without looking explicitly into the resource database.  And, you
  1447. will have a pixmap handy if the application insensitizes the label (without an
  1448. XmNlabelInsensitivePixmap your label will go empty if made insensitive).
  1449.  
  1450. [Bob's original code was for a PushButton. Just change all Label to PushButton
  1451. for them.]
  1452.  
  1453. -----------------------------------------------------------------------------
  1454. Subject: 154)  Why doesn't the XmLabel widget obey the XmNwith and XmNheight
  1455. that I give it?
  1456. [Last modified: May 95]
  1457.  
  1458. Answer: By default, XmLabel ignores these resources and instead computes a
  1459. size based on the size of the label string or pixmap.  You can change this
  1460. behavior by setting XmNrecomputeSize to False.  (Note that setting
  1461. XmNrecomputeSize to False can dramatically improve performance if you have
  1462. alot of labels or change them frequently.)
  1463.  
  1464. Ken Lee
  1465.  
  1466. -----------------------------------------------------------------------------
  1467. Subject: 155)  How do you set the background color of a label widget using
  1468. XtVaTypedArg?
  1469. [Last modified: July 96]
  1470.  
  1471. Answer: Use the XmNbackground resource to control the background color, e.g.
  1472.  
  1473. strcpy(bgcolor, "yellow");
  1474. XtVaSetValues(widget,
  1475.         XtVaTypedArg, XmNbackground, XtRString, bgcolor,
  1476.         strlen(bgcolor) + 1, NULL);
  1477.  
  1478. The length of the color string is plus one to include the null character.
  1479. XtRString is the type to be converted.  The conversion is required because
  1480. XmNbackground expects a Pixel type.
  1481.  
  1482. Thanks to Martin Squicciarini (msquicci@resd.vf.ge.com).
  1483.  
  1484. -----------------------------------------------------------------------------
  1485. END OF PART FIVE
  1486.