Motif FAQ [Last changed: 04 APR 94] This article contains the answers to some Frequently Asked Questions (FAQ) often seen in comp.windows.x.motif. It is posted to help reduce volume in this newsgroup and to provide hard-to-find information of general interest. Please redistribute this article! This FAQ is maintained by Brian Dealy . Send updates and corrections to me at that mail address. It would help if the subject line contained the phrase "FAQ". I will Be making a HTML version available in the very near (MAY)? future. It will hopefully provide a much fuller set of resources including URLs for examples and free software. It will require a bit of reorganizing and rewriting, but it should be well worth the wait. History: From November 89-July 93 the FAQ was maintained by Jan Newmarch This article includes answers to the following questions. Ones marked with a + indicate questions new to this issue; those with changes of content since the last issue are marked by *: 0)* TOPIC: WHAT ARE OTHER RELEVANT NEWSGROUPS? 1) TOPIC: FTP ARCHIVES 2) Is the FAQ list available for FTP anywhere? 3)* Is this FAQ accessible via WWW? 4) Is this newsgroup accessible via email? 5) Is this newsgroup archived? 6) Is the mail list motif-talk archived? 7) TOPIC: OSF AND MOTIF 8) Because of COSE, is Motif now in the public domain? 9)* What versions of Motif are there? 10)* Where can I get Motif? 11) Is there a list of Motif bugs? 12) Where can I get public domain Motif source? 13)* Are the Motif examples publically available? 14)* Has anyone done a public domain Motif lookalike? 15) Does anyone from OSF pay attention to our questions/suggestions? 16) Does OSF have an application compliance validation service? 17) What is the motif-talk mailing list? 18) What MIT patches do I use, and when do I use fix-osf? 19) How does Motif work with X11R5? 20)* How can I find which version of Motif I have? 21) TOPIC: LITERATURE 22)* What books should I read or do I need to program using Motif? 23) TOPIC: MWM 24) What is the difference between Motif and mwm? 25) Does anyone have an alternative set of 3-D defaults for a monochrome screen? 26) How can I modify the Motif window manager decorations? 27) How can I turn off the Motif window manager functions from the system menu? 28) How can tell I if the user has selected the "Close" item on the system menu attached to the top-level shell? 29) Is there an mwm virtual desktop manager? 30) Why does mwm 1.2 crash on startup? 31) TOPIC: MOTIF GENERATORS 32) What prototyping tools are there to generate Motif code? 33) TOPIC: TEXT WIDGET 34) What is the difference between a XmTextField widget and a single 35) Why does pressing in a text widget do nothing? 36) When I add text to a scrolling text widget how can I get the new text to show? 37) Does the text widget support 16 bit character fonts? 38) How can I stop the text widget from echoing characters typed? 39) How can I replace characters typed with say a `*'? 40) How can I best add a large piece of text to a scrolled text widget? 41) How can I highlight text in the Text widget? 42) How can I select all of the text in a widget programmatically? 43) How can I change colours of text in the Text widget? 44) How can I change the font of text in the Text widget? 45) Is there an emacs binding for the text widget? 46) How can I use a file as the text source for a Text widget? 47) How can put Text in overstrike mode instead of insert? 48) How can I make the Delete key do a backspace? 49) TOPIC: LIST WIDGET 50) Should I create an XmList widget as a child of automatic XmScrolledWindow or use the XmCreateScrolledList() convenience function? 51) How do I best put a new set of items into a list? 52) Can I have strings with different fonts in a list? 53) Can I get a bitmap to show in a list item like I can in a Label? 54) Can I have items with different colours in a list? 55) Can I grey out an item in a list? 56) Can I have multi-line items in a list? 57) How can I tell the position of selected items in a list? 58) TOPIC: FILE SELECTION BOX WIDGET 59) What is libPW.a and do I need it? 60) What are these compile errors: Undefined symbol _regcmp and _regex? 61) What's wrong with the Motif 1.0 File Selection Box? 62) TOPIC: FORM WIDGET 63) Why don't labels in a Form resize when the label is changed? 64) How can I center a widget in a form? 65) How do I line up two columns of widgets of different types? 66) TOPIC: PUSHBUTTON WIDGET 67) Why can't I use accelerators on buttons not in a menu? 68) TOPIC: LABEL WIDGET 69) How can I align the text in a label (button, etc) widget? 70) Why doesn't label alignment work in a RowColumn? 71) How can I set a multiline label? 72) How can I have a vertical label? 73) How can I have a Pixmap in a Label? 74) TOPIC: DRAWING AREA WIDGET 75) How can I send an expose event to a Drawing Area widget? 76) How can I know when a DrawingArea has been resized? 77) TOPIC: MENUS 78) What can I put inside a menu bar? 79) Can I have a cascade button without a submenu in a pulldown menu? 80) Should I have a cascade button without a submenu in a pulldown menu? 81) What is the best way to create popup menus? 82) How do popup menus work? 83) Should I use translation tables or actions for popup menus? 84) What are the known bugs in popup menus? 85) Can I have multiple popup menus on the same widget? 86) TOPIC: INPUT FOCUS 87) How can I specify the widget that should have the keyboard focus when my application starts up? 88) How can I direct the keyboard input to a particular widget? 89) How can I have a modal dialog which has to be answered before the application can continue? 90) TOPIC: MEMORY AND SPEED 91) When can I free data structures passed to or retrieved from Motif? 92) Why does my application grow in size? 93) Why does my application take a long time to start up? 94) My application is running too slowly. How can I speed it up? 95) Why is my application so huge? 96) TOPIC: XMSTRING 97) How can I get the Ascii text out of an XmString? 98) When can XmStrings used as resources be freed? 99) Why doesn't XmStringGetNextSegment() work properly? 100) Why does using XmStringDraw cause a Bad Font error? 101) TOPIC: DIALOGS 102) How do I stop my dialog disappearing when I press the help button? 103) How do I make my own dialog? 104) How come the title bars for my dialogs now have "_popup" or "<-popup" concatenated onto the widget name? 105) How can I force a dialog window to display? 106) How can I control placement of a popup widget? 107) TOPIC: LANGUAGE BINDINGS 108)* Is there a C++ binding for Motif? 109) How can I have a C++ member function in a callback? 110) Is there a Common Lisp binding for Motif? 111)* Is there an Ada binding for Motif? 112) Is there a Poplog binding for Motif? 113) TOPIC: SPECIFIC PLATFORMS 114) Is it easy to build Motif for a Sun? 115) How do I build Motif 1.2.2 on Solaris 2.1 with Sun C? 116) What compile errors/warnings might I get in both Sun 3 and Sun 4? 117) On a Sun 3, what are the mwm startup error messages about? 118) Are there problems making shared libraries on a Sun? 119) The OpenWindows server hangs when I popup a menu with Button 3. 120) Has anyone made shared libraries on an IBM RS/6000? 121) What is the error "Unaligned access in XmString" under Ultrix? 122) TOPIC: KEYSYMS 123) What is causing the messages "unknown keysym osfDown..."? 124) What happens if I can't install Motif Keysyms? 125) Why has OSF introduced Keysyms into Motif 1.1? 126) TOPIC: ICONS 127) How can I keep track of changes to iconic/normal window state? 128) How can I check if my application has come up iconic? 129) How can I start my application in iconic state? 130) How can an application iconify itself? 131) How can an application de-iconify itself? 132) TOPIC: MISCELLANEOUS 133)+ How do I controll the repeat rate on a SUN keyboard ?? 134) How can I identify the children of a manager widget? 135) How do I tell if a scrolled window's scrollbars are visible? 136) How can I programatically scroll a XmScrolledWindow in XmAUTOMATIC mode? 137) What functions can an application use to change the size or position of a widget? 138) What widgets should I use to get the look of push buttons, but 139)+ How do I obtain the size of a unmanaged shell widget? 140) Can I use XtAddTimeOut(), XtAddWorkProc(), and XtAddInput() with XtAppMainLoop()? 141) Why does XtGetValues() XmNx and XmNwidth return extremely large values. 142) Can I specify callback functions in resource files? 143) How do I specify a search path for ".uid" files? 144) XtGetValues() on XmNx and XmNy of my top level shell don't return the correct root window coordinates. How do I compute these? 145) Can I use XmGetPixmap() with widgets that have non-default visual types? 146) How can I determine the item selected in a option menu or a RadioBox? 147) What is the matter with Frame in Motif 1.2? 148) What is IMUG and how do I join it? 149) What is the X Professional Organization 150) How do I set the title of a top level window? 151) Can I use editres with Motif? 152) How can I put decorations on transient windows using olwm? 153) Why does an augment translation appear to act as replace for some widgets? 154) How do you "grey" out a widget so that it cannot be activated? 155) Why doesn't the Help callback work on some widgets? 156) Where can I get a Table widget? 157) Has anyone done a bar graph widget? 158) Does anyone know of a source code of a graph widget 159)+ Is there a help system available, such as in Windows 3? 160) Can I specify a widget in a resource file? 161) Why are only some of my translations are being installed? 162) Where can I get the PanHandler code? 163) What are these passive grab warnings? 164) How do I have more buttons than three in a box? 165) How do I create a "busy working cursor"? 166) Can I use the hourglass that mwm uses? 167) What order should the libraries be linked in? 168) How do I use xmkmf for Motif clients? 169) How do I make context sensitive help? 170) How do I debug a modal interaction? 171)+ How can I disable Drag and Drop in my Motif 1.2 client ? 172) Where can I get info on the Motif drag and drop protocol? 173) TOPIC: ACKNOWLEDGEMENTS If you have suggestions or corrections for any of these answers or any additional information, please send them directly to dealy@kong.gsfc.nasa.gov; the information will be included in the next revision (or possibly the one after that; thanks for the many suggestions which haven't been incorporated yet). The answers in this iteration are acknowledged to be partial. This posting is intended to be distributed at approximately the beginning of each month. The information contained herein has been gathered from a variety of sources. In many cases attribution has been lost; if you would like to claim responsibility for a particular item, please let us know. Conventions used below: telephone numbers tend to be Bell-system unless otherwise noted; prices on items are not included. copyright 1993 b.dealy ----------------------------------------------------------------------------- Subject: 0)* TOPIC: WHAT ARE OTHER RELEVANT NEWSGROUPS? [Last modified: Feb 93] Answer: This newsgroup is comp.windows.x.motif. The nearest related group is comp.windows.x. It also maintains an FAQ, which deals in all sorts of X, Xlib and Xt questions. Look there for answers to questions such as "How do I get a screendump of my application?", "where do I get X11R4,X11R5, X11R6", etc. Other groups which may have relevant information are comp.windows.x.pex, comp.windows.x.apps, comp.windows.x.intrinsics, comp.windows.news, comp.windows.misc and comp.windows.open-look. The intrinsics and open-look groups also have an FAQ. The newsgroup news.answers contains *lots* of FAQs (including this one). Look there for lots of info on everything. ----------------------------------------------------------------------------- Subject: 1) TOPIC: FTP ARCHIVES ----------------------------------------------------------------------------- Subject: 2) Is the FAQ list available for FTP anywhere? [Last modified: Dec 93] Answer: A number of FAQ's (including this one) are available for anonymous ftp at rtfm.mit.edu, under the directory pub/usenet. (Motif is under pub/usenet/comp.windows.x.motif and also under pub/usenet/comp/windows/x/motif) There is also a mail server called mail- server@rtfm.mit.edu. To retrieve a file send mail to the server with a subject or body similar to send usenet/comp.windows.x.motif/Motif_FAQ_(Part_1_of_5).Z This service is looked after by Jonathan Kamens (jik@rtfm.mit.edu). It has also been placed in contrib/Motif-FAQ at ftp://ftp.x.org/contrib/Motif-FAQ This files are also accessible from WAIS (Wide Area Information System) under UC-Motif-FAQ, allowing keyword-based searches of the FAQ. --------- -------------------------------------------------------------------- Subject: 3)+ Is this FAQ accessible via WWW? [Last modified: Dec 93] Answer: A simple version of the FAQ has been htmlized on news.answers But a more in-depth restructuring is under way and should be available soon at a web server near you. ----------------------------------------------------------------------------- Subject: 4) Is this newsgroup accessible via email? [Last modified: April 93] Answer: An email link is maintained by Brian Dealy. To join, send mail to motif-request@lobo.gsfc.nasa.gov. ----------------------------------------------------------------------------- Subject: 5) Is this newsgroup archived? [Last modified: November 1992] Answer: The newsgroup files from August 1991 are available from csc.canberra.edu.au (137.92.1.1) by anonymous ftp. They are in the directory /pub/motif/comp.windows.x.motif. These files are also accessible from WAIS (Wide Area Information System) under comp.windows.x.motif, allowing keyword-based searches of the newsgroup articles (this time on machine services.canberra.edu.au (137.92.1.12)). ----------------------------------------------------------------------------- Subject: 6) Is the mail list motif-talk archived? Answer: If you have purchased support from OSF then you have access to their archive server for motif-talk. ----------------------------------------------------------------------------- Subject: 7) TOPIC: OSF AND MOTIF ----------------------------------------------------------------------------- Subject: 8) Because of COSE, is Motif now in the public domain? Answer: The *specification* for Motif is no longer controlled by OSF, but by X/Open. This does not affect the *implementation*. The implementation is still in the hands of OSF, and will not be released into the public domain. So no, the OSF source code will still only be available to those who buy a source code license from OSF. The specification does not include UIL or obsolete features (ie 1.0 bugs in design), but these will continue to be supported by the OSF code. ----------------------------------------------------------------------------- Subject: 9)* What versions of Motif are there? [Last modified: March 93] Answer: Motif 1.0 is based on the R3 toolkit. There are patch releases to 1.0: 1.0.1, 1.0.A, 1.0.2 and 1.0.3, 1.0.4, 1.0.5. 1.0.A was a fairly major patch, as it involved a complete re-engineering of UIL and Mrm. Almost everyone who has 1.0.x has either 1.0.A or 1.0.3. Motif 1.1 is based on the R4 toolkit. The intial version was Motif 1.1.0. Motif 1.1.1 has been released as a patch to licensees with Full Support or Technical Update service. Motif 1.1.2 is a patch release which contains the necessary changes to fix over 80 bugs reported against Motif. It is available to support contract holders (including both full support and update service). The 1.1.3 release fixed a further 150 bugs and was available from August 1991 to support contract holders (including both full support and update service). 1.1.4 offers X11R5 support, but is not an X11R5 product. 1.1.5 was released in June 92 to licensees who hold a Motif Full Support or Update Support contract Motif 1.2.0 was released in April 1992 and is based on the X11R5 toolkit. It offers increased compatibility with international standards, PC-style behavior and binary compatibility with OSF/Motif 1.1 applications. New features include drag-and-drop, tear- off menus, toolkit enhancements and new documentation. toolkit. The code is totally ANSI C. OSF distributes a 10 pages sheet entitled "OSF/Motif R1.1 to R1.2: detailed overview of changes", which is available from OSF Motif direct channels. (617-621-7300 or email direct@osf.org) Motif 1.2.1 was released September 92. Due to an optimisation from 1.2.0 to 1.2.1 object code compiled under 1.2.1 (that is, using 1.2.1 header files) will not link with 1.2.0 libraries (and, very probably, clients that use shared libraries and are linked against 1.2.1 won't startup against 1.2). Motif 1.2.2 was released March 93. This release contains over 250 bug fixes, improved text, drag-and-drop features and has less than one reported defect per 1000 lines of code. from dbrooks@osf.org Motif 1.2.3 was released on September 13, 1993. The defect density is measured at < 0.8 known reports per thousand lines. In this release, we have paid particular attention to memory leaks, and have improved drag-and-drop performance greatly. ----------------------------------------------------------------------------- Subject: 10)* Where can I get Motif? [Last modified: APR 94] Answer: Various hardware vendors produce developer's toolkits of binaries, header files, and documentation; check your hardware vendor, particularly if that vendor is an OSF member. Systems known to be shipping now: HP (sans UIL), Apollo (sans UIL), SCO, ICS, Mips (RISCwindows=X11R3 + full Motif), IBM, Data General for AViioNs (includes UIL), Bull (?), Concurrent Computer Corporation 5000, 6000, 8000 series machines, Convex, Sequent. In addition, independent binary vendors produce Motif toolkits . [An FAQ is for "personal opinions" on these toolkits. I don't think it is appropriate to give such opinions through this particular posting, so I haven't included any.] Integrated Computer Solutions, Inc. (ICS) 201 Broadway, Cambridge, MA 02139 USA info@ics.com 617/621-0060 ICS provides binary distributions of Motif for Sun platforms. Other platforms are available as well, call or send mail for current info. ICS also provides in-depth programming support for Motif and additional tools such as Builder Xcessory, a Motif interface builder, and the Widget Databook, a source for third party, commercially available and supported widgets, class libraries, and subsystems. Quest (408-496-1900) sells kits for Suns, as well; IXI (+44 223 236 555) offers kits for Sun3 (SunOS 3.5 or later, and Sun4 (SunOS 4.0.1 or later). (Solaris 2.1 or later ( both SPARC and Intel )) ( both M1.1.5 and Motif 1.2.2 for SPARC, Motif 1.2.2 for Intel ). Sun Microsystems is now shipping a version of Motif also. NSL (+33 (1) 43 36 77 50; requests@nsl.fr) offers kits for the Sun 3 and Sun 4. In Australia, Information Technology Consultants Pty Ltd has Motif 1.1.2 for Sun Sparc 4.1 ( phone on (02) 360 6999, fax on (02) 360 6695 or e-mail to motif@itcsyd.itc.oz.au) SILOGIC (+33 61.57.95.95), 78 chemin des Sept Deniers - 31200 TOULOUSE FRANCE sells Motif 1.1 and 1.2 on Sun4 machines. They also provide customers with Motif maintenance and support, and do consulting on the X window System at large, including software development. METRO LINK INC., has Motif 1.2.3 and Motif 1.2.2 Runtime and Development packages available for a variety of operating systems. All versions ship with shared library version of libXm. Linux version includes free O'Reilly volume and FTP shipping option. Send mail to: Motif 1.2.3 (available Dec. 1, 1993) Linux 0.99, Solaris 2.x (SPARC), SunOS 4.1.x ---> $199.00 Solaris 2.1 (x86) ---> $299.00 Motif 1.2.2 Linux 0.99, Solaris 2.x (SPARC), SunOS 4.1.x ---> $199.00 QNX, SVR3, SVR4.[012], SCO, UnixWare, SINIX, LynxOS, Venix, ISC, NCR SVR4 MP ---> Under $299.00 Metro Link Incorporated. 2213 W. McNab Rd. Pompano Beach, Florida 33069 Voice: +1.305.970.7353x412 Fax: +1.305.970.7351 Email: ken@metrolink.com BIM (Fax : +32(2)759.47.95) offer Motif 1.1 for Sun-3, Sun-4, Sun-386i. Includes shared libraries. Metrolink Inc. (+1-305-566-9586, sales@metrolink.com; in Europe contact ADNT, (33 1) 3956 5333) ships an implementation of X11R4 and Motif 1.1 for several 386 systems. An OSF/Motif source license must be obtained from OSF before source can be obtained from the Open Software Foundation. Call the Direct Channel Desk at OSF at 617-621-7300 or email direct@osf.org for ordering information. Bluestone offers Motif for $99. Bluestone's MWM is the compiled version of OSF/ Motif for Sun/SPARC. It is plain vanilla Motif based on X11 and Xt Intrinsics. There is no license manager. Platforms: Sun/OS 4.1+ and Solaris V2.1,2.2. Contact: Bluestone @609-727-4600 In addition to the full Motif source, "option C" allows you to purchase source for the window manager mwm to run on X terminals. ----------------------------------------------------------------------------- Subject: 11) Is there a list of Motif bugs? Answer: With each patch release of Motif shipped, there is a list of known bugs provided. The filename on the tape is "./OPENBUGS". There is also a list of all the issues closed/resolved in that patch. That is found as part of the "./README-1.1.n" (where n is the patch number) file. These are the only OSF published lists. No-one else seems to publish a list. ----------------------------------------------------------------------------- Subject: 12) Where can I get public domain Motif source? Answer: You cannot. Motif source is not publically available. ----------------------------------------------------------------------------- Subject: 13)* Are the Motif examples publically available? [Last modified: DEC 93] Answer: OSF has produced a list of which of the example programs can be distributed. Call OSF Direct for a copy of it. Most of the example programs have been freed from distribution limitations so should be available. In addition to these, many programs on export.lcs.mit.edu in the contrib directory use Motif. Source code posted to comp.sources.x often uses Motif. The examples from Dan Heller's book are on export in /contrib/OReilly/motif/examples.tar.Z. The examples from Thomas Berlages's book are on export in /contrib/berlage.motif.tar.Z The examples from Donald L. McMinds's book are on export in /contrib/mastering.motif.tar.Z The examples from Jan Newmarch's book are export in /contrib/newmarch.tar.Z The examples from Jerry Smith's book are on export in contrib/smith.motif.tar.Z Also from a list maintained by: qizeng@acsu.buffalo.edu (Qi Y. Zeng) FTP sites for X/MOTIF source codes: ftp.uu.net published/brain.motif.tar.Z ftp.x.org contrib/young.C++.tar.Z ftp.x.org contrib/pwmxmpl.tar.Z ftp.x.org contrib/newmarch.tar.Z ora.com pub/examples/xresource skye.aiai.ed.ac.uk(192.41.104.6) pub/wxwin/wxwin150.tar.Z (UNIX) pub/wxwin/wxwin150.zip (PC) ----------------------------------------------------------------------------- Subject: 14)* Has anyone done a public domain Motif lookalike? [Last modified: March 93] Answer: Not yet. The specification is available (AES), and the validation suite can be bought, but no-one has taken up the challenge. There are some commercial lookalikes (Looking Glass and Neuron Data), but no workalikes. Applications that follow the Style Guide might be certified Motif-compliant through the checklist process, even though they're not using OSF/Motif binaries. Tcl/Tk is available for ftp from allspice.berkeley.edu, and although implemented without Xt, has a "strict Motif" mode. Strom Sytems (18666 Redmond Way o-2118, Redmond, WA 98052-6725) have a Simple Toolkit for X-Windows (sic) that appears to follow the Style Guide even though it doesn't quite look like Motif. MOOLIT is a USL product that can be runtime switched between the Sun Open Look and Motif appearance. It is based on OLIT 4i. Interviews is a C++ based product with appearance similar to Motif. A ftp- able version is on interviews.stanford.edu. A commercial version is available as InterViews Plus. ----------------------------------------------------------------------------- Subject: 15) Does anyone from OSF pay attention to our questions/suggestions? Answer: Yes, and they quite often post answers too. But they may not respond to *your* problem because they have other things to do as well. This newsgroup is not run by OSF, and has no formal connection with OSF. OSF is a member-driven company. The membership (and anyone can be a member) provides the primary input for future development of Motif. ----------------------------------------------------------------------------- Subject: 16) Does OSF have an application compliance validation service? Answer: They have a checklist and a certification process which you can request from them. Ask for the Level One Certification Checklist. The process is one of self-certification. It tests only the appearance and behavior of the application against Motif style. The product will also be put in the OSF reference listing. There's a one-time fee of $250. According to the master license agreement, you can't use any OSF identifying mark unless you have done a certification. ----------------------------------------------------------------------------- Subject: 17) What is the motif-talk mailing list? Answer: The motif-talk mailing list is only for those who have purchased a Motif source code license. You can be placed on this list by emailing to motif-talk-request@osf.org, citing your Company name and source license number. ----------------------------------------------------------------------------- Subject: 18) What MIT patches do I use, and when do I use fix-osf? Answer: The Motif 1.1.0 tape contains MIT patches 1-14. Apply these and any others you can get. If your MIT patch level only goes up to fix-16, you also need to apply fix-osf. Fix-osf was an emergency patch for a problem that existed when the Motif 1.1 tape was cut, The MIT fix-17 completely superseded osf-fix, so if you have applied fix-17 do not apply fix-osf. The 1.1.1 tape contains MIT fixes 15-18, as well as an OSF-developed fix that deals with a subtle bug in the Selection mechanism of the Intrinsics. Most people will have fix-15 to 18 by now; if you don't have them: Back out fix-osf if you have applied it Apply fix-15 to 18 Apply fix-osf-1.1.1 The Selection fix was submitted to MIT, who came up with a different fix. It will not be made into an R4 fix but should be in R5. The MIT fix was posted to motif-talk. ----------------------------------------------------------------------------- Subject: 19) How does Motif work with X11R5? Answer: Motif 1.1.X is only intended to be built with X11R4. Motif 1.2.X is for X11R5. however, Motif 1.1.4 has been set to also work with X11R5. For Motif 1.1.1, 1.1.2 and 1.1.3 you will need to compile Xlib and Xt with a MOTIFBC flag set to YES (page 8, section 3.3 of the R5 release notes), or you'll also have a link problem (LowerCase) and a fatal run time problem (XContext manager). If your applications come up with "Unknown keysym name: osfActivate" errors, check the variable ProjectRoot. The name /$PROJECTROOT/lib/XKeysymDB will have been wired into your Xlib. In Motif 1.1.0, XtCallCallback uses NULL as the first argument instead of a widget ID. This was ok under R4, but must be changed in the source for R5. It was changed by OSF from Motif 1.1.1 onward. Mrm won't work at all (can't link since it uses an X private variable that has disappeared in R5). Thre is an MIT patch that may fix this?? [I confess ignorance of Mrm and UIL]. ----------------------------------------------------------------------------- Subject: 20)* How can I find which version of Motif I have? [Last modified: October 93] Answer: The macro XmVERSION gives you the version number. The macro XmREVISION gives you the major revision number. The macro XmVersion combines these e.g. a value of 1002 is Motif 1.2. To find the minor revision number is not easy. From Motif 1.1.3 onwards, try this: 'strings `which mwm` | grep OSF'. to get the full version number e.g. 1.1.3. In Motif 1.2, the macro XmUPDATE_LEVEL was added to give the minor revision number. + ( above also known as the patch level). + In addition there was a macro string added, XmVERSION_STRING which has all + the above info in a char string. + grepping through a strings of libXm.a for OSF can also sometime give + something useful. Version X11R6 is due out in spring of 1994 (april 15?) thanks to hops@x.co.uk Mike Hopkirk ----------------------------------------------------------------------------- Subject: 21) TOPIC: LITERATURE ----------------------------------------------------------------------------- Subject: 22)* What books should I read or do I need to program using Motif? [Last modified: April 93] Answer: Ken Lee of the DEC Western Software Laboratory (klee@wsl.dec.com) regularly posts to comp.windows.x and ba.windows.x a list of reference books and articles on X and X programming. In FAQ comp.windows.x an extract of his list appears. Specifically for Motif programming, though: OSF/Motif Programmers Guide, Prentice-Hall ISBN 13-640525-8 (Motif 1.0), ISBN 0-13-640681-5 (Motif 1.1), ISBN 0-13-643107-0 (Motif 1.2) (NB: This makes use of the demo programs that you get with a Motif source license. The programs are not included and may or may not be available on your system.) OSF/Motif Programmers Reference Manual, Prentice-Hall ISBN 13-640517-17 (Motif 1.0), ISBN 0-13-640616-5 (Motif 1.1), ISBN 0-13-643115-1 (Motif 1.2) You will need this for the system calls. OSF/Motif Style Guide, Prentice-Hall 13-640491-X (Motif 1.0), ISBN 0-13- 640673-4 (Motif 1.1), ISBN 13-643123-2 (Motif 1.2) You will need this to get some idea of how to write programs with the correct `look and feel'. You should read at least one of the the non-OSF books on Motif: Sebern, Mark "Building OSF/Motif Applications: A Practical Introduction". The ISBN is 0-13-122409-3. Prentice-Hall. The book uses a large, realistic Motif application (a program to make slides for presentations) to demonstrate the use of Motif features. Both UIL and toolkit calls are discussed, though UIL is featured, both in the examples and in a reference chapter. Young, Doug. "The X Window System: Applications and Programming with Xt (Motif Version)," Prentice Hall, 1989 (ISBN 0-13-497074-8). The excellent tutorial "X Window Systems Programming and Applications with Xt," (ISBN 0-13-972167-3) updated for Motif. Marshall Brain at brain@adm.csc.ncsu.edu posted a set of simple and useful Motif tutorials. Berlage, Thomas Berlage, OSF/Motif: Concepts and Programming, Addison-Wesley, UK, 1991. ISBN 0-201-55792-4. Johnson, Eric F. and Kevin Reichard, Power Programming Motif, MIS: Press, Portland, OR, 1991. ISBN 1-55828-059-6. Book with disk, ISBN 1-55828-061-8. Ferguson, Paula M, The Motif Reference Manual, Volume 6B of the O'Reilly series on X. This is the new volume of a two volume set on Motif programming. ISBN 1-56592-038-4 (Motif 1.2) (Volume 6A is expected to ship soon) Barkakati, Nabajyoti, X Window System Programming, SAMS. ISBN 0-672-22750-9. This contains a section on Motif. Smith, Jerry, Designing X Clients with Xt/Motif, ISBN 1-55860-255-0 Morgan Kaufmann Publishers This adopts a higher-level approach to many of the objects that commonly occur in Motif but are not in the Motif API. Newmarch, Jan, The X Window System and Motif - A Fast Track Approach. Addison-Wesley, ISBN 0-201-53931-4. You will also need books and references on Xt such as: Asente, Paul J., and Swick, Ralph R., "X Window System Toolkit, The Complete Programmer's Guide and Specification", Digital Press, 1990. The bible on Xt. A treasury of information, excellent and invaluable. Distributed by Digital Press, ISBN 1-55558-051-3, order number EY-E757E-DP; and by Prentice- Hall, ISBN 0-13-972191-6. Nye, Adrian, and Tim O'Reilly, "X Toolkit Programming Manual, Volume 4," O'Reilly and Associates, 1989. The folks at O'Reilly give their comprehensive treatment to programming with the MIT Intrinsics; R4 versions are now available, as is a Motif 1.1 version (Volume 4M). Dan Heller's version of the Motif Programming Manual is still a widely used and useful book. It is being replaced by Volume 6a and 6b but is a very useful resource. Volume 6, Oreilly and Associates, Motif Edition. Flanagan, David, ed., "X Toolkit Reference Manual, Volume 5," O'Reilly and Associates, 1992a, Third Edition. A professional reference manual for the MIT X11R4 and X11R5 Xt. Books and reference manuals on Xlib may also be useful. If you want to learn about UIL, look in the Motif Programmers's Guide. This seems to be the only information. ----------------------------------------------------------------------------- Subject: 23) TOPIC: MWM ----------------------------------------------------------------------------- Subject: 24) What is the difference between Motif and mwm? Answer: mwm is a window manager. Motif itself is made up of four parts: a User-Interface Guideline, an API toolkit of `C' routines which helps in the building of applications which conform to the Guideline, the window manager mwm, and a language UIL which is designed to ease user interface development. In general mwm will run an application built with any X-windows API, and in general an application built using the Motif toolkit will run under any window manager. ----------------------------------------------------------------------------- Subject: 25) Does anyone have an alternative set of 3-D defaults for a monochrome screen? Answer: This is obviously a matter of taste. Some alternatives suggested include !Benjamin Schreiber, bs@osf.osf.org, bs@cs.brandeis.edu Mwm*foreground: black ! Actually, when a window is Mwm*background: white ! deactivated, the background Mwm*backgroundPixmap: 50_foreground ! becomes white, insted of Mwm*topShadowPixmap: white ! 50% foreground (grey) Mwm*activeForeground: black Mwm*activeBackground: white Mwm*activeBackgroundPixmap: 50_foreground Mwm*activeTopShadowPixmap: white Mwm*menu*backgroundPixmap: background Mwm*menu*topShadowPixmap: 50_foreground Mwm*title*foreground: black Mwm*title*background: white Mwm*title*backgroundPixmap: white Mwm*title*topShadowPixmap: 50_foreground Mwm*title*activeForeground: white Mwm*title*activeBackground: black Mwm*title*activeBackgroundPixmap: black Mwm*title*activeBottomShadowPixmap: 50_foreground Mwm*feedback*backgroundPixmap: white or ! From: tsang@isi.com (Kam C. Tsang) Mwm*background: White Mwm*activeBackground: White Mwm*activeBackgroundPixmap: 25_foreground Mwm*foreground: Black Mwm*activeForeground: Black Mwm*menu*background: white Mwm*menu*foreground: black xterm*Foreground: black xterm*Background: white or ! From: ucsd.edu!usc!snorkelwacker!paperboy!yee (Michael K. Yee) Mwm*cleanText: True Mwm*activeBackground: white Mwm*activeForeground: black Mwm*background: white Mwm*foreground: black Mwm*client*activeBackgroundPixmap: 50_foreground Mwm*client*activeTopShadowPixmap: foreground Mwm*client*activeBottomShadowPixmap: background !Mwm*client*background: white !Mwm*client*foreground: black Mwm*client*backgroundPixmap: 75_foreground Mwm*client*topShadowPixmap: foreground Mwm*client*bottomShadowPixmap: background !Mwm*feedback*background: white !Mwm*feedback*foreground: black Mwm*feedback*backgroundPixmap: 50_foreground !Mwm*feedback*topShadowPixmap: 25_foreground !Mwm*feedback*bottomShadowPixmap: background !Mwm*menu*background: white !Mwm*menu*foreground: black Mwm*menu*backgroundPixmap: foreground !Mwm*menu*topShadowPixmap: foreground !Mwm*menu*bottomShadowPixmap: background !Mwm*icon*background: white !Mwm*icon*foreground: black Mwm*icon*activeBackgroundPixmap: 50_foreground Mwm*icon*activeBottomShadowPixmap: foreground Mwm*icon*backgroundPixmap: 75_foreground ----------------------------------------------------------------------------- Subject: 26) How can I modify the Motif window manager decorations? Answer: In resource files, use the window manager's client resource (which is the application) and the resource clientDecoration: Mwm*XClock.clientDecoration: none turns off all clock decorations. See the mwm(1) entry for other possibilities. Programmatically, set the VendorShell resource XmNmwmDecorations to appropriate values: MWM_DECOR_NONE (or a bitwise or of values). ----------------------------------------------------------------------------- Subject: 27) How can I turn off the Motif window manager functions from the system menu? [Last modified: October 92] Answer: The user of an application can control functions in the system menu for an application using the mwm resource clientFunctions: mwm.application_name.clientFunctions: -resize -close Note that mwm will have to be restarted after putting this in their resource database. Answer: The writer of an application can only remove items. Be warned that your users will probably gnash their teeth, swear furiously at your product and stop using it if they discover that you have done this. (Especially if you have removed the Close button, your application has hung and it has taken up all of memory and swap so it can't be killed.) Much better is to catch the action gracefully as in the next question. #include XtVaGetValues(shell, XmNmwmFunctions, &int_val, NULL); int_val &= ~(MWM_FUNC_CLOSE | MWM_FUNC_ALL); XtVaSetValues(shell, XmNmwmFunctions, int_val, NULL); ----------------------------------------------------------------------------- Subject: 28) How can tell I if the user has selected the "Close" item on the system menu attached to the top-level shell? I need to do some clean up before exiting. [Last modified: May 93] Answer: This works with R4 Intrinsics #include void FinalCleanupCB(w, client_data, call_data) Widget w; caddr_t client_data, call_data; { /* tidy up stuff here */ ... /* exit if you want to */ exit (0); } main() { Atom wm_delete_window; ... XtRealizeWidget(toplevel); ... wm_delete_window = XmInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW", False); XmAddWMProtocolCallback(toplevel, wm_delete_window, FinalCleanupCB, NULL); XtMainLoop(); } This will still kill the application. To turn this behaviour off so that the application is not killed, set the shell resource XmNdeleteResponse to XmDO_NOTHING. This means that users cannot kill your application via the system menu, and may be a bad thing. If you are running R3, Bob Hays (bobhays@spss.com) has suggested this: "Trapping on the delete window atom does not work as I cannot force my action routine to the top of the action list for the activity desired, so the window manager kills my window anyway BEFORE I can do anything about it. And, to make matters worse, the window manager (Motif in this case) tacks its atoms and handlers onto the window at some unknown point down the line after the creation of the shell widget as far as I can tell. So.... I have a procedure as an action routine for ClientMessage. Then, if I get a property change event on the window manager protocols, I then tack on WM_SAVE_YOURSELF. If I get this request, I clean up (it seems to happen on WM_DELETE_WINDOW, BTW, if you remove WM_DELETE_WINDOW from the WM protocols atom) and exit. Works great and is less filling overall:-)." ----------------------------------------------------------------------------- Subject: 29) Is there an mwm virtual desktop manager? Answer: Peter E. Wagner (pew@cs.brown.edu): Imagine that your "desktop" extends beyond the view provided by your monitor. A virtual window manager gives you access to the space beyond your viewport (i.e. your screen) by allowing you to move the viewport to other areas of the extended desktop. The first one is Solbourne's swm, which spawned vtwm/tvtwm/olvwm. David B. Lewis created one. suresh@unipalm.co.uk has further developed it into the UniPalm product DOORS, which is only available as a source code extension to the MOTIF window manager. The price of the source and unlimited right to distribute binaries is 10,000 pounds Sterling. Alternately, source and right to use within one company is 2,000 pounds Sterling. Contact Peter Dawe Unipalm Limited Voice: +44 (0) 223 420002 216 The Science Park Fax: +44 (0) 223 426868 CAMBRIDGE CB4 4WA An enhancement request for such an object has been filed with OSF. ----------------------------------------------------------------------------- Subject: 30) Why does mwm 1.2 crash on startup? [Last modified: March 93] Answer: From David Brooks: The commonest cause of early mwm demise is as follows: - You, or someone, built Xlib in the default way using the Xsi internationalization functions. - Your Xlib wasn't installed completely (or at all). - Early on, mwm calls the function XmbTextListToTextProperty, which calls _XConvertMBToCT, which looks for the Xsi locale database, finds it missing, ignores this fact and tries to dereference zero. The workaround is to find the database *somewhere*, and point the environment variable XNLSPATH at it. For example, in my personal X source tree: setenv XNLSPATH /home/X11r5src/mit/lib/nls/Xsi ----------------------------------------------------------------------------- END OF PART ONE ----------------------------------------------------------------------------- Subject: 31) TOPIC: MOTIF GENERATORS ----------------------------------------------------------------------------- Subject: 32) What prototyping tools are there to generate Motif code? [Last modified: June 93] Answer: [An FAQ is for "personal opinions" on these tools. I don't think it is appropriate to give such opinions through this particular posting, so I haven't included any. I will include vendor-provided descriptions provided they are consise and informative] `Prototyping tools' come in two forms: those that can be used to design the interface only (GUI builder), and those that go beyond this to give support for application code (User Interface Management Systems). There are a number of commercial and non-commercial tools of both kinds that will support the Motif interface. They include: GUI builders: Builder Xcessory iXBUILD (formerly X Build) ExoCODE/xm MOTIFATION X-Designer Druid UIMS: WINTERP ALEX TAE Plus Widget Creation Library UIMX Serpent TeleUse XFaceMaker2 MetaCard ezX User Interface Management System Some contact addresses are: TAE Plus: Don Link, Century Computing, Inc. (301) 953-3330 tae-facts@cen.com TAE Plus is a mature, portable software development environment that supports rapid building, tailoring, and management of Motif-based graphical user interfaces. The code generator can produce C, C++ and Ada code and allows for merging regenerated code with previously modified parts of the interface. You an also generate a UIL/Mrm representation of your interface. Scripting capabilities are provided which facilitate automatic testing, on-line demos, and tutorials. A record and playback feature lets you build scripts simply by interacting with your GUI. A library of Dynamic Data Objects allows the user to create truly graphical objects whose dynamic portions can reflect data as well as be directly manipulated by the end-user. TAE Plus is available on virtually all the standard X platforms and comes with a wide array of support vehicles. (i.e., support office, newsletter, user's conference, etc.) WINTERP: You may obtain the current source, documentation, and examples via anonymous ftp from host export.lcs.mit.edu: in directory contrib/winterp you will find the compress(1)'d tar(1) file winterp.tar.Z. If you do not have Internet access you may request the source code to be mailed to you by sending a message to winterp-source%hplnpm@hplabs.hp.com or hplabs!hplnpm!winterp- source. Serpent: The S/W is free (anonymous ftp) from ftp.sei.cmu.edu. For more info contact erik/robert at serpent-info@sei.cmu.edu. This is no longer supported, and is apparently replaced by a commercial product called Alpha. TeleUSE: Built around X Windows and OSF/Motif, TeleUSE's comprehensive toolset gives you maximum control over every phase of graphical user interface development, including static screen layout and design, automatic implementation of callbacks, building the executable, and the interactive test, debug, and maintenance cycles. For more information, please contact: In North America and countries not specified below: Alsys (formerly TeleSoft) 10251 Vista Sorrento Parkway Suite 300 San Diego, CA 92121 USA (619) 457-2700 X244 (619) 452-1334 (fax) leigh@alsys.com In France: +33 1 47 66 21 83 In the UK: +49 491 579 090 In Scandinavia: +46 8 520 69010 In the Benelux: +31 15 62 21 21 In Germany: +49 7531 65022 In Italy: +39 6 5045 1 In Japan: +81 3 522 85620 In South Korea: +82 2 577 2044 Builder Xcessory from ICS. More details are available by sending a request to info@ics.com. Address: ICS Inc., 201 Broadway, Cambridge MA 02139, Tel. (617) 621-0060, Fax. (617) 621-9555 X-Designer: From Imperial Software Technology in the UK. Email address is sales@ist.co.uk. (+44) 743 587055 Recently, V.I. Corporation have become the distributor for the X-Designer product in the United States. In addition, IST and V.I. Corporation have developed a product called DVX-Designer that merges X-Designer with their GUI product called DataViews. Other merged products are in the works. For more information, people can contact: V.I. Corporation 47 Pleasant Street Northampton, MA 01060 Phone: (413) 586-4144 Fax: (413) 586-3805 Email: vi@vicorp.com ExoCODE/xm: From Expert Object Corp., 7250 Cicero Avenue, Lincolnwood, IL 60646 (708)676-5555. X Build: iXOS Software GmbH, Bretonischer Ring 12, 8011 Grasbrunn/Munich, Germany, email support@ixos.de or office@ixos.de, phone ++49-89-46005 0 or in the US UniPress Software, 2025 Lincoln Hwy., Edison, NJ 08817, phone 1-800-222-0550 ExoCode: From EXOC (Chicago, IL) UIMX: Visual Edge Software Limited, 3870 Cote Vertu, St Laurent, Quebec, H4R 1V4, Phone: (514) 332-6430, Fax: (514) 332-5914, or: Visual Edge Software Ltd., 101 First Street, Suite 443, Los Altos, CA 94022, Phone: (415) 948-0753, Fax: (415) 948-0843 The Widget Creation Library: The distribution is available in several ways. The preferred approach it for you to get the compressed tar file using anonymous ftp from: export.lcs.mit.edu (18.30.0.238) /contrib/Wcl.1.06.tar.Z XFaceMaker2: NSL - Non Standard Logics S.A., 57-59, rue Lhomond, 75005 Paris - France, Phone: +33 (1) 43.36.77.50, Fax: +33 (1) 43.36.59.78 email: requests@nsl.fr or requests%nsl.fr@inria.fr for information. Their North American office: Non Standard Logics, Inc., 4141 State Street, Suite B-11, Santa Barbara CA 93110, Tel: 805 964 9599, Fax: 805 964 4367 MOTIFATION: PEM GmbH, Vaihinger Strasse 49, 7000 Stuttgart 80, Germany, Tel: +49 (0) 711 713045, Fax: +49 (0) 711 713047 Email: basien@pem-stuttgart.de. Available for (Motif 1.2/1.1) on SunOS, Solaris 2.1, HP, Interactive, ODT 3.0, Silicon Graphics, PCS, ... ALEX: For more information contact Michael Karliner on (+44) 81 566 2307 or E-mail to alex@s-strat.co.uk. ALEX Technologies, Waterman's Yard, 32a The Mall, Ealing, London W5, UK. MetaCard: MetaCard 1.0 is supported on five popular UNIX/X11 platforms: SPARC, Sun3, DECstation, HP-9000/300, and SCO ODT. An HP-9000/700 port is underway and should be available by the end of July. [They] plan to support IBM RS/6000, SGI Iris, and DG AViiON sometime fall '92. For more information, or to receive a free save-disabled but licensable copy of MetaCard, email to info@metacard.com or call 303- 447-3936. If you have anonymous FTP access to the Internet, you can download the current engines, documentation, and an unlicensed Home stack from ftp.metacard.com (128.138.213.21), directory MetaCard. Commercial users can get MetaCard from world.std.com (192.74.137.5), directory pub/Metacard. If you don't have an anonymous ftp access, you can also download MetaCard from The World using kermit or xmodem from the ~ftp/pub/MetaCard directory. Sign up by calling 617-739-0202 (voice) or via modem by dialing 617-739-9753 (7 bits even parity) and logging in as new. MetaCard 1.2 Beta 5 is now available for anonymous FTP from ftp.metacard.com (directory MetaCard/1.2B5), and ftp.uu.net (directory vendor/MetaCard/1.2B5). There is also a MetaCard mailing list. To subscribe to the metacard-list, send mail to listserv@grot.starconn.com with the following commands in the body of the message: subscribe metacard-list firstname lastname quit Replace "firstname lastname" with your name, not your e-mail address. ezX User Interface Management System Sunrise Software, International 170 Enterprise Center Middletown, RI 02840 401-847-7868 email: support@sunrise.com WKSH (Windowing Korn Shell): EXtensible Korn Shell (C language calling interface, dynamic library loading, etc.) Motif or OpenLook API X Toolkit Intrinsics WKSH Convenience Functions Fast Learning and Prototyping Feature (ksh interpreter) Contact: Acacia Computer, PO Box 4376, Warren, NJ 07059, Phone: 908 548 6955, Email: uunet!aca1 or Computer Aid Inc, 1-(800)-444-WKSH or Consensys Corp, Europe: +(44)-734-833241 (Roger Chalke), +(44)0734-835391 (Fax), US: (416)-940-2903, (416)-940-2903 (Fax). WKSH was developed by USL. Binaries are available through Acacia Computer for SUNOS, Solaris, SCO ODT, Intel SVR4.0 Druid is a commercial product. It currently supports Motif1.1 and 4 unix platforms: SPARC, HP 9000, RS6000, and SGI. For further information contact: Mr. Fred Lee, Automated Systems (Pte) Limited, 203 Henderson Road, #12-07/14, Henderson Industrial Park, Singapore 0315. FAX: (65)272-2029 Or: Dr. Gurminder Singh (gsingh@iss.nus.sg), Institute of Systems Science, National University of Singapore ----------------------------------------------------------------------------- Subject: 33) TOPIC: TEXT WIDGET ----------------------------------------------------------------------------- Subject: 34) What is the difference between a XmTextField widget and a single line XmText widget? Answer: Their functionality is the same, but the XmTextField is designed to give superior performance. thanks to Ken Lee, klee@synoptics.com ----------------------------------------------------------------------------- Subject: 35) Why does pressing in a text widget do nothing? This happens using Motif 1.0 when I have a text widget inside a bulletin board (or form) inside a dialog shell. (In Motif 1.1 it is fixed for both text and list widgets.) Answer: In single line mode, pressing the key usually invokes the activate() action, and in multi-line mode, the newline() action. However, whenever a widget is the child of a bulletin board widget which is the child of a dialog shell, the bulletin board forces all of its children to translate to the bulletin board action Return() which is usually associated with the default button of the dialog. To restore the text actions of activate() or newline(), you need to overide the Return() action of the bulletin board. /* declarations */ /* for a single line widget */ char newTrans[] = "Return : activate()"; /* for a multi line widget */ char newTrans[] = "Return : newline()"; XtTranslations transTable; /* in executable section */ transTable = XtParseTranslationTable(newTrans); /* after creating but before managing text widget */ XtOverrideTranslations(textWidget, transTable); ----------------------------------------------------------------------------- Subject: 36) When I add text to a scrolling text widget how can I get the new text to show? Answer: Use the call undocumented in Motif 1.0 void XmTextShowPosition(w, position) Widget w; XmTextPosition position; where the position is the number of characters from the beginning of the buffer of the text to be displayed. If you don't know how many characters are in the buffer, use another call undocumented in Motif 1.0 position = XmTextGetLastPosition(w) ----------------------------------------------------------------------------- Subject: 37) Does the text widget support 16 bit character fonts? [Last modified: November 92] Answer: R5 has support for 16 bit character sets, and Motif 1.2 uses that. Neither Motif 1.0 nor 1.1 support 16 bit sets. ----------------------------------------------------------------------------- Subject: 38) How can I stop the text widget from echoing characters typed? I need to turn off echo for password input. Answer: Use the modifyVerifyCallback to tell when input is received. Set the `doit' field in the XmTextVerifyCallbackStruct to False to stop the echo. In Motif 1.0 this will cause a beep per character: Live with it, because at 1.1 you can turn it off. Note that password hiding is inherently insecure in X - someone may have an X grab on the keyboard and be reading all characters typed in anyway. Another solution often proposed is to set the foreground and background colours to be the same, effectively hiding the text. This has a major flaw: someone may select the text (triple click the mouse to get the line), and then paste the password into say an xterm with *different* foreground and background colours. This immediately shows the password. ----------------------------------------------------------------------------- Subject: 39) How can I replace characters typed with say a `*'? I want to replace input for password entry. [Last modified: April 93] Answer: In Motif 1.1 Use the modifyVerifyCallback to tell when input is received. Set text->ptr in the callback structure to '*'. This does not work under 1.0 because of an oversight in which changes to this are ignored. In Motif 1.0, what you can do is set the doit flag to 'false' so the text is not displayed. Then set a static boolean to True to prevent re-entrance. Next call XmTextReplace() to display your '*'. then reset your re-entrance flag to False. XmTextReplace() will call the XmNmodifyVerify callback. To prevent getting into an infinite loop, you need the re-entrance flag. The following program from Dan Heller illustrates this: -------------- /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates. * This program is freely distributable without licensing fees and * is provided without guarantee or warranty expressed or implied. * This program is -not- in the public domain. This program appears * in the Motif Programming Manual, O'Reilly Volume 6. */ /* passwd.c -- prompt for a passwd. Meaning, all input looks like * a series of *'s. Store the actual data typed by the user in * an internal variable. Don't allow paste operations. Handle * backspacing by deleting all text from insertion point to the * end of text. */ #include #include #include #include void check_passwd(); char *passwd; /* store user-typed passwd here. */ main(argc, argv) int argc; char *argv[]; { Widget toplevel, text_w, rowcol; XtAppContext app; toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); rowcol = XtVaCreateWidget("rowcol", xmRowColumnWidgetClass, toplevel, XmNorientation, XmHORIZONTAL, NULL); XtVaCreateManagedWidget("Password:", xmLabelGadgetClass, rowcol, NULL); text_w = XtVaCreateManagedWidget("text_w", xmTextWidgetClass, rowcol, NULL); XtAddCallback(text_w, XmNmodifyVerifyCallback, check_passwd, NULL); XtAddCallback(text_w, XmNactivateCallback, check_passwd, NULL); XtManageChild(rowcol); XtRealizeWidget(toplevel); XtAppMainLoop(app); } void check_passwd(text_w, unused, cbs) Widget text_w; XtPointer unused; XmTextVerifyCallbackStruct *cbs; { char *new; int len; if (cbs->reason == XmCR_ACTIVATE) { printf("Password: %s\n", passwd); return; } if (cbs->text->ptr == NULL) { /* backspace */ cbs->endPos = strlen(passwd); /* delete from here to end */ if (cbs->endPos <= 0) return; /* catch null passwd - Mark Scoville */ passwd[cbs->startPos] = 0; /* backspace--terminate */ return; } if (cbs->text->length > 1) { cbs->doit = False; /* don't allow "paste" operations */ return; /* make the user *type* the password! */ } new = XtMalloc(cbs->endPos + 2); /* new char + NULL terminator */ if (passwd) { strcpy(new, passwd); XtFree(passwd); } else new[0] = NULL; passwd = new; strncat(passwd, cbs->text->ptr, cbs->text->length); passwd[cbs->endPos + cbs->text->length] = 0; for (len = 0; len < cbs->text->length; len++) cbs->text->ptr[len] = '*'; } ----------------------------------------------------------------------------- Subject: 40) How can I best add a large piece of text to a scrolled text widget? In some versions of Motif 1.0 even using XmTextSetString, it insists on adding the text one line at a time, adjusting the scroll bar each time. It looks awful and is slow. Answer: If you don't have this problem, use XmTextSetString to set all of the text in the widget. If you do have this slowdown problem even using XmTextSetString, unmanage the widget, add the text and then manage it again. This may cause the window to blink, but you have to put up with that or switch to a different version of Motif. ----------------------------------------------------------------------------- Subject: 41) How can I highlight text in the Text widget? Answer: From: argv@zipcode.com (Dan Heller) If you don't need font or color changes, you can do all this using a Text widget very easily [in Motif 1.1, anyway]. loop() { pos = offset_of_pattern_in_text_widget(pattern, text_w); search_len = strlen(pattern); XmTextSetHighlight(text_w, pos, pos+search_len, XmHIGHLIGHT_SELECTED); } There are two choices for highlighting: reverse video (HIGHLIGHT_SELECTED) and underlined (HIGHLIGHT_SECONDARY_SELECTED). Be careful that your users won't confuse your highlights with actual selections! ----------------------------------------------------------------------------- Subject: 42) How can I select all of the text in a widget programmatically? So that some initial text is displayed, but anything typed replaces it. Answer: XmTextSetSelection(Text1, 0, XmTextGetLastPosition(Text1), event- >xbutton.time); where Text1 is the widget in question (obviously) and event is some event that triggered this call. You can use XtLastTimestampProcessed( display) instead of xbutton.time if you don't happen to have an event pointer handy. ----------------------------------------------------------------------------- Subject: 43) How can I change colours of text in the Text widget? I want some of the text in one colour, some in another. Answer: You can't. Text stores an ordinary string, and points where `highlights' of various types begin and end. These highlights are all the control you have over components of the text. See the previous question. ----------------------------------------------------------------------------- Subject: 44) How can I change the font of text in the Text widget? I want some of the text in one font, some in another. Answer: You can't in Text (see the previous question). If you wanted readonly text, you could do it by using a label instead. Label uses XmStrings, which can contain multiple character sets in the one string. ----------------------------------------------------------------------------- Subject: 45) Is there an emacs binding for the text widget? Answer: This set is due to Kee Hinckley (nazgul@alfalfa.com): *XmText.translations: #override\n\ Ctrl b: backward-character()\n\ Alt b: backward-word()\n\ Meta b: backward-word()\n\ Shift Alt b: backward-word(extend)\n\ Shift Meta b: backward-word(extend)\n\ Alt [: backward-paragraph()\n\ Meta [: backward-paragraph()\n\ Shift Alt [: backward-paragraph(extend)\n\ Shift Meta [: backward-paragraph(extend)\n\ Alt <: beginning-of-file()\n\ Meta <: beginning-of-file()\n\ Ctrl a: beginning-of-line()\n\ Shift Ctrl a: beginning-of-line(extend)\n\ Ctrl osfInsert: copy-clipboard()\n\ Shift osfDelete: cut-clipboard()\n\ Shift osfInsert: paste-clipboard()\n\ Alt >: end-of-file()\n\ Meta >: end-of-file()\n\ Ctrl e: end-of-line()\n\ Shift Ctrl e: end-of-line(extend)\n\ Ctrl f: forward-character()\n\ Alt ]: forward-paragraph()\n\ Meta ]: forward-paragraph()\n\ Shift Alt ]: forward-paragraph(extend)\n\ Shift Meta ]: forward-paragraph(extend)\n\ Ctrl Alt f: forward-word()\n\ Ctrl Meta f: forward-word()\n\ Ctrl d: kill-next-character()\n\ Alt BackSpace: kill-previous-word()\n\ Meta BackSpace: kill-previous-word()\n\ Ctrl w: key-select() kill-selection()\n\ Ctrl y: unkill()\n\ Ctrl k: kill-to-end-of-line()\n\ Alt Delete: kill-to-start-of-line()\n\ Meta Delete: kill-to-start-of-line()\n\ Ctrl o: newline-and-backup()\n\ Ctrl j: newline-and-indent()\n\ Ctrl n: next-line()\n\ Ctrl osfLeft: page-left()\n\ Ctrl osfRight: page-right()\n\ Ctrl p: previous-line()\n\ Ctrl g: process-cancel()\n\ Ctrl l: redraw-display()\n\ Ctrl osfDown: next-page()\n\ Ctrl osfUp: previous-page()\n\ Ctrl space: set-anchor()\n ! If you'd like the Delete key to work like backspace instead of deleting ! backwards, add the following definition to the lines above. ! osfDelete: delete-previous-character()\n\ ! These aren't included because they could intefere with | menu accelerators (or vice versa) ! Alt p: backward-paragraph()\n\ ! Meta p: backward-paragraph()\n\ ! Shift Altp: backward-paragraph(extend)\n\ ! Shift Metap: backward-paragraph(extend)\n\ ! Alt w: copy-clipboard()\n\ ! Meta w: copy-clipboard()\n\ ! Ctrl Alt w: cut-clipboard()\n\ ! Ctrl Meta w: cut-clipboard()\n\ ! Alt y: paste-clipboard()\n\ ! Meta y: paste-clipboard()\n\ ! Alt f: forward-word()\n\ ! Meta f: forward-word()\n\ ! Alt n: forward-paragraph()\n\ ! Meta n: forward-paragraph()\n\ ! Shift Alt n: forward-paragraph(extend)\n\ ! Shift Meta n: forward-paragraph(extend)\n\ ! Shift Alt f: forward-word(extend)\n\ ! Shift Meta f: forward-word(extend)\n\ ! Alt d: kill-next-word()\n\ ! Meta d: kill-next-word()\n\ ! Alt h: select-all()\n\ ! Meta h: select-all()\n\ Similar sets of translations have been suggested by others. ----------------------------------------------------------------------------- Subject: 46) How can I use a file as the text source for a Text widget? Answer: You can't do it directly like you can with the Athena Text widget. Instead, read the text from the file into a string (all of it!) and then use XmTextSetString. Alternatively, read blocks of characters and add them at the end of the text using XmTextInsertString. The following is an excerpt from Dan Heller's "file_browser.c": /* file_browser.c -- use a ScrolledText object to view the * contents of arbitrary files chosen by the user from a * FileSelectionDialog or from a single-line text widget. */ ... struct stat statb; /* make sure the file is a regular text file and open it */ if (stat(filename, &statb) == -1 || (statb.st_mode & S_IFMT) != S_IFREG || !(fp = fopen(filename, "r"))) { if ((statb.st_mode & S_IFMT) == S_IFREG) perror(filename); /* send to stderr why we can't read it */ else fprintf(stderr, "%s: not a regular file0, filename); XtFree(filename); return; } /* put the contents of the file in the Text widget by allocating * enough space for the entire file, reading the file into the * allocated space, and using XmTextFieldSetString() to show the file. */ if (!(text = XtMalloc((unsigned)(statb.st_size+1)))) { fprintf(stderr, "Can't alloc enough space for %s", filename); XtFree(filename); fclose(fp); return; } if (!fread(text, sizeof(char), statb.st_size+1, fp)) fprintf(stderr, "Warning: may not have read entire file!0); text[statb.st_size] = 0; /* be sure to NULL-terminate */ /* insert file contents in Text widget */ XmTextSetString(text_w, text); ----------------------------------------------------------------------------- Subject: 47) How can put Text in overstrike mode instead of insert? Answer: There is no direct way. This was posted by Edmond Pitt (ejp@bohra.cpg.oz) The correct answer to the question is to put the following in a modifyVerify callback, where 'mvcb' is the XmTextVerifyCallbackStruct, and 'overstriking' is defined by you: if (overstriking && mvcb->text->length == 1) { _XmTextDisableRedisplay(w,FALSE); XtCallActionProc(w,"delete-next-character",mvcb->event,0); _XmTextEnableRedisplay(w); } _XmText{Dis,En}ableRedisplay() are XmText{Dis,En}ableRedisplay() in 1.0, but X11R3 has no XtCallActionProc() anyway. For this environment you need my 1.0.3 Text widget patches posted last year & available on request. ----------------------------------------------------------------------------- Subject: 48) How can I make the Delete key do a backspace? Answer: Put this in your .Xdefaults *XmText.translations: #override osfDelete: delete-previous-character() ----------------------------------------------------------------------------- Subject: 49) TOPIC: LIST WIDGET ----------------------------------------------------------------------------- Subject: 50) Should I create an XmList widget as a child of automatic XmScrolledWindow or use the XmCreateScrolledList() convenience function? Answer: With most implementations, the convenience function use internal hooks to give somewhat better scrolling performance. thanks to Ken Lee, klee@synoptics.com ----------------------------------------------------------------------------- Subject: 51) How do I best put a new set of items into a list? Answer: Set the new list count and list by XtSetArgs and install them by XtSetValues. XmString list[SIZE]; int list_size; XtSetArg (args[n], XmNitemCount, list_size); n++; XtSetArg (args[n], XmNitems, list); n++; XtSetValues (w, args, n); Each time the list is reset by this the old contents are freed by the widget and the new supplied list is copied. Do *not* free the old list of items yourself as this would result in the space being freed twice. It is not necessary to remove the items one at a time, nor to "zero" out the list first. ----------------------------------------------------------------------------- Subject: 52) Can I have strings with different fonts in a list? Answer: Yes. The strings are XmStrings. Each one can be created using a different character set using a different font. ----------------------------------------------------------------------------- Subject: 53) Can I get a bitmap to show in a list item like I can in a Label? I want to place a bitmap along with some normal text in my list items. Answer: No. The list contains XmStrings, and these only allow text in various character sets. The workaround is to define your font containing the icons you want. Then you can create a fontlist containing your icon font and the font you want the text in, and then make your items multi-segment XmStrings where the first segment contains the code of the icon you want with a charset that matches the icon font in your fontlist and the second segment with a charset matching the text font. ----------------------------------------------------------------------------- Subject: 54) Can I have items with different colours in a list? Answer: No. The list contains XmStrings, and these only allow text in various character sets. Since the items are XmStrings, you can already change the font of an item by replacing it with an item with the same text and a different charset tag. Adding support for color would require modification of the internal data structure in XmList as well as modification to the drawing routines. A possible workaround is to use a rowcolumn of buttons which can be individually set. However, you would have to do all list functionality yourself. ----------------------------------------------------------------------------- Subject: 55) Can I grey out an item in a list? I want to make insensitive items in a list so that they cannot be selected. Answer: From W. Scott Meeks of OSF: Unfortunately, you can't do it directly since the list items aren't individual widgets. We've had other requests for this technology, but it didn't make the cut for 1.2; it should be in some future release. However, you can probably fake it in your application with some difficulty. First, a list item is an XmString, so you can specify a different charset for the item than for other items in the list and then specify a font in the list's fontlist that matches the charset and gives you the visual you want. The next problem is making the item unselectable. One idea would be to have the application keep track of the insensitive items and the items currently selected. Then you would set up a selection callback that when called would check the item selected against the list of insensitive items and if the selected item matched would deselect that item and reselect the previously selected items. Otherwise it would just update the application's list of selected items. The major drawback with this approach is that you'll get flashing whenever the list selects an item and your application immediately de-selects. Unfortunately I can't think of a way around this without mucking with the list internals. Another alternative suggested is to use instead a column of say read only text widgets which you can make insensitive. ----------------------------------------------------------------------------- Subject: 56) Can I have multi-line items in a list? [Last modified: August 92] Answer: Motif 1.0 and 1.1 both have problems with multi-line items in a list. They should work okay in Motif 1.2. ----------------------------------------------------------------------------- Subject: 57) How can I tell the position of selected items in a list? [Last modified: Oct 92] Answer: From W. Scott Meeks: 1) All XmList selection callbacks get an XmListCallbackStruct which includes the item selected and its position. In addition, the multiple and extended selection callbacks also get a list of the selected items. This approach requires that your application saves this information if you need it outside of the immediate callback. 2) At any time you can XtGetValues the XmNselectedItems and XmNselectedItemCount resources. The problem with this approach is that identical items may or may not show up in multiple times in this list and the position in the selectedItems list may not relate directly to the position in the items list. 3) You can call XmListGetSelectedPos on the list widget. This will return a list of the positions of all selected items. ----------------------------------------------------------------------------- Subject: 58) TOPIC: FILE SELECTION BOX WIDGET ----------------------------------------------------------------------------- Subject: 59) What is libPW.a and do I need it? My manual says I need to link in libPW.a to use the File Selection Box. I can't find it on my system. Answer: The libPW.a is the Programmers Workbench library which is an ATT product not included in Berkeley based systems, hence it is not found in SunOS or Ultrix, but is found on HP-UX (a Berkeley/ATT hybrid which chose ATT in this case). It contains the regex(3) routines (regcmp, regex). Some systems which don't have these in the libc.a need to link with -lPW. Some systems which have the regex(3) routines in there also have the libPW.a. If you have regex(3) in libc, and it works, don't link with libPW. If you don't have regex(3) in libc, and you don't have a libPW, then check some sites on the net for public domain replacements (several exist), or call your vendor. In most versions of Motif (see the doco), you can compile FileSB.c with -DNO_REGEX if you don't have it. ----------------------------------------------------------------------------- Subject: 60) What are these compile errors: Undefined symbol _regcmp and _regex? Answer: You need to link in the libPW library - see previous question. ----------------------------------------------------------------------------- Subject: 61) What's wrong with the Motif 1.0 File Selection Box? I can't set the directory, change the directory or get the file mask to work. Answer: The 1.0 File Selection Box is broken, and these don't work. They weren't fixed until Motif 1.04. Use these later versions of 1.0 or switch to Motif 1.1 where it changed a lot. Joe Hildebrand has a work-around for some of this: Before popping up an XmFileSelectionDialog, change to the directory you want. When a file is selected, check if it is a directory, so that we can change to it. i.e. static void show_file_box_CB(w, client_data, call_data) Widget w; Widget client_data; XmAnyCallbackStruct *call_data; { chdir("/users/hildjj/files"); XtManageChild(client_data); } static void val_save(w, client_data, call_data) Widget w; Widget client_data; XmSelectionBoxCallbackStruct *call_data; { struct stat buf; /* struct stat is defined in stat.h */ char *filename; /* get the file name from the FileSelectionBox */ filename = SmX(call_data->value); /* get the status of the file named filename, and put it into buf */ if (!stat(filename, &buf)) { /* if it's a directory */ /* if it's a directory */ if(S_ISDIR(buf.st_mode)) { /* change to that directory, and update the FileSelectionBox */ chdir(filename); XmFileSelectionDoSearch(w, NULL); } else /* if it's a regular file */ if(S_ISREG(buf.st_mode)) /* ask if it should be overwritten */ XtManageChild(valbox); else /* it's another kind of file. What type, i can't think of, but it might happen */ pop_up_error_box(client_data, "Error saving file"); } else /* we couldn't get the file status */ { /* if it's because the file doesn't exist, we're golden */ if (errno == ENOENT) save_file(); else /* there is some other problem getting the status. e.g. bad path */ pop_up_error_box(client_data, "Error saving file"); } } this still doesn't implement the file masking stuff. ----------------------------------------------------------------------------- END OF PART TWO ----------------------------------------------------------------------------- Subject: 62) TOPIC: FORM WIDGET ----------------------------------------------------------------------------- Subject: 63) Why don't labels in a Form resize when the label is changed? I've got some labels in a form. The labels don't resize whenever the label string resource is changed. As a result, the operator has to resize the window to see the new label contents. I am using Motif 1.1. Answer: This problem may happen to any widget inside a Form widget. The problem was that the Form will resize itself when it gets geometry requests from its children. If its preferred size is not allowed, the Form will disallow all geometry requests from its children. The workaround is that you should set any ancestor of the Form to be resizable. For the shell which contains the Form you should set the shell resource XmNallowShellResize to be True (by default, it is set to FALSE). There is currently an inconsistency on how resizing is being done, and it may get fixed in Motif 1.2. From db@sunbim.be (Danny Backx) Basically what you have to do is set the XmNresizePolicy on the Form to XmRESIZE_NONE. The facts seem to be that XmRESIZE_NONE does NOT mean "do not allow resizes". You may also have to set XmNresizable on the form to True. ----------------------------------------------------------------------------- Subject: 64) How can I center a widget in a form? Answer: One of Motif's trickier questions. The problems are that: Form gives no support for centering, only for edge attachments, and the widget must stay in the center if the form or the widget is resized. Just looking at horizontal centering (vertical is similar) some solutions are: a. Use the table widget instead of Form. b. A hack free solution is from Dan Heller: /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates. * This program is freely distributable without licensing fees and * is provided without guarantee or warranty expressed or implied. * This program is -not- in the public domain. This program is * taken from the Motif Programming Manual, O'Reilly Volume 6. */ /* corners.c -- demonstrate widget layout management for a * BulletinBoard widget. There are four widgets each labeled * top-left, top-right, bottom-left and bottom-right. Their * positions in the bulletin board correspond to their names. * Only when the widget is resized does the geometry management * kick in and position the children in their correct locations. */ #include #include char *corners[] = { "Top-Left", "Top-Right", "Bottom-Left", "Bottom-Right", }; static void resize(); main(argc, argv) int argc; char *argv[]; { Widget toplevel, bboard; XtAppContext app; XtActionsRec rec; int i; /* Initialize toolkit and create toplevel shell */ toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); /* Create your standard BulletinBoard widget */ bboard = XtVaCreateManagedWidget("bboard", xmBulletinBoardWidgetClass, toplevel, NULL); /* Set up a translation table that captures "Resize" events * (also called ConfigureNotify or Configure events). If the * event is generated, call the function resize(). */ rec.string = "resize"; rec.proc = resize; XtAppAddActions(app, &rec, 1); XtOverrideTranslations(bboard, XtParseTranslationTable(": resize()")); /* Create children of the dialog -- a PushButton in each corner. */ for (i = 0; i < XtNumber(corners); i++) XtVaCreateManagedWidget(corners[i], xmPushButtonGadgetClass, bboard, NULL); XtRealizeWidget(toplevel); XtAppMainLoop(app); } /* resize(), the routine that is automatically called by Xt upon the * delivery of a Configure event. This happens whenever the widget * gets resized. */ static void resize(w, event, args, num_args) CompositeWidget w; /* The widget (BulletinBoard) that got resized */ XConfigureEvent *event; /* The event struct associated with the event */ String args[]; /* unused */ int *num_args; /* unused */ { WidgetList children; int width = event->width; int height = event->height; Dimension w_width, w_height; short margin_w, margin_h; /* get handle to BulletinBoard's children and marginal spacing */ XtVaGetValues(w, XmNchildren, &children, XmNmarginWidth, &margin_w, XmNmarginHeight, &margin_h, NULL); /* place the top left widget */ XtVaSetValues(children[0], XmNx, margin_w, XmNy, margin_h, NULL); /* top right */ XtVaGetValues(children[1], XmNwidth, &w_width, NULL); /* To Center a widget in the middle of the BulletinBoard (or Form), * simply call: * XtVaSetValues(widget, XmNx, (width - w_width)/2, XmNy, (height - w_height)/2, NULL); * and return. */ XtVaSetValues(children[1], XmNx, width - margin_w - w_width, XmNy, margin_h, NULL); /* bottom left */ XtVaGetValues(children[2], XmNheight, &w_height, NULL); XtVaSetValues(children[2], XmNx, margin_w, XmNy, height - margin_h - w_height, NULL); /* bottom right */ XtVaGetValues(children[3], XmNheight, &w_height, XmNwidth, &w_width, NULL); XtVaSetValues(children[3], XmNx, width - margin_w - w_width, XmNy, height - margin_h - w_height, NULL); } c. No uil solution has been suggested, because of the widget size problem ----------------------------------------------------------------------------- Subject: 65) How do I line up two columns of widgets of different types? I have a column of say label widgets, and a column of text widgets and I want to have them lined up horizontally. The problem is that they are of different heights. Just putting them in a form or rowcolumn doesn't line them up properly because the label and text widgets are of different height. If you want the geometry to look like this ------------------------------------- | -------------------------- | |a label |Some text || | -------------------------- | ------------------- | |a longer label |Some more text || | ------------------- | | ---------------- | |a very long label |Even more text || | ---------------- | ------------------------------------- try /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates. * This program is freely distributable without licensing fees and * is provided without guarantee or warranty expressed or implied. * This program is -not- in the public domain. This program is * taken from the Motif Programming Manual, O'Reilly Volume 6. */ /* text_form.c -- demonstrate how attachments work in Form widgets. * by creating a text-entry form type application. */ #include #include #include #include #include char *prompts[] = { "Name:", "Phone:", "Address:", "City:", "State:", "Zip:", }; main(argc, argv) int argc; char *argv[]; { Widget toplevel, mainform, subform, label, text; XtAppContext app; char buf[32]; int i; toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); mainform = XtVaCreateWidget("mainform", xmFormWidgetClass, toplevel, NULL); for (i = 0; i < XtNumber(prompts); i++) { subform = XtVaCreateWidget("subform", xmFormWidgetClass, mainform, /* first one should be attached for form */ XmNtopAttachment, i? XmATTACH_WIDGET : XmATTACH_FORM, /* others are attached to the previous subform */ XmNtopWidget, subform, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); label = XtVaCreateManagedWidget(prompts[i], xmLabelGadgetClass, subform, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNalignment, XmALIGNMENT_BEGINNING, NULL); sprintf(buf, "text_%d", i); text = XtVaCreateManagedWidget(buf, xmTextWidgetClass, subform, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, label, NULL); XtManageChild(subform); } /* Now that all the forms are added, manage the main form */ XtManageChild(mainform); XtRealizeWidget(toplevel); XtAppMainLoop(app); } If you resize horizontally it stretches the text widgets. If you resize vertically it leaves space under the bottom (if you don't resize, this is not problem). If you want the text widgets to be lined up on the left, as in ---------------------------------------- | ------------------- | | a label |Some text || | ------------------- | ------------------- | | a longer label |Some more text || | ------------------- | | ------------------- | |a very long label |Even more text || | ------------------- | ---------------------------------------- try this /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates. * This program is freely distributable without licensing fees and * is provided without guarantee or warranty expressed or implied. * This program is -not- in the public domain. This program is * taken from the Motif Programming Manual, O'Reilly Volume 6. */ /* text_entry.c -- This demo shows how the RowColumn widget can be * configured to build a text entry form. It displays a table of * right-justified Labels and Text widgets that extend to the right * edge of the Form. */ #include #include #include char *text_labels[] = { "Name:", "Phone:", "Address:", "City:", "State:", "Zip:", }; main(argc, argv) int argc; char *argv[]; { Widget toplevel, rowcol; XtAppContext app; char buf[8]; int i; toplevel = XtVaAppInitialize(&app, "Demos", NULL, 0, &argc, argv, NULL, NULL); rowcol = XtVaCreateWidget("rowcolumn", xmRowColumnWidgetClass, toplevel, XmNpacking, XmPACK_COLUMN, XmNnumColumns, XtNumber(text_labels), XmNorientation, XmHORIZONTAL, XmNisAligned, True, XmNentryAlignment, XmALIGNMENT_END, NULL); /* simply loop thru the strings creating a widget for each one */ for (i = 0; i < XtNumber(text_labels); i++) { XtVaCreateManagedWidget(text_labels[i], xmLabelGadgetClass, rowcol, NULL); sprintf(buf, "text_%d", i); XtVaCreateManagedWidget(buf, xmTextWidgetClass, rowcol, NULL); } XtManageChild(rowcol); XtRealizeWidget(toplevel); XtAppMainLoop(app); } This makes all objects exactly the same size. It does not resize in nice ways. If you want the text widgets lined up on the left, and the labels to be the size of the longest string, resizing nicely both horizontally and vertically, as in ------------------------------------- | ---------------- | | a label |Some text || | ---------------- | ---------------- | | a longer label |Some more text || | ---------------- | | ---------------- | |a very long label |Even more text || | ---------------- | ------------------------------------- Answer: Do this: to get the widgets lined up horizontally, use a form but place the widgets using XmATTACH_POSITION. In the example, attach the top of the first label to the form, the bottomPosition to 33 (33% of the height). Attach the topPosition of the second label to 33 and the bottomPosition to 66. Attach the topPosition of the third label to 66 and the bottom of the label to the form. Do the same with the text widgets. To get the label widgets lined up vertically, use the right attachment of XmATTACH_OPPOSITE_WIDGET: starting from the one with the longest label, attach widgets on the right to each other. In the example, attach the 2nd label to the third, and the first to the second. To get the text widgets lined up, just attach them on the left to the labels. To get the text in the labels aligned correctly, use XmALIGNMENT_END for the XmNalignment resource. /* geometry for label 2 */ n = 0; XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNtopPosition, 66); n++; XtSetValues (label[2], args, n); /* geometry for label 1 */ n = 0; XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNbottomPosition, 66); n++; XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNtopPosition, 33); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg (args[n], XmNrightWidget, label[2]); n++; XtSetValues (label[1], args, n); /* geometry for label 0 */ n = 0; XtSetArg (args[n], XmNalignment, XmALIGNMENT_END); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNbottomPosition, 33); n++; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg (args[n], XmNrightWidget, label[1]); n++; XtSetValues (label[0], args, n); /* geometry for text 0 */ n = 0; XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNbottomPosition, 33); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, label[0]); n++; XtSetValues (text[0], args, n); /* geometry for text 1 */ XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNtopPosition, 33); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNbottomPosition, 66); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, label[1]); n++; XtSetValues (text[1], args, n); /* geometry for text 2 */ XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION); n++; XtSetArg (args[n], XmNtopPosition, 66); n++; XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg (args[n], XmNleftWidget, label[2]); n++; XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetValues (text[2], args, n); ----------------------------------------------------------------------------- Subject: 66) TOPIC: PUSHBUTTON WIDGET ----------------------------------------------------------------------------- Subject: 67) Why can't I use accelerators on buttons not in a menu? Answer: It is apparently a difficult feature to implement, but OSF are considering this for the future. It is problematic trying to use the Xt accelerators since the Motif method interferes with this. one workaround suggested is to duplicate your non-menu button by a button in a menu somewhere, which does have a menu-accelerator installed. When the user invokes what they think is the accelerator for the button they can see Motif actually invokes the button on the menu that they can't see at the time. Another method is described below and was contributed by Harald Albrecht of Institute of Geometry and Practical Mathematics Rhine Westphalia Technical University Aachen (RWTH Aachen), Germany From albrecht@igpm.rwth-aachen.de Thu Jul 8 11:44:21 1993 My work-around of this problem looks like this: (I've written that code for a Motif Object Library in C++ so please forgive me for being object orientated!) The hack consists of a rewritten message loop which checks for keypresses +. If MessageLoop() finds such a keypress HandleAcc() ist called and the widget tree is searched for a suitable widget with the right mnemonic. // -------------------------------------------------------------------------- // traverse the widget tree starting with the given widget. // BOOL TraverseWidgetTree(Widget w, char *pMnemonic, XKeyEvent *KeyEvent) { Widget wChild; WidgetList ChildList; int NumChilds, Child; KeySym LabelMnemonic; char *pMnemonicString; // Check if the widget is a subclass of label -- then it may have an // accelerator attached... if ( XtIsSubclass(w, xmLabelWidgetClass) ) { // ok. Now: get the widget's mnemonic, convert it to ASCII and compare // it with the Key we're looking for. XtVaGetValues(w, XmNmnemonic, &LabelMnemonic, NULL); pMnemonicString = XKeysymToString(LabelMnemonic); if ( pMnemonicString && (strcasecmp(pMnemonicString, pMnemonic) == 0) ) { // stimulate the keypress XmProcessTraversal((Widget)w, XmTRAVERSE_CURRENT); KeyEvent->type = KeyPress; KeyEvent->window = XtWindow(w); KeyEvent->subwindow = XtWindow(w); KeyEvent->state = 0; KeyEvent->keycode = XKeysymToKeycode(XtDisplay(w), XK_space); XSendEvent(XtDisplay(w), XtWindow(w), True, ButtonPressMask, (XEvent*) KeyEvent); KeyEvent->type = KeyRelease; XSendEvent(XtDisplay(w), XtWindow(w), True, ButtonReleaseMask, (XEvent*) KeyEvent); return True; } } // if this widget is a subclass of Composite check all the widget's // childs. if ( XtIsSubclass(w, compositeWidgetClass) ) { // if we're in a menu (or something like that) forget this leaf of the // widget tree! if ( XtIsSubclass(w, xmRowColumnWidgetClass) ) { unsigned char RowColumnType; XtVaGetValues(w, XmNrowColumnType, &RowColumnType, NULL); if ( RowColumnType != XmWORK_AREA ) return False; } XtVaGetValues(w, XmNchildren, &ChildList, XmNnumChildren, &NumChilds, NULL); for ( Child = 0; Child < NumChilds; ++Child ) { wChild = ChildList[Child]; if ( TraverseWidgetTree(wChild, pMnemonic, KeyEvent) ) return True; } } return False; } // TraverseWidgetTree // -------------------------------------------------------------------------- // handle accelerators (keypress MAlt + key) // #define MAX_MAPPING 10 BOOL HandleAcc(Widget w, XEvent *event) { Widget widget, OldWidget; static char keybuffer[MAX_MAPPING]; int CharCount; static XComposeStatus composeStatus; // convert KeyPress to ASCII CharCount = XLookupString((XKeyEvent*) event, keybuffer, sizeof(keybuffer), NULL, &composeStatus); keybuffer[CharCount] = 0; // Only one char is alright -- then search the widget tree for a widget // with the right mnemonic if ( CharCount == 1 ) { keybuffer[0] = tolower(keybuffer[0]); widget = w; while ( (widget != NULL) && !XtIsSubclass(widget, shellWidgetClass) ) { OldWidget = widget; widget = XtParent(widget); } if ( !widget ) widget = OldWidget; return TraverseWidgetTree(widget, keybuffer, (XKeyEvent*) event); } return False; // no-one found. } // HandleAcc // -------------------------------------------------------------------------- // modified message loop // loops until the Boolean pFlag points to is set to False void MessageLoop(Boolean *pFlag) { XEvent nextEvent; while ( *pFlag ) { if ( XtAppPending(AppContext) ) { XtAppNextEvent(AppContext, &nextEvent); if ( nextEvent.type == KeyPress ) { // Falls es ein Tastendruck ist, bei dem auch noch die ALT-Taste // (=Modifier 1) gedrueckt ist, koennte es ein Accelerator sein! if ( nextEvent.xkey.state & Mod1Mask ) if ( HandleAcc(XtWindowToWidget(nextEvent.xkey.display, nextEvent.xkey.window), &nextEvent) ) continue; // Mitteilung konnte ausgeliefert werden // und darf daher nicht den ueblichen // Weg gehen! } XtDispatchEvent(&nextEvent); } } } // TApplication::MessageLoop Harald Albrecht albrecht@igpm.rwth-aachen.de Institute of Geometry and Practical Mathematics Rhine Westphalia Technical University Aachen (RWTH Aachen), Germany ----------------------------------------------------------------------------- Subject: 68) TOPIC: LABEL WIDGET ----------------------------------------------------------------------------- Subject: 69) How can I align the text in a label (button, etc) widget? Answer: The alignment for the label widget is controlled by the resource XmNalignment, and the default centers the text. Use this resource to change it to left or right alignment. However, when the label (or any descendant) is in a row column, and XmNisAligned is True (the default), the row column aligns text using its resource XmNentryAlignment. If you want simultaneous control over all widgets use this, but otherwise turn XmNisAligned off and do it individually. ----------------------------------------------------------------------------- Subject: 70) Why doesn't label alignment work in a RowColumn? Answer: RowColumn has a resource XmNisAligned (default True) and and XmNentryAlignment (default XmALIGNMENT_BEGINNING). These control alignment of the labelString in Labels and descendants. Set XmNisAligned to False to turn this off. ----------------------------------------------------------------------------- Subject: 71) How can I set a multiline label? [Last modified: September 92] Answer: In .Xdefaults *XmLabel*labelString: Here\nis\nthe\nLabel This method does not seem to work in some of the older Motif 1.0 versions. In code, char buf[128]; XmString msg; sprintf(buf, "Here\nis\nthe\nLabel"); msg = XmStringCreateLtoR(buf, XmSTRING_DEFAULT_CHARSET); XtSetArg (args[n], XmNlabelString, msg); Gives a four line label, using the escape sequence \n for a newline. However, XmStringCreateLtoR() is obsoleted from version 1.1 on, and may disappear. This is because it it is only in the AES as "trial-use" and has been proposed for removal from the AES. Realistically, it will probably not be removed from any backward compatible versions of Motif, but the potential is there. If it does disappear (or if you want to avoid using the non-AES compliant XmSTRING_DEFAULT_CHARSET), try this from Jean-Philippe Martin-Flatin #include #include /*----------------------------------------------------- Create a new XmString from a char* This function can deal with embedded 'newline' and is equivalent to the obsolete XmStringCreateLtoR, except it does not use non AES compliant charset XmSTRING_DEFAULT_CHARSET ----------------------------------------------------*/ XmString xec_NewString(char *s) { XmString xms1; XmString xms2; XmString line; XmString separator; char *p; char *t = XtNewString(s); /* Make a copy for strtok not to */ /* damage the original string */ separator = XmStringSeparatorCreate(); p = strtok(t,"\n"); xms1 = XmStringCreateSimple(p); while (p = strtok(NULL,"\n")) { line = XmStringCreateSimple(p); xms2 = XmStringConcat(xms1,separator); XmStringFree(xms1); xms1 = XmStringConcat(xms2,line); XmStringFree(xms2); XmStringFree(line); } XmStringFree(separator); XtFree(t); return xms1; } Do not use XmStringCreateSimple() - it does not process the newline character in the way you want. In UIL, you have to explicitly create a compound string with a separator. Here's what W. Scott Meeks suggests: value nl : compound_string('', seperate=true); object my_label : XmLabel { arguments { XmNlabelString = 'Here' & nl & 'is' & nl & 'the' & nl & 'Label'; }; }; ----------------------------------------------------------------------------- Subject: 72) How can I have a vertical label? Answer: Make a multiline label with one character per line, as in the last question. There is no way to make the text rotated by 90 degrees though. ----------------------------------------------------------------------------- Subject: 73) How can I have a Pixmap in a Label? Answer: From Bob Hays (bobhays@spss.com) Pixmap px_disarm, px_disarm_insens; Widget Label1; Pixel foreground, background; Arg args[4]; Arg arg[] = { { XmNforeground, &foreground }, { XmNbackground, &background } }; Label1 = XmCreateLabel ( Shell1, "Label1", (Arg *) NULL, (Cardinal) 0 ); XtGetValues ( Label1, arg, XtNumber ( arg ) ); px_disarm = XCreatePixmapFromBitmapData(display, DefaultRootWindow(display), mtn_bits, mtn_width, mtn_height, foreground, background, DefaultDepth(display,DefaultScreen(display))); px_disarm_insens = XCreatePixmapFromBitmapData(display, DefaultRootWindow(display), mtn_ins_bits, mtn_ins_width, mtn_ins_height, foreground, background, DefaultDepth(display,DefaultScreen(display))); n = 0; XtSetArg(args[n], XmNlabelType, XmPIXMAP); n++; XtSetArg(args[n], XmNlabelPixmap, px_disarm); n++; XtSetArg(args[n], XmNlabelInsensitivePixmap, px_disarm_insens ); n++; XtSetValues ( Label1, args, n ); XtManageChild(Label1); That will cause the foreground and background of your pixmap to be inherited from the one that would be used by OSF/Motif when the label is displayed. The advantage is that this will utilize any resource values the user may have requested without looking explicitly into the resource database. And, you will have a pixmap handy if the application insensitizes the label (without an XmNlabelInsensitivePixmap your label will go empty if made insensitive). [Bob's original code was for a PushButton. Just change all Label to PushButton for them.] ----------------------------------------------------------------------------- Subject: 74) TOPIC: DRAWING AREA WIDGET ----------------------------------------------------------------------------- Subject: 75) How can I send an expose event to a Drawing Area widget? (or any other, come to that). I want to send an expose event so that it will redraw itself. Answer: Use the Xlib call XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, True) This clears the widget's window and generates an expose event in doing so. The widgets expose action will then redraw it. This uses a round trip request. An alternative, without the round trip is from orca!mesa!rthomson@uunet.uu.net (Rich Thomson): Widget da; XmDrawingAreaCallbackStruct da_struct; da_struct.reason = XmCR_EXPOSE; da_struct.event = (XEvent *) NULL; da_struct.window = XtWindow(da); XtCallCallbacks(da, XmNexposeCallback, (XtPointer) da_struct); ----------------------------------------------------------------------------- Subject: 76) How can I know when a DrawingArea has been resized? It generates an expose event whn it is enlarged, but not when it is shrunk. Answer: Use the resize callback. ----------------------------------------------------------------------------- Subject: 77) TOPIC: MENUS ----------------------------------------------------------------------------- Subject: 78) What can I put inside a menu bar? Answer: You can only put cascade buttons in menu bars. No pushbuttons, toggle buttons or gadgets are allowed. When you create a pulldown menu with parent a menu bar, its real parent is a shell widget. ----------------------------------------------------------------------------- Subject: 79) Can I have a cascade button without a submenu in a pulldown menu? Answer: Yes you can. A cascade button has an activate callback which is called when you click on it and it doesn't have a submenu. It can have a mnemonic, but keyboard traversal using the arrow keys in the menu will skip over it. ----------------------------------------------------------------------------- Subject: 80) Should I have a cascade button without a submenu in a pulldown menu? Answer: No. This is forbidden by the style guide. Technically you can do it (see previous question) but if you do it will not be Motif style compliant. This is unlikely to change - if a "button" is important enough to be in a pulldown menu bar with no pulldown, it should be a button elsewhere. (Mind you, you won't be able to put accelerators on it elsewhere though.) ----------------------------------------------------------------------------- Subject: 81) What is the best way to create popup menus? [Last modified: August 92] Susan Murdock Thompson (from OSF): In general, create a popupMenu as the child from which you will be posting it from (ie: if you have a bulletinBoard with a PushButton in it and want MB2 on the pushButton to post the popupMenu, create the popupMenu as a child of the pushButton). [This parent-child relationship seems to make a big difference in the behavior of the popups.] Add an event handler to handle buttonPress events. You'll need to check for the correct button (what you've specified menuPost to be) before posting the menu. To create a popup that can be accessible from within an entire client window, create it as the child of the top-most widget (but not the shell) and add event handlers for the top-most widget and children widgets. ie: { .... XtManageChild(rc=XmCreateRowColumn(Shell1, "rc", NULL, 0)); XtManageChild(label = XmCreateLabel(rc, "label", NULL, 0)); XtManageChild(text = XmCreateText(rc, "text", NULL, 0)); XtManageChild(pushbutton = XmCreatePushButton(rc, "pushbutton", NULL, 0)); n = 0; XtSetArg(args[n], XmNmenuPost, ""); n++; popup = XmCreatePopupMenu(rc, "popup", args, n); XtAddEventHandler(rc, ButtonPressMask, False, PostMenu3, popup); XtAddEventHandler(text, ButtonPressMask, False, PostMenu3, popup); XtAddEventHandler(label, ButtonPressMask, False, PostMenu3, popup); XtAddEventHandler(pushbutton, ButtonPressMask, False, PostMenu3, popup); XtManageChild(m1 = XmCreatePushButton(popup, "m1", NULL, 0)); XtManageChild(m2 = XmCreatePushButton(popup, "m2", NULL, 0)); XtManageChild(m3 = XmCreatePushButton(popup, "m3", NULL, 0)); XtAddCallback(m1, XmNactivateCallback, SayCB, "button M1"); XtAddCallback(m2, XmNactivateCallback, SayCB, "button M2"); XtAddCallback(m3, XmNactivateCallback, SayCB, "button M3"); ... } /* where PostMenu3 is ... */ PostMenu3 (w, popup, event) Widget w; Widget popup; XButtonEvent * event; { printf("menuPost = 3, button %d0, event->button); if (event->button != Button3) return; XmMenuPosition(popup, event); XtManageChild(popup); } ----------------------------------------------------------------------------- Subject: 82) How do popup menus work? [Last modified: August 92] Answer: When a popup menu is created as the child of a widget the menu system installs a translation on the parent of the popup and descendants with an action which: (1) when 3-rd button (the default for the menuPost resource) is pressed the cursor changes and the mouse is grabbed for 5 seconds; (2) disables event handlers on the descendants and the handlers are never called; (3) an event handler installed on the parent works fine. It is done so that the correct event handler will (in fact) be called. There is a grab with owner_events true. The grab is released by a timer, but normally the posted menu shell puts up it's own grab. If you only have widgets then you can use the subwindow field in the event to identify the original widget. If you have gadgets or other data that you want to change the menu for (or use a specific menu for) then you must do a walk of the parent's children to find the best match. One thing to beware of is that even with the grab, because the menu system does a grab with owner events true, you must either have an event handler, or nothing that will use the event on each widget in the hierarchy of the menu's parent. If a child widget has another event handler for button down, it may swallow the event and do something else. ----------------------------------------------------------------------------- Subject: 83) Should I use translation tables or actions for popup menus? [Last modified: August 92] Answer: The original goal of popupMenus was that the user would not have to specify an event handler to manage popupMenus; however, that did not become reality. Larry Rogers wrote: > There appear to be two ways to manage popup menus. I > am curious what the correct way would be: > 1. Change the translation table of the widget with the > popup child to popup the menu. Note that this does > not currently working for many widgets, because aug- > menting their translations, even for augment breaks > the widget. > 2. Add an event handler at creation to the widget; then > determine if the event that caused the event handler > to be called is the current button being used by the > menu as its activation button. Susan Murdock Thompson (from OSF) replied: *Theoretically, you should be able to do both.* Our documentation says use event handlers. Our tests for the toolkit use event handlers and for UIL use translations. (Although I tried an event handler with a UIL test and it works). ----------------------------------------------------------------------------- Subject: 84) What are the known bugs in popup menus? [Last modified: August 92] Answer: As at Motif 1.1.4, the bugs for which an OSF PIR exists are: (3) Menus not being sticky (ie: posted on a Btn CLICK) [ Note:this problem occurs with OptionMenus as well] (PIR 3435) (6) Destroying a widget with an associated popupMenu results in "Warning: Attempt to remove non-existant passive grab" (PIR 2972) (7) Current documentation insufficient regarding requirements for success in using PopupMenus. (PIR 3433) ----------------------------------------------------------------------------- Subject: 85) Can I have multiple popup menus on the same widget? [Last modified: August 92] Answer: If you want to have several popups (activated by different mouse buttons) on the same widget..., well, that doesn't work yet. If you want to have several popups on different children... that works. But don't put a popup on the parent (manager) widget, or it will rule! ----------------------------------------------------------------------------- Subject: 86) TOPIC: INPUT FOCUS ----------------------------------------------------------------------------- Subject: 87) How can I specify the widget that should have the keyboard focus when my application starts up? Answer: In Motif 1.2, use XmNinitialFocus on the manager widget. thanks to Ken Lee, klee@synoptics.com ----------------------------------------------------------------------------- Subject: 88) How can I direct the keyboard input to a particular widget? Answer: In Motif 1.1 call XmProcessTraversal(target, XmTRAVERSE_CURRENT). The widget (and all of its ancestors) does need to be realized BEFORE you call this. Otherwise it has no effect. XmProcessTraversal is reported to have many bugs, so it may not work right. A common occurrence is that it doesn't move to the widget, but if you call XmProcessTraversal *twice* in a row, it will. If you can't get it to work, try this from Kee Hinckley: // This insane sequence is as follows: // On manage set up a focus callback // On focus callback set up a timer (and get rid of focus callback!) // On timer set the focus (which only works if the parent // has the focus, // which is why we went through all of this garbage) // There may be a better way, but I haven't time to try it now. // static void focusTO(void *data, XtIntervalId *) { XmProcessTraversal((Widget) data, XmTRAVERSE_CURRENT); } static void focusCB(Widget w, XtPointer data, XtPointer) { XtRemoveCallback(w, XmNfocusCallback, focusCB, data); XtAppAddTimeOut(XtWidgetToApplicationContext(w), 0, focusTO, data); } void OmXSetFocus(Widget parent, Widget w) { XtAddCallback(parent, XmNfocusCallback, focusCB, w); } In Motif 1.0 call the undocumented _XmGrabTheFocus(target). Do not use the X or Xt calls such as XtSetKeyboardFocus since this bypasses the Motif traversal layer and can cause it to get confused. This can lead to odd keyboard behaviour elsewhere in your application. ----------------------------------------------------------------------------- Subject: 89) How can I have a modal dialog which has to be answered before the application can continue? [Last modified: July 92] Answer: The answer depends on whether you are using the Motif window manager mwm or not. Test for this by XmIsMotifWMRunning. The window manager mwm knows how to control event passing to dialog widgets declared as modal. If the dialog is set to application modal, then no interaction with the rest of the application can occur until the dialog is destroyed or unmanaged. Use the appropriate code in the following program. There is followup discussion after the program. /* Written by Dan Heller. Copyright 1991, O'Reilly && Associates. * This program is freely distributable without licensing fees and * is provided without guarantee or warranty expressed or implied. * This program is -not- in the public domain. This program is * taken from the Motif Programming Manual, O'Reilly Volume 6. */ /* * ask_user.c -- create a pushbutton that posts a dialog box * that asks the user a question that requires an immediate * response. The function that asks the question actually * posts the dialog that displays the question, waits for and * returns the result. */ #include #include #include #include #include #include #include XtAppContext app; #define YES 1 #define NO 2 /* main() --create a pushbutton whose callback pops up a dialog box */ main(argc, argv) char *argv[]; int argc; { Widget parent, button, toplevel; XmString label; void pushed(); toplevel = XtAppInitialize(&app, "Demos", NULL, 0, &argc, argv, NULL, NULL, 0); label = XmStringCreateSimple("/bin/rm *"); button = XtVaCreateManagedWidget("button", xmPushButtonWidgetClass, toplevel, XmNlabelString, label, NULL); XtAddCallback(button, XmNactivateCallback, pushed, "Remove Everything?"); XmStringFree(label); XtRealizeWidget(toplevel); XtAppMainLoop(app); } /* pushed() --the callback routine for the main app's pushbutton. */ void pushed(w, question) Widget w; char *question; { if (AskUser(w, question) == YES) puts("Yes"); else puts("No"); } /* * AskUser() -- a generalized routine that asks the user a question * and returns the response. */ AskUser(parent, question) char *question; { static Widget dialog; XmString text, yes, no; static int answer; extern void response(); answer = 0; if (!dialog) { dialog = XmCreateQuestionDialog(parent, "dialog", NULL, 0); yes = XmStringCreateSimple("Yes"); no = XmStringCreateSimple("No"); XtVaSetValues(dialog, XmNdialogStyle, XmDIALOG_APPLICATION_MODAL, XmNokLabelString, yes, XmNcancelLabelString, no, NULL); XtSetSensitive( XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False); XtAddCallback(dialog, XmNokCallback, response, &answer); XtAddCallback(dialog, XmNcancelCallback, response, &answer); /* if the user interacts via the system menu: */ XtAddCallback(dialog, XmNpopdownCallback, response, &answer); } text = XmStringCreateSimple(question); XtVaSetValues(dialog, XmNmessageString, text, NULL); XmStringFree(text); XtManageChild(dialog); XtPopup(XtParent(dialog), XtGrabNone); /* while the user hasn't provided an answer, simulate XtMainLoop. * The answer changes as soon as the user selects one of the * buttons and the callback routine changes its value. Don't * break loop until XtPending() also returns False to assure * widget destruction. */ while (answer == 0 || XtAppPending(app)) XtAppProcessEvent(app, XtIMAll); return answer; } /* response() --The user made some sort of response to the * question posed in AskUser(). Set the answer (client_data) * accordingly and destroy the dialog. */ void response(w, answer, reason) Widget w; int *answer; XmAnyCallbackStruct *reason; { switch (reason->reason) { case XmCR_OK: *answer = YES; break; case XmCR_CANCEL: *answer = NO; break; default: *answer = NO; return; } } If you aren't running a window manager that acknowledges this hint, then you may have to grab the pointer (and keyboard) yourself to make sure the user doesn't interact with any other widget. Change the grab flag in XtPopup to XtGrabExclusive, and XtRemoveGrab(XtParent(w)) to the response() function. ----------------------------------------------------------------------------- Subject: 90) TOPIC: MEMORY AND SPEED ----------------------------------------------------------------------------- Subject: 91) When can I free data structures passed to or retrieved from Motif? Answer: In most cases, especially for XmStrings and XmFontLists, Motif copies data passed to it or retrieved from it, so it may be freed immediately. Server- side resources, such as pixmaps and color cells, however, are not copied, so should not be freed. More recent versions of Motif are better than earlier versions and exceptions should be documented. thanks to klee*synoptics.com (Ken Lee) ----------------------------------------------------------------------------- Subject: 92) Why does my application grow in size? Answer: Motif 1.0 has many memory leaks, particularly in XmString manipulation. Switch to Motif 1.1. Answer: The Intrinsics have a memory leak in accelerator table management, and Motif uses this heavily. Avoid this by mapping/unmapping widgets rather than creating/destroying them, or get X11R4 fix-15/16/17. Answer: The server may grow in size due to its own memory leaks. Switch to a later server. Answer: You are responsible for garbage collection in `C'. Some common cases where a piece of memory becomes garbage are a. Memory is allocated by Motif for XmStrings by the functions XmStringConcat, XmStringCopy, XmStringCreate, XmStringCreateLtoR, XmStringCreateSimple, XmStringDirectionCreate, XmStringNConcat, XmStringNCopy, XmStringSegmentCreate, and XmStringSeparatorCreate. The values returned by these functions should be freed using XmStringFree when they are no longer needed. b. Memory is allocated by Motif for ordinary character strings (of type String) by Motif in XmStringGetLtoR, XmStringGetNextComponent, and XmStringGetNextSegment. After using the string, XtFree() it. [Note that XmStrings and Strings are two different data types. XmStrings are XmStringFree'd, Strings are XtFree'd.] c. If you have set the label (an XmString) in a label, pushbutton, etc widget, free it after calling XtSetValues() or the widget creation routine by XmStringFree(). d. If you have set text in a text widget, the text widget makes its own copy. Unless you have a use for it, there is no need to keep your own copy. e. If you have set the strings in a list widget the list widget makes its own copy. Unless you have a use for it, there is no need to keep your own copy. f. When you get the value of a single compound string from a Widget e.g. XmNlabelString, XmNmessageString, ... Motif gives you a copy of its internal value. You should XmStringFree this when you have finished with it. g. On the other hand, when you get a value of a Table e.g. XmStringTable for a List, you get a *pointer* to the internal Table, and should not free it. h. When you get the value of the text in a widget by XmTextGetString or from the resource XmNvalue, you get a copy of the text. You should XtFree this when you have finished with it. Answer: From Josef Nelissen: at least in Motif 1.1.4, X11R4 on a HP 720, the XmText/XmTextFieldSetString() functions have a memory leak. The old value/contents of the Widget isn't freed correctly. To work around this bug, one should use a XmText Widget (in single-line-mode) instead of a XmTextField Widget (the solution fails with XmTextField Widgets !) and replace any XmTextSetString(text_widget, str); by XmTextReplace(text_widget, (XmTextPosition) 0, XmTextGetLastPosition(text_widget), str); ----------------------------------------------------------------------------- Subject: 93) Why does my application take a long time to start up? Answer: You are probably creating too many widgets at startup time. Delay creating them until needed. If you have a large number of resources in text files (such as in app-defaults), time may be spent reading and parsing it. ----------------------------------------------------------------------------- Subject: 94) My application is running too slowly. How can I speed it up? Answer: Use the R4 rather than R3 server. It is much faster. Answer: The standard memory allocator is not well tuned to Motif, and can degrade performance. Use a better allocator. e.g. with SCO Unix, link with libmalloc.a; use the allocator from GNU emacs; use the allocator from Perl. Answer: Avoid lots of widget creation and destruction. It fragments memory and slows everything down. Popup/popdown, manage/unmanage instead. Answer: Set mappedWhenManaged to FALSE, and then call XtMapWidget() XtUnmapWidget() rather than managing. Answer: Get more memory - your application, the server and the Operating System may be spending a lot of time being swapped. Answer: If you are doing much XmString work yourself, such as heavy use of XmStringCompare, speed may deteriorate due to the large amount of internal conversions and malloc'ing. Try using XmStringByteCompare if appropriate or ordinary Ascii strings if you can. ----------------------------------------------------------------------------- Subject: 95) Why is my application so huge? Answer: The typical size of a statically linked Motif app is in the megabytes. This is often caused by the size of libXm.a. A large part of this gets linked in to even trivial Motif programs. You can reduce the code size by linking against shared libraries if they are available. Running "strip" on the executable can often reduce size. Note that the size of the running program should be measured by "ps", not by the code size. ----------------------------------------------------------------------------- END OF PART THREE ----------------------------------------------------------------------------- Subject: 96) TOPIC: XMSTRING ----------------------------------------------------------------------------- Subject: 97) How can I get the Ascii text out of an XmString? Answer: To get the first line of text from a string created left-to-right char *str; XmString xmstr; /* stuff to create xmstr */ ... /* set str to point to the text */ XmStringGetLtoR(xmstr, XmSTRING_DEFAULT_CHARSET, &str); /* use the string */ ... /* and reclaim space */ XtFree(str); ----------------------------------------------------------------------------- Subject: 98) When can XmStrings used as resources be freed? Answer: The policy OSF have been trying to enforce is that if you set an XmString or XmStringTable resource, the application is responsible for freeing the XmStrings used because the widget makes a copy. If you get an XmString resource, then the application must free the value gotten. If you get an XmStringTable, then the application should NOT free the value gotten. If the application wants to manipulate it, it should make a copy first. This policy appears to be implemented progressively, so may be less true for Motif 1.0 than 1.1. ----------------------------------------------------------------------------- Subject: 99) Why doesn't XmStringGetNextSegment() work properly? Answer: The documentation in Motif 1.0 is in error. Instead of XmStringGetnextSegment(context, ...) XmStringContext * context; it should be XmStringGetnextSegm