home *** CD-ROM | disk | FTP | other *** search
Text File | 2004-05-05 | 53.5 KB | 1,419 lines |
- Path: senator-bedfellow.mit.edu!dreaderd!not-for-mail
- Message-ID: <motif-faq/part4_1083675484@rtfm.mit.edu>
- Supersedes: <motif-faq/part4_1082292761@rtfm.mit.edu>
- Expires: 17 Jun 2004 12:58:04 GMT
- References: <motif-faq/part1_1083675484@rtfm.mit.edu>
- X-Last-Updated: 2002/01/31
- Organization: none
- Subject: Motif FAQ (Part 4 of 9)
- Newsgroups: comp.windows.x.motif,comp.answers,news.answers
- Keywords: FAQ question answer
- From: kenton@rahul.net (Ken Lee)
- Reply-To: kenton@rahul.net (Ken Lee)
- Approved: news-answers-request@MIT.EDU
- Followup-To: poster
- Summary: Motif Frequently Asked Questions (with answers).
- Originator: faqserv@penguin-lust.MIT.EDU
- Date: 04 May 2004 12:59:11 GMT
- Lines: 1398
- NNTP-Posting-Host: penguin-lust.mit.edu
- X-Trace: 1083675551 senator-bedfellow.mit.edu 561 18.181.0.29
- Xref: senator-bedfellow.mit.edu comp.windows.x.motif:75187 comp.answers:57052 news.answers:270856
-
- Archive-name: motif-faq/part4
- Last-modified: 1 FEB 2002
- Posting-Frequency: irregular
- Organization: Kenton Lee, X/Motif Consultant, http://www.rahul.net/kenton/
- URL: http://www.rahul.net/kenton/mfaq.html
- Version: 8.1
-
- ----------------------------------------------------------------------------
- Subject: 67) Is there an mwm virtual desktop manager?
- [Last modified: Sep 97]
-
- Answer: David Kaelbling (drk@x.org) reports: In OSF/Motif 2.0, mwm supports
- both workspaces (see the f.cci function and the wsm demo for a sample
- interface) and a virtual root window. To manipulate the virtual screen
- f.goto, f.pan, and f.track_pan were added, as were iconPinned and clientPinned
- client resources.
-
- Peter E. Wagner (pwagner@panix.com): 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.
-
- Tim Failes (tim@aus.oz.au) of Advanced User Systems Pty Ltd writes: IXI (now
- SCO) has a fully supported product called Panorama which provides this
- facility. Panorama allows the user to pan around the virtual work space,
- dynamically change the size of the virtual workspace, and also access windows
- via an icon box. Panorama also includes a point-and-click tool for setting
- resources such as colours, focus policy, etc. [SCO contact information appears
- in the "Where can I get Motif?" subject. -ed]
-
- -----------------------------------------------------------------------------
- Subject: 68) Why does mwm 1.2 crash on startup?
- [Last modified: March 93]
-
- Answer: David Brooks wrote: 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
-
- -----------------------------------------------------------------------------
- Subject: 69) How do I obtain the size of a unmanaged shell widget?
-
- Answer: In the code below, use getsize() for widgets which have been managed,
- and getsize2() for newly created shell widgets which have not yet been
- managed.
-
- getsize2() takes two widget parameters because popup dialogs etc. _consist_
- of two separate widgets - the parent shell and the child bulletin board, form,
- whatever. This important distinction (somewhat glossed over in the Motif
- manuals) is the cause of a large number of queries in comp.windows.x.motif.
- XmCreate...Dialog() functions return the (bulletin board, form, whatever)
- _child_ of the pair, not the parent shell.
-
- getsize2() takes the _shell_ widget as it's first parameter, and the shell's
- _child_ (the bulletin board, form, whatever) as it's second. Thus, if you are
- using code like widget = XmCreate...Dialog() to create your popup dialogs, use
- code like getsize2(XtParent(widget),widget,&width,&height) to get the width
- and height. If you use e.g. XmCreateDialogShell() or XtCreatePopupShell(),
- then you are creating the the shell widget and it's child explicitly, and can
- just pass them into getsize2() with no problem.
-
- Note: getsize2() calls getsize().
-
- /* getsize(widget,width,height);
- * Widget widget;
- * int *width,*height;
- *
- * returns the width and height of a managed widget */
-
-
- void getsize(l,w,h) Widget l; int *w,*h; { Dimension w_,h_,b_;
-
- static Arg size_args[] =
- {
- { XmNwidth,0 },
- { XmNheight,0 },
- { XmNborderWidth,0 },
- };
-
- size_args[0].value = (XtArgVal)&w_; size_args[1].value = (XtArgVal)&h_;
- size_args[2].value = (XtArgVal)&b_;
-
- XtGetValues(l,size_args,3);
-
- if (w) *w = w_ + b_; if (h) *h = h_ + b_; } /*
- getsize2(shell,child,width,height);
- * Widget shell,child;
- * int *width,*height;
- *
- * returns the width, height of an unmanaged shell widget */
-
- void getsize2(p,c,w,h) Widget p,c; int *w,*h; { XtSetMappedWhenManaged(p,0);
-
- XtManageChild(c);
-
- getsize(p,w,h);
-
- XtUnmanageChild(c);
-
- XtSetMappedWhenManaged(p,-1); } submitted by: [ Huw Rogers Communications
- Software Engineer, NEC Corporation, Tokyo, Japan ] [ Email:
- rogersh@ccs.mt.nec.co.jp Fax: +81-3-5476-1005 Tel: +81-3-5476-1096 ]
-
- -----------------------------------------------------------------------------
- Subject: 70) How can I create a shell widget with a non-default visual type?
- [Last modified: Feb 00]
-
- Answer: You must specify the colormap, visual type, and depth for the shell
- before it is realized. If you don't specify all three resources (or specify
- them incorrectly), you will probably get BadMatch protocol errors from your X
- server.
-
- Ken Lee, http://www.rahul.net/kenton/
-
-
- Mike Stroyan, mike_stroyan@fc.hp.com, adds:
- It is convenient to use XrmPutResource to cause all widgets to pick up a
- consistent set of visual, depth, and colormap. It is just very difficult to
- get at each and every shell including menushells created by functions like
- XmVaCreateSimpleMenuBar and XmVaCreateSimpleOptionMenu.
-
- This example uses the default visual for menus, but a non-default for the top
- level shell:
-
- if (!non_default_dialogs) {
- /* Set default depth and colormap of shell widgets, especially menus */
- Screen *default_screen;
- int default_depth;
- Colormap default_colormap;
- XrmDatabase db = XtDatabase(display);
- XrmValue v;
-
- default_screen = DefaultScreenOfDisplay(display);
- default_depth = DefaultDepthOfScreen(default_screen);
- default_colormap = DefaultColormapOfScreen(default_screen);
- v.size = sizeof(default_depth);
- v.addr = (XtPointer) &default_depth;
- XrmPutResource(&db,"*XmMenuShell.depth", XmRInt, &v);
- XrmPutResource(&db,"*XmDialogShell.depth", XmRInt, &v);
- v.size = sizeof(default_colormap);
- v.addr = (XtPointer) &default_colormap;
- XrmPutResource(&db,"*XmMenuShell.colormap", XmRColormap, &v);
- XrmPutResource(&db,"*XmDialogShell.colormap", XmRColormap, &v);
- }
-
- /* Get visual information. */
- template.screen = DefaultScreen(display);
- template.class = TrueColor;
- template.depth = 24;
- mask = VisualScreenMask | VisualDepthMask | VisualClassMask;
- vilist = XGetVisualInfo(display, mask, &template, &nvisual);
- if (nvisual == 0) {
- fprintf(stderr, "Cannot find an acceptable visual!0);
- exit(1);
- }
- visual = vilist[0].visual;
- depth = vilist[0].depth;
- XFree((char *) vilist);
-
- private_colormap = XCreateColormap(display, DefaultRootWindow(display),
- visual, AllocNone);
- {
- XColor real, exact;
- XAllocNamedColor(display, private_colormap, "Green", &real, &exact);
- green = real.pixel;
- }
-
- XtVaSetValues(toplevel,
- XmNdepth, depth,
- XmNvisual, visual,
- XmNcolormap, private_colormap,
- NULL);
-
- if (non_default_dialogs) {
- /* Set non-default visual for all widgets. */
- XrmDatabase db = XtDatabase(display);
- XrmValue v;
- v.size = sizeof(visual);
- v.addr = (XtPointer) &visual;
- XrmPutResource(&db,"*visual", XmRVisual, &v);
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 71) Can a non-shell Motif widget have a different visual type from
- its parent?
- [Last modified: May 97]
-
- Answer: None of the standard Motif widgets support this. You can, however,
- write your own subclasses that have different visual types. You'll have to
- override the Realize method in your subclass. Becareful to set the colormap
- and depth properly to match your visual type.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 72) Why do I get BadMatch errors from my menus when I use a non-
- default visual type for my application shell?
- [Last modified: Sept 95]
-
- Answer: Unfortunately, the visual type and depth attributes are copied
- differently from parent to child. To be safe you use non-default visuals on
- any of your widgets and use these as parents for shell widgets (including
- menus), you should set the visual type, depth, and colormap on the child
- shells.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 73) How do I popup a scrolled list on top of other widgets?
- [Last modified: Sept 95 ]
-
- Put it in an override redirect shell and do a XMapRaise on the shell's window.
- That will do it. If you're using Motif then just use a VendorShell with
- XmNoverrideRedirect set to true.
-
- Thanks to Doug Rand (drand@sgi.com)
-
- -----------------------------------------------------------------------------
- Subject: 74) How can I keep my application's window always on top of all
- other applications' windows?
- [Last modified: Sep 97]
-
- Answer: Some window managers have features supporting this. Mwm does not.
- The ICCCM does not specify a standard protocol for using the feature.
-
- Note: some applications attempt to implement this by periodically popping
- themselves to the top of the stack (perhaps in response to visibility change
- events). This is very poor practice and should be avoided. If more than one
- of a user's applications try this hack, the user will not be pleased.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 75) How can I maximize my top level shell?
- [Last modified: Apr 98]
-
- Answer: There is no explicit support for this. Maximizing makes sense in
- single tasking operating systems where the user must choose one application to
- be active. Motif usually runs in multi-tasking operating systems where
- several applications may be active and having one take over the screen is
- undesirable.
-
- If you must make your application full screen, use the Xlib macros to compute
- the root window size and set the width and height of your shell to this size.
- You may want to leave a little space around the edges for the window manager
- frame.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 76) TOPIC: MOTIF DEVELOPMENT TOOLS (GUI BUILDERS and UIMS's)
-
- -----------------------------------------------------------------------------
-
- Subject: 77)* What GUI tools exist to assist in developing Motif
- applications?
- [Last modified: Feb 02 ]
-
- Answer: This subject was very out-of-date and has been deleted. Some popular
- tools are listed at: http://www.rahul.net/kenton/xsites.framed.html
-
- -----------------------------------------------------------------------------
- Subject: 78) TOPIC: GEOMETRY MANAGEMENT
-
- -----------------------------------------------------------------------------
- Subject: 79) Why is geometry management so important?
- [Last modified: Sept 94]
-
- Answer: Geometry management is a key element of Motif applications for reasons
- which include, but are not limited to, the following:
-
-
- The user should be able to re-size the shell and get
- some reasonable geometry response (other than clipping).
-
- The user should be able to tailor fonts and have the
- widgets adjust accordingly. (Many people over 40 simply
- can't read small fonts without serious eye strain.)
-
- When the designers decide to change a label, the widgets
- should re-adjust accordingly.
-
- Some labels must be set dynamically and the widgets should
- re-layout accordingly.
-
- An internationalized application must work with several resource
- files, one for each supported natural language. The labels in each
- file have different lengths and the application should adjust
- accordingly.
-
-
- -----------------------------------------------------------------------------
- Subject: 80) Why don't my labels resize in a RowColumn widget? I have a
- RowColumn widget in my application, with several rows and columns of XmLabels.
- When I update the text in the labels, the label's width does not get updated.
- [Last modified: Oct 94]
-
- Answer: Make sure all the ancestor widget resize mechanisms are enabled:
-
- - on shells, set XmNallowShellResize
- - on row column, set XmNresizeWidth and XmNresizeHeight
- - on bulletin board and form, set XmNresizePolicy
-
- Also, set XmNrecomputeSize on the label itself. The shell resource is off by
- default; the others should be on by default.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 81) Does XmRowColumn support multiple columns with different column
- widths?
- [Last modified: Apr 98]
-
- Answer: XmRowColumn was designed for simple layouts like menu panes and tool
- bars. For more sophisticated layouts, you should use an XmForm widget
- instead.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 82) Why do composite widgets (including dialogs) that were created
- after their parents were realized appear smaller under 1.2.3 and later?
- [Last modified: Dec 97]
-
- A. Thanks to David Brooks (dbrooks@ics.com) for pointing me to Daniel
- Dardailler (daniel@x.org) who wrote this scholarly treatise:
-
- Application's Geometry Management Advanced Guidelines:
- =====================================================
- (or "How to properly manage children of already realized parent")
-
- Xt Background:
- -------------
-
- XtCreateWidget: call Initialize ;
-
- XtManageChild: if (parent realized)
- call ChangeManaged ;
- call Realize ;
-
- XtRealizeWidget: postorder ChangeManaged loop ;
- preorder Window-creation loop ;
-
- Creating a widget only invokes its Initialize method (its parent's
- InsertPosition method too, but that has nothing to do with GM).
- Composite widgets, by opposition to Primitive, does
- not usually get a correct size at initialization time, since their
- correct size is based on their children sizes, which do not exist yet
- at this time.
-
- Applications usually create an entire tree of managed but
- unrealized widgets and then realize their top level widget, which recursively
- realize every widgets in the tree. During the creation process, the
- managing of the unrealized widgets is a no-op (only mark them managed).
-
- When XtRealizeWidget(toplevel) happens, the change_managed methods of
- all the composite widgets in the tree are called in bottom-to-top
- order, thus giving each of them a chance to determine their own size
- based on their children *current* sizes (composite or not).
- Using the current size of the children in this situation is fine,
- since they should also be the children's preferred size, not
- yet constrained by the parents layout (post-order traversal).
-
- When one create a widget inside an already realized parent, this is
- a different story and the order of management vs realization is important.
-
- Consider a MessageBox created in a realized Frame.
- The MessageBox itself creates a bunch of managed children
- inside its Initialize method.
- If you manage the MessageBox right after its creation, the Frame
- ChangeManaged will be called (since it is realized), and its will use
- the MessageBox current size as its base for its own size.
- Unfortunately, the MessageBox ChangeManaged proc has never been called!
- so its current size is whatever the default is, usually a non-settable
- value (needed for tracking real initial size setting).
- The MessageBox ChangeManaged has not been called because its children
- were created and managed at a time where it wasn't realized.
-
- What to do ?
-
- The first solution would be to have all the ChangeManaged methods in
- Motif call XtQueryGeometry instead of using the current size if it's
- not the first time (i.e. if they're already realized).
- But this is a lot of code to change and a kind of expensive run-time
- process as it results in non-linear traversal order of the realized
- tree (looks like an O(n!) but I'm not sure).
- It's not even guaranteed that it will always work fine, since it relies on
- the assumption that the geometry queried is the same that the geometry
- asked for any manager (I mean, it might be the case, but if it's not,
- it's just more code to fix in a very "bc-sensitive" part of Xm).
-
- This other solution lies into the application, and is to realize a
- manager first and then to manage it.
- By realizing it, you are forcing its ChangeManaged proc to be
- called (XtRealizeWidget does that), it will get a correct size and
- this size will be used by its parent ChangeManaged when
- you'll manage the manager. By explicitly realizing the branch
- before managing its root, you are reproducing the ordering that
- is typical of most applications at startup.
-
- So the trick is:
-
- XtCreateWidget(realize_parent, MessageBox);
- XtRealizeWidget(MessageBox); /* needed */
- XtManageChild(MessageBox);
-
- and the model is:
-
- "Always explicitly realize a composite widget child of an already
- realized parent before managing it if all its children have been
- already managed"
-
- One can always realize every widget children of realized parents, that
- won't hurt, but it's useless for Primitives and Composites that
- get more children added later in the program.
- Why? because Primitives get their correct size at initialization
- time anyway and adding a child to a Composite will generate a geometry
- request and a layout that will have the same effect as if the
- ChangeManaged method had been called (well, nearly the same effect,
- that a complication I will address later).
-
- If we consider Motif, this trick is only useful for MessageBox,
- SelectionBox and subclasses, and Scale, since those are the only
- Composites that create managed children in their Initialize method and
- don't usually get additional kids from the application.
-
- However, any application that re-creates this order of actions will
- need to apply the "realize<manage" method too.
- For instance:
-
- XtCreateWidget(realize_parent, DrawingArea);
- XtRealizeWidget(DrawingArea); /* not needed */
- XtManageChild(DrawingArea);
- XtCreateWidget(DrawingArea, any_child) ;
- XtManageChild(any_child);
- but
- XtCreateWidget(realize_parent, DrawingArea);
- XtCreateWidget(DrawingArea, any_child) ;
- XtManageChild(any_child);
- XtRealizeWidget(DrawingArea); /* needed */
- XtManageChild(DrawingArea);
-
- Now this is becoming interesting: there are exceptions to the model :-)
-
- The first one is the Xt Shell widget, which has what I consider to be a
- bug, but what MIT has, until recently, always considered to be a specific
- behavior overridable by a subclass (like our VendorShell):
- the ChangeManaged method always resizes the child to its own size
- when the Shell is realized.
-
- A side effect of this behavior is that even the realized<managed trick
- won't work for direct descendant of Shell widget:
-
- XtCreateWidget(realize_shell, MessageBox);
- XtRealizeWidget(MessageBox); /* needless */
- XtManageChild(MessageBox); /* will get resized anyway */
-
- To get rid of this problem, one needs to add a regular manager
- between the Shell and the MessageBox in this case, for the sake
- of having this manager doing a request to the Shell from its
- ChangeManaged proc. This request will then be handled by the Shell
- geometry manager, not its ChangeManaged proc, and it will take into
- account the child size.
- Note that we could also change our VendorShell ChangeManaged code to not
- systematically envelop the Xt Shell ChangeManaged class method, and
- check for the already realized case, but I would rather wait
- for an Xt fix instead (I'm working on it).
-
- If you broader the scope of the Xt Shell situation, you find that there are
- also some resources in Xm that come into effect upon geometry request
- reception but are not used in the ChangeManaged method.
-
- Take the PanedWindow constraint resource XmNallowResize for instance,
- which controls the validity of a geometry request made by a PW child.
-
- If you do:
-
- XtCreateWidget(realize_shell, PanedWindow);
- XtManageChild(PanedWindow);
-
- XtCreateWidget(PanedWindow, button);
- XtManageChild(button);
-
- that works fine since the ChangeManaged of the PanedWindow will
- handle the insertion of the button and allowResize won't be used.
-
- But if you add a manager in this hierarchy:
-
- XtCreateWidget(realize_parent, PanedWindow);
- XtManageChild(PanedWindow);
-
- XtCreateWidget(PanedWindow, manager);
- XtManageChild(manager);
-
- XtCreateWidget(manager, button);
- XtManageChild(button);
-
- That doesn't work anymore since the button management results in
- its parent manager's ChangeManaged being called, which in turn makes a
- *request* to the PanedWindow, resulting in a No reply because
- of allowResize (set to False by default).
-
- The PanedWindow parent wouldn't have been realized that everything
- would have worked fine, since no request would have been made.
- It really depends on the early realization scheme.
-
- I think XmNresizable in Form is the only other resource to present
- this problem. There is not much to do in those cases except than
- setting the corresponding resource to True, which makes sense.
-
- - Daniel Dardailler (daniel@x.org)
-
-
- In addition, John Michael Davison <davisonj@panix.com> sends this suggestion.
- I think it's overkill for most people, but you may want to consider it if you
- have problems in this area:
-
- /* Workaround for motif 1.2.3-style geometry management */
- void
- smart_manage_child(Widget widget)
- {
- assert(widget != 0);
-
- #if XmVersion >= 1002 && XmUPDATE_LEVEL >= 3
- /* In Motif 1.2.3 and later:
- /* "Always explicitly realize a composite widget child of an already
- /* realized parent before managing it..."
- /* Note that this is unnecessary for simple UI objects (i.e. wrappers for
- /* Motif "Primitive" widgets.)
- */
- if (XtIsManaged(widget))
- return;
- if (!XtIsRealized(widget) && XtIsComposite(widget))
- {
- Widget parent_widget = XtParent(widget);
- if (parent_widget && XtIsRealized(parent_widget))
- XtRealizeWidget(widget);
- }
- #endif /* XmVersion >= 1002 && XmUPDATE_LEVEL >= 3 */
- XtManageChild(widget);
- }
-
- - John Michael Davison <davisonj@panix.com>
-
-
- FYI - Asente & Swick (p. 207) says:
-
- If the child's parent is realized, XtManageChild and XtManageChildren
- automatically realize any widgets passed to them that are not currently
- realized, causing the creation of their windows. However, you should
- explicitly realize a composite child of a realized widget before managing the
- child to ensure that the child appears with its correct size.
-
- - Ken Lee, http://www.rahul.net/kenton/
-
- -----------------------------------------------------------------------------
- Subject: 83) How does the ScrolledWindow manage resizing?
- [Last modified: June 95]
-
- Answer: The scrolled window should resize its immediate child when it is
- resized. The child is XmNworkWindow in the default application-defined
- scrolling mode or XmNclipWindow in the automatic scrolling mode. In either
- case, you can then resize your row column. If you set XmNadjustLast, the
- children of a one column row column will be automatically resized.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 84) Does the XmPanedWindow widget support horizontal paning?
- [Last modified: May 97]
-
- Answer: In Motif 2.x it does, but not in Motif 1.x. There are, however, some
- 3rd party horizontal paned widgets listed in the Widget FAQ:
-
-
- http://reality.sgi.com/widgetFAQ/
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 85) TOPIC: TEXT WIDGET
-
- -----------------------------------------------------------------------------
- Subject: 86) How do XmTextField and a single line XmText widget differ?
- [Last modified: Oct 94]
-
- Answer: XmTextField is designed to be a lightweight, single line text editor.
- It does not provide as much functionality as does XmText in order to achieve
- better performance.
-
- Thanks to Kevin Till, kev@osf.org
-
- -----------------------------------------------------------------------------
- Subject: 87) Why does pressing RETURN 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 <return> 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
- <return> 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[] = "<Key>Return : activate()";
- /* for a multi line widget */
- char newTrans[] = "<Key>Return : newline()";
- XtTranslations transTable;
-
- /* in executable section */
-
- transTable = XtParseTranslationTable(newTrans);
-
- /* after creating but before managing text widget */
-
- XtOverrideTranslations(textWidget, transTable);
-
-
- -----------------------------------------------------------------------------
- Subject: 88) Can you reuse the return value from XtParseTranslationTable?
- [Last modified: Nov 96]
-
- Answer: The following is a conversation circa 30 Sep 1996 between Kaleb
- Keithley (kaleb@x.org) and Tim Behrendsen (tim@a-sis.com, tim@airshields.com>.
- The latter suggested this appear in the Motif FAQ.
-
- B> Can the return value from XtParseTranslationTable be saved
- TB> off and reused for the lifetime of the application?
-
- KK> Yes.
-
- TB> Ah! The answer. Thank you.
- KK>
- KK> XtVaSetValues(widget,
- KK> XmNtranslations, XtParseTranslationTable(table), NULL);
-
- TB> which implies it's a one-shot deal (otherwise, this would cause
- TB> a memory leak).
-
- KK> No, you can always retrieve them with Xt(Va)GetValues.
-
- TB> You can, but if you don't and use the technique to wantonly
- TB> create and destroy dialogs, it seems you will get a memory
- TB> leak.
-
- KK> That's correct.
-
- TB> In fact, what's scary is this technique is used in the Motif
- TB> FAQ list; I knew I saw it somewhere reasonably authoritative
- TB> ([approx.] Question 133; code by Dan Heller, O'Reilly and Associates).
- TB> He does the following:
-
- TB> XtOverrideTranslations(bboard,
- TB> XtParseTranslationTable("<Configure>: resize()"));
-
- TB> This has to be unquestionably broken code, if the translation
- TB> tables are never freed or never reused. Obviously, I can't
- TB> extract out the table from overridden translations.
-
- KK> You can't extract the original translations, that's correct.
-
- TB> Come to think of it; how is this handled when translations are
- TB> parsed in resource files? If I have lots of translation
- TB> overrides, do they simply burn up space that can't be reused?
- TB> Does it get burned up over and over as I create widgets that
- TB> use those translation resources?
-
- KK> Yup and yup.
-
-
- -----------------------------------------------------------------------------
- Subject: 89) When I add text to a scrolling text widget, how can I get the
- new text to show?
- [Last modified: Sept 94]
-
- Answer: Use the (fully supported) function XmTextShowPosition:
-
- 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 XmTextGetLastPosition.
-
- position = XmTextGetLastPosition(w)
-
-
- -----------------------------------------------------------------------------
- Subject: 90) How do I scroll text to display the most recently added
- information?
- [Last modified: Aug 95]
-
- Answer: If you're using the XmScrolledText widget, use XmTextSetTopCharacter()
- or XmTextScroll().
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 91) 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: 92) How can I stop the text widget from echoing characters typed? I
- need to turn off echo for password input.
-
- Answer: Use the XmNmodifyVerifyCallback 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: 93) How can I replace characters typed with say a `*'? I want to
- replace input for password entry.
- [Last modified: Nov 96]
-
- Answer: The solution involves the use of XmNmodifyVerifyCallback and then
- examining the XmTextVerifyCallbackStruct. The following program from Dan
- Heller and Paula Ferguson illustrates this:
-
- /* Written by Dan Heller and Paula Ferguson.
- * Copyright 1994, O'Reilly & Associates, Inc.
- * Permission to use, copy, and modify this program without
- * restriction is hereby granted, as long as this copyright
- * notice appears in each copy of the program source code.
- * This program is freely distributable without licensing fees and
- * is provided without guarantee or warrantee expressed or implied.
- * This program is -not- in the public domain.
- *
- * 9Sept1996 RAF -- this is a working version, at least under Sol2.4,
- * using gcc. I only modified check_passwd().
- *
- */
-
- /* password.c -- prompt for a password. 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 <Xm/Text.h>
- #include <Xm/LabelG.h>
- #include <Xm/RowColumn.h>
- #include <ctype.h>
-
- void check_passwd();
- char *passwd; /* store user-typed passwd here. */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- Widget toplevel, text_w, rowcol;
- XtAppContext app;
-
- XtSetLanguageProc (NULL, NULL, NULL);
-
- 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);
- }
-
- /* check_passwd() -- handle the input of a password. */
- void
- check_passwd(text_w, client_data, call_data)
- Widget text_w;
- XtPointer client_data;
- XtPointer call_data;
- {
- char *new;
- char *oldpasswd;
- int len;
- XmTextVerifyCallbackStruct *cbs =
- (XmTextVerifyCallbackStruct *) call_data;
-
- if (cbs->reason == XmCR_ACTIVATE) {
- printf ("4assword: %s0, passwd);
- return;
- }
-
- if( cbs->text->length > 1 ) {
- cbs->doit = False; /* don't allow paste operations; make the */
- return; /* user type the password! */
- }
-
- if( cbs->startPos < cbs->endPos ) {
- /* shrink the password by moving endPos... characters forward to
- /* the point of deletion */
- memmove( &(passwd[cbs->startPos]),
- &(passwd[cbs->endPos]),
- strlen(passwd) - cbs->endPos + 1 );
- if( cbs->text->length == 0 ) /* then just a delete, not a replace */
- return;
- }
-
- new = XtMalloc( cbs->text->length + 1 );
- strncpy( new, cbs->text->ptr, cbs->text->length ); /* just the new chars */
- new[cbs->text->length]=' ';
-
- if( passwd ) {
- /* open a hole for the new characters, and insert them
- /* in the proper place */
- passwd = XtRealloc( passwd, strlen(passwd) + cbs->text->length + 1 );
- memmove( &(passwd[cbs->startPos + cbs->text->length]),
- &(passwd[cbs->startPos]),
- strlen(passwd) - cbs->startPos + 1 );
- memcpy( &(passwd[cbs->startPos]), new, cbs->text->length );
- } else {
- passwd = new;
- }
-
- memset( cbs->text->ptr, '*', cbs->text->length ); /* makes it all stars */
-
- }
-
-
- Thanks to OM1_JDA@pki-nbg.philips.de (Joerg Danne) for alerting me to updating
- this code sample. Thanks also to Russell Fink (rfink@polaris.umuc.edu) for
- providing the Nov. 1996 code update.
-
- -----------------------------------------------------------------------------
- Subject: 94) How can I make a text widget insensitive without graying out the
- text?
- [Last modified: Dec 98]
-
- This is mostly a problem in Motif 1.2 and later, since grayed-out text is
- sometimes difficult to read.
-
- Instead of making the widget insensitive, set XmNeditable to false.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 95) How can I best add a large piece of text to a scrolled text
- widget?
- [Last modified: Sept 94]
-
- [NOTE: This problem is probably only relevant for Motif 1.0 which probably no
- one is using anymore. If you know this to still be a problem, send mail to
- kenton@nojunk.rahul.net. I'll probably remove this question otherwise.]
-
- 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: 96) How can I get the correct colors for scrolled text widget
- scrollbars (Sun only)?
- [Last modified: Nov 97]
-
- Answer: Michael Hall <mhall@semy.com> writes:
-
- I have found a fix to a bug which is common on SUN platforms. The problem is
- that the scroll bars on scrolled text widgets are not colored or shaded
- correctly.
-
-
- scrolledWindowText2 = XtVaCreateManagedWidget("scrolledWindowText2",
- xmScrolledWindowWidgetClass,
- form1,
- XmNscrollBarDisplayPolicy, XmSTATIC,
- NULL );
-
- runValuesText = XtVaCreateManagedWidget("runValuesText",
- xmTextWidgetClass,
- scrolledWindowText2,
- XmNeditMode, XmMULTI_LINE_EDIT ,
- XmNeditable, FALSE,
- NULL );
-
- /* workaround a Motif bug - text widget scroll bars are wrong color,
- and not shaded. */
- /* by Michael Hall */
-
- /* just to get background */
- junkScroll = XmCreateScrollBar(form1, "junkScroll", NULL, 0);
- XtVaGetValues(junkScroll,
- XmNbackground, &junkPixel,
- NULL);
- XtVaGetValues(XtParent(runValuesText),
- XmNchildren, &kids,
- XmNnumChildren, &numkids,
- NULL);
- for (n=0;n<numkids;n++)
- {
- if (XmIsScrollBar(kids[n]))
- {
- XtVaSetValues(kids[n],
- XmNbackground, junkPixel,
- XmNshadowThickness, 30,
- XmNwidth, 200,
- XmNheight, 200,
- NULL);
- XmChangeColor(kids[n], junkPixel);
- }
- }
-
-
- -----------------------------------------------------------------------------
- Subject: 97) How can I highlight text in the Text widget?
-
- Answer: argv@zipcode.com (Dan Heller) wrote:
-
- 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: 98) How can I select all of the text in a widget programmatically?
- So that some initial text is displayed, but anything typed replaces it.
- [Last modified: July 95]
-
- 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.
-
- Jon A. Christopher (jac8792@tam2000.tamu.edu) writes:
-
- I have had difficulty getting this to work as described (even though it agrees
- with the documentation). I believe that it may be because I usually change
- the TextField to some value and then try to select it. I haven't looked at
- the internals of the TextField widget, but it must only select the text if the
- text hasn't changed since the time specified. Ususally the
- "LastTimestampProcessed" will be be *before* you modify the text, and the
- selection is therefore ignored. I'd suggest using the CurrentTime variable.
- This is an X variable which, if used will make sure that your text is always
- selected.
-
- -----------------------------------------------------------------------------
- Subject: 99) Can I customize the pointer cursor or insert position indicator
- used by the text widget?
- [Last modified: May 97]
-
- Answer: No. These are hard coded.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 100) How can I change colours of text in the Text widget? I want
- some of the text in one colour, some in another.
- [Last modified: Feb 98]
-
- Answer: In Motif 1.x, 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.
-
- In the Motif 2.0 CSText widget, XmStrings may be different colors in the same
- widget.
-
- Note, however, that the CSText widget was dropped from Motif 2.1.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 101) How can I change the font of text in the Text widget? I want
- some of the text in one font, some in another.
- [Last modified: Feb 98]
-
- 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.
-
- If you are using Motif 2.0, however, XmStrings are now permitted in CSText
- widgets, which solves this particular problem.
-
- Note, however, that the CSText widget was dropped from Motif 2.1.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- Subject: 102) Is there an emacs binding for the text widget?
-
- Answer: This set is due to Kee Hinckley:
-
- *XmText.translations: #override\n\
- Ctrl <Key>b: backward-character()\n\
- Alt <Key>b: backward-word()\n\
- Meta <Key>b: backward-word()\n\
- Shift Alt <Key>b: backward-word(extend)\n\
- Shift Meta <Key>b: backward-word(extend)\n\
- Alt <Key>[: backward-paragraph()\n\
- Meta <Key>[: backward-paragraph()\n\
- Shift Alt <Key>[: backward-paragraph(extend)\n\
- Shift Meta <Key>[: backward-paragraph(extend)\n\
- Alt <Key><: beginning-of-file()\n\
- Meta <Key><: beginning-of-file()\n\
- Ctrl <Key>a: beginning-of-line()\n\
- Shift Ctrl <Key>a: beginning-of-line(extend)\n\
- Ctrl <Key>osfInsert: copy-clipboard()\n\
- Shift <Key>osfDelete: cut-clipboard()\n\
- Shift <Key>osfInsert: paste-clipboard()\n\
- Alt <Key>>: end-of-file()\n\
- Meta <Key>>: end-of-file()\n\
- Ctrl <Key>e: end-of-line()\n\
- Shift Ctrl <Key>e: end-of-line(extend)\n\
- Ctrl <Key>f: forward-character()\n\
- Alt <Key>]: forward-paragraph()\n\
- Meta <Key>]: forward-paragraph()\n\
- Shift Alt <Key>]: forward-paragraph(extend)\n\
- Shift Meta <Key>]: forward-paragraph(extend)\n\
- Ctrl Alt <Key>f: forward-word()\n\
- Ctrl Meta <Key>f: forward-word()\n\
- Ctrl <Key>d: kill-next-character()\n\
- Alt <Key>BackSpace: kill-previous-word()\n\
- Meta <Key>BackSpace: kill-previous-word()\n\
- Ctrl <Key>w: key-select() kill-selection()\n\
- Ctrl <Key>y: unkill()\n\
- Ctrl <Key>k: kill-to-end-of-line()\n\
- Alt <Key>Delete: kill-to-start-of-line()\n\
- Meta <Key>Delete: kill-to-start-of-line()\n\
- Ctrl <Key>o: newline-and-backup()\n\
- Ctrl <Key>j: newline-and-indent()\n\
- Ctrl <Key>n: next-line()\n\
- Ctrl <Key>osfLeft: page-left()\n\
- Ctrl <Key>osfRight: page-right()\n\
- Ctrl <Key>p: previous-line()\n\
- Ctrl <Key>g: process-cancel()\n\
- Ctrl <Key>l: redraw-display()\n\
- Ctrl <Key>osfDown: next-page()\n\
- Ctrl <Key>osfUp: previous-page()\n\
- Ctrl <Key>space: set-anchor()
-
-
- ! If you'd like the Delete key to work like backspace instead of deleting
- ! backwards, add the following definition to the lines above.
- ! <Key>osfDelete: delete-previous-character()\n\
-
- ! These aren't included because they could intefere with
- | menu accelerators (or vice versa)
- ! Alt <Key>p: backward-paragraph()\n\
- ! Meta <Key>p: backward-paragraph()\n\
- ! Shift Alt<Key>p: backward-paragraph(extend)\n\
- ! Shift Meta<Key>p: backward-paragraph(extend)\n\
- ! Alt <Key>w: copy-clipboard()\n\
- ! Meta <Key>w: copy-clipboard()\n\
- ! Ctrl Alt <Key>w: cut-clipboard()\n\
- ! Ctrl Meta <Key>w: cut-clipboard()\n\
- ! Alt <Key>y: paste-clipboard()\n\
- ! Meta <Key>y: paste-clipboard()\n\
- ! Alt <Key>f: forward-word()\n\
- ! Meta <Key>f: forward-word()\n\
- ! Alt <Key>n: forward-paragraph()\n\
- ! Meta <Key>n: forward-paragraph()\n\
- ! Shift Alt <Key>n: forward-paragraph(extend)\n\
- ! Shift Meta <Key>n: forward-paragraph(extend)\n\
- ! Shift Alt <Key>f: forward-word(extend)\n\
- ! Shift Meta <Key>f: forward-word(extend)\n\
- ! Alt <Key>d: kill-next-word()\n\
- ! Meta <Key>d: kill-next-word()\n\
- ! Alt <Key>h: select-all()\n\
- ! Meta <Key>h: select-all()\n\
-
- Similar sets of translations have been suggested by others.
-
- -----------------------------------------------------------------------------
- Subject: 103) What if I have problems with the backspace/delete keys?
- [Last modified: Dec 94]
-
- Answer: mclarnon@maths.ox.ac.uk (Gerald.McLarnon) writes:
-
- I am running a precompiled program based on motif and am having some problems
- with the backspace/delete keys. Following the instructions of the faq I put th
- e following lines in my .Xdefaults file
-
- *XmText.translations: #override <Key>osfDelete: delete-previous-character()
- *XmTextField.translations: #override <Key>osfDelete: delete-previous-character()
-
- This meant that in dialogue boxes (such as 'Open File') the delete key deleted
- to the left, but not in the main application window.
-
- Any hints for someone who isn't much of an X-pert?
-
- David Kaelbling <drk@x.org> replied:
-
- There are a couple possibilities. In addition to the precedence of loading
- resource files (explained in section 2.3 of the X11R5 X Toolkit Intrinsics
- manual), resource values in the database are chosen based on a "most explicit
- match" algorithm (i.e. those with the most qualifiers on the left hand side
- win -- see section 15.2 of the X11R5 Xlib - C Library manual). So if this
- application's app-defaults file or fallback resources says
- *Foo*XmText.translations:... that value will be used instead of yours.
-
- Find the app-defaults file for your application and look to see if it
- specifies translations for text widgets in the main application; if it does
- you'll need to make yours at least as explicit.
-
- If the app-defaults file isn't the problem then the application may be hard-
- wiring the translations. If that's the case you'll probably have to change
- your virtual key bindings so that the key you think of as osfDelete is really
- osfBackSpace. You can do that for an individual application by setting its
- defaultVirtualBindings resource, or for all Motif applications with a
- $HOME/.motifbind file ("man xmbind" and "man VirtualBindings" give more detail
- and alternatives). In either case you'll need to specify a complete list of
- virtual key bindings; there is no equivalent to #override. To find out your
- current virtual key bindings run "xprop -root | fgrep BINDINGS" and clean up
- the result.
-
- -----------------------------------------------------------------------------
- Subject: 104) 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 file\n", 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!\n");
-
- text[statb.st_size] = 0; /* be sure to NULL-terminate */
-
- /* insert file contents in Text widget */
- XmTextSetString(text_w, text);
-
-
- -----------------------------------------------------------------------------
- Subject: 105) How can put Text in overstrike mode instead of insert?
- [Last modified: Mar 95]
-
- Answer: (Be sure to read the update after the first answer. This is also a
- second update which cautions against the approach.)
-
- 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.
-
- An update was provided by Ingeborg (inca@osf.org):
-
- In 1.2 and later releases, there is an action function toggle-overstrike()
- which will toggle between overstrike and insert mode. Before 1.2.3, there is
- no visual difference, and at most one character will get overstruck. In 1.2.3,
- a block cursor was added as a visual cue to that the widget is in overstrike
- mode, and the code was fixed to overstrike the actual number of characters
- input (this makes a difference if you have preediting - for example in
- japanese).
-
- There is no default binding in 1.2, but the recommended key is osfInsert
- without modifiers. No resource exists.
-
-
- Ed Kaltenbach (kaltenba@ataway.aptec.com) wrote:
-
- I was simulating overstrike mode in the Text Field widget by using
- the delete_next_character solution listed in subject 71.
- When the software is compiled with Motif 1.2.2, the modifyVerify
- callback does not get called for the last character when XmNmaxLength
- is specified. It seems that the check if maxLength has been reached
- is done before the modifyVerify gets called and it keeps the modifyVerify
- from being called. Is this a Motif bug? Does anybody have a solution that
- will work with Versions 1.1 and 1.2 of Motif?
-
-
- Phil Day <phil@cfmu.eurocontrol.be> responded to Ed (and apologized for only
- sending pseudocode!):
-
- I've had the same problem, and for my money it's a bug. My workaround is to
- make all text widgets (I don't use textfield because of some other problems in
- the past) have XmNmaxLength > XmNcolumns, so that the modifyVerify callback
- gets a chance to do its stuff.
-
- If you only want to support overstrike for typing, 1 extra charater is enough,
- but if you want to support cut-and-paste for any length string you need
- maxLength = 2*columns. In the modifyVerify you have to check the result is <
- columns.
-
- I've tried using the Motif 1.2 support for overstrike, but this just seems to
- work on a kind of pending-delete and only works for the single charater
- replacement caes (that's my main argument for calling it a bug).
-
- I don't use delete-next-character (I can't remember why just now, but I know I
- had some problem with it). Instead I have something like the following:
-
- modifyVerify()
- {
- if (acceptable)
- XmReplaceText(...)
-
- cd->doit = False;
- // we've just done it, we don't wnat Motif to !
-
- XtVaSetValues (w,
- XmNverifyBell, False,
- NULL);
- // Otherwise we'll get a beep.
- }
-
- valueChanged()
- {
-
- XtVaSetValues (w,
- XmNverifyBell, True,
- NULL);
- // turned off in modifyVerify
-
- }
-
- Glenn Mandelkern <gmandel@Corp.Megatest.Com> writes about a problem with the
- above solution.
-
-
- We have been running our software on Sparc 20's, under Motif 1.1
- and Motif 1.2, X11R5, Solaris 2.4.
- Unfortunately, some colleagues and I have found a disturbing side effect
- when following this suggestion. Calling XtVaSetValues() in the
- modifyVerifyCallback causes the Text widget to flash.
-
- The O'Reilly guides say not to call XtVaSetValues() during text
- modification callbacks. Motif Volume 6 has this on page 511 and
- Motif Volume 6A has it on page 496.
-
- I myself thought it would be fairly trivial to just switch the bell
- on and off. But since XtVaSetValues() calls XmText's set_values() method,
- my guess is that its set_values() does something that causes this.
-
- So when you enter characters, the Text widget flashes. It also slows
- down the performance of the Text widget. You'll see this on a multi-line
- Text widget, especially with it occupying a full screen with text.
-
- If you want to see this, take the editor.c program in Volume 6 or 6A,
- then add a modifyVerifyCallback to the text_output widget. Then inside
- that callback, call XtVaSetValues with the XmNverifyBell like above.
-
- This is a common "mistake", one which I've done more than once.
- I remember also that when I did not have the XtVaSetValues() in place,
- I got the beeps.
-
- So now we've reworked the application as follows:
- 1. The Text widget is initially created with XmNverifyBell
- set to False.
-
- 2. We ring the bell using XBell() when we detect a condition
- for which we want to veto text modifications.
-
- For our application, this provides the wanted feedback and gets rid
- of the flashes.
-
-
- -----------------------------------------------------------------------------
- Subject: 106) How can I make the Delete key do a Backspace? Related
- question: How can I swap Delete and Backspace?
- [Last modified: Oct 94]
-
- Answer: Put this in your .Xdefaults
-
- *XmText.translations: #override <Key>osfDelete: delete-previous-character()
-
-
- Additional information from David Kaelbling <drk@x.org>:
-
- You can also supply an arbitrary file name to xmbind (so you can conditionally
- run xmbind from your .xinitrc file based on the hostname, architecture,
- xdpyinfo output, or whatever).
-
- Some people prefer to use xmodmap to swap the keysyms for all applications,
- but what you're doing will work fine if you specify all of the virtual key
- bindings. The current bindings are stored on the root window -- use "xprop
- -root" and look for a _MOTIF_BINDINGS or _MOTIF_DEFAULT_BINDINGS property.
- OSF/Motif is also distributed with a "bindings" directory containing all the
- fallback virtkey binding files.
-
- There are several ways to do display-specific customization: make
-
- -----------------------------------------------------------------------------
- Subject: 107) Can I change the tab stops in the XmText widget?
- [Last modified: May 95]
-
- Answer: No.
-
- Ken Lee
-
- -----------------------------------------------------------------------------
- END OF PART FOUR
-