Skip to main content

Full text of "X Toolkit Intrinsics programming manual"

See other formats


The Definitive Guides 
to the X Window System 

Volume Four 

I I I 

X Toolkit Intrinsics 
Programming Manual 

OSF/Motif Edition 

by Adrian Nye and Tim O'Reilly 

O'Reilly & Associates, Inc. 

I III,AI,Y ('()PY 



Volume Four 

X Toolkit Intrinsics 

Programming Manual 

OSF/Motif 1.1 Edition 
for X11, Release 4 

by Adrian Nye and Tim O'Reilly 

O'Reilly & Associates, Inc. 



X Protocol Reference Manual, R-4 Release, 500 pages 
Describes the X Network Protocol which underlies all software for Version l I of the X Window System. 
Xlib Programming Manual, R-4 Release, 672 pages 
Xlib Reference Manual, R-4 Release, 792 pages 
Complete programming and reference guides to the X library (Xlib), the lowest level of programming 
interface to X. 
g Window System User's Guide, R-4 Release 
Orients the new user to window system concepts, provides detailed tutorials for many client programs, and 
explains how to customize the X environment. 
Standard Edition, 752 pages 
Motif Edition, 734 pages 
X Toolkit Intrinsics Programming Manual, R-4 Release 
Complete guide to programming with Xt Intrinsics, the library of C language routines that facilitate the design 
of user interfaces, with reusable components called widgets. 
Standard Edition, 624 pages 
Motif Edition, 666 pages 
X Toolkit Intrinsics Reference Manual, R-4 Release, 776 pages 
Complete programmer's reference for the X Toolkit. 
Motif Programming Manual, Motif 1.1, 1032 pages 
Complete guide to programming for the Motif graphical user interface. 
XView Programming Manual, XView Version 3.0, 768 pages 
XView Reference Manual, 266 pages 
Complete information on programming with XView, an easy-to-use toolkit that is widely available. 
The X Window System in a Nutshell, R-3 and R-4 Release, 380 pages 
A single-volume quick reference that is an indispensable companion to the series. 

Contact us for a catalog of our books, for orders, or for more information. 
O'Reilly & Associates, Inc. 

632 Petaluma Avenue, Sebastopol CA 95472 
(800) 338-6887 US/Canada 707-829-0515 overseas/local 707-829-0104 Fax 



Table of Contents 

Page 

Preface ..................................................................................................................................... xxv 

Summary of Contents ................................................................................................................ xxv 
Assumptions .............................................................................................................................. xxvi 
Related Documents .................................................................................................................. xxvi 
How to Use This Manual ........................................................................................................ xxvii 
Font Conventions Used in This Manual ................................................................................... xxx 
Request for Comments .............................................................................................................. xxx 
Bulk Sales Information ............................................................................................................ xxxi 
Obtaining the X Window System Software ............................................................................ xxxi 
Obtaining Motif ........................................................................................................................ xxxi 
Obtaining the Example Programs ............................................................................................ xxxi 
Acknowledgments ................................................................................................................... xxxii 

1 Introduction to the X Window System .................................................................. 3 

1.1 The Server and Client ............................................................................................................. 7 
1.2 The Software Hierarchy ......................................................................................................... 9 
1.3 Event-driven PrOgramming .................................................................................................. 11 
1.4 The Window Manager .......................................................................................................... 12 
1.5 Extensions to X ..................................................................................................................... 13 

2 Introduction to the X Toolkit and Motif ............................................................ 17 

2.1 Programming with Widgets ................................................................................................. 17 
2.1.1 About Widget Sets ......................................................................................................... 20 
2.1.2 Widget Classes and Instances ....................................................................................... 22 
2.1.3 Widget Configurability with Resources ....................................................................... 25 
2.1.4 Widget Independence .................................................................................................... 27 
2.1.5 Widget-Application Interaction ................................................................................... 29 
2.1.6 Xt and Object-oriented Programming (OOP) .............................................................. 32 
2.1.6.1 The Object ................................................................................................................. 32 
2.1.6.2 Methods ..................................................................................................................... 33 
2.1.6.3 Messages ................................................................................................................... 33 
2.1.6.4 Encapsulation ............................................................................................................ 33 
2.2 Structure of Motif Applications .......................................................................................... 34 
2.3 A Simple X Toolkit Application .......................................................................................... 35 



2.3.1 The Code ........................................................................................................................ 36 
2.3.2 Compiling the Application ........................................................................................... 39 
2.3.3 The App-defaults File ................................................................................................... 39 
2.3.4 To Hardcode or Not to Hardcode ................................................................................. 43 
2.4 Connecting Widgets to Application Code .......................................................................... 44 
2.4.1 Callbacks ........................................................................................................................ 45 
2.5 More About Resources ......................................................................................................... 49 
2.5.1 Setting and Getting Resources from the Application ................................................. 49 
2.5.1.1 Setting Resources with the Varargs Interfaces ....................................................... 50 
2.5.1.2 Setting Resources with the ArgList Interfaces ....................................................... 51 
2.5.1.3 Getting a Resource Value ........................................................................................ 53 
2.5.2 Core Resources .............................................................................................................. 54 
2.5.3 Other Inherited Resources ............................................................................................ 57 
2.6 Advice on X Programming .................................................................................................. 60 

3 More Techniques for Using Widgets .................................................................... 63 

3.1 Using Composite Widgets ................................................................................................... 63 
3.1.1 Setting Resources for an Instance Hierarchy .............................................................. 66 
3.1.2 Geometry Management in Practice .............................................................................. 67 
3.2 Using Constraint Widgets .................................................................................................... 71 
3.3 The Standard Motif Instance Hierarchy .............................................................................. 74 
3.3.1 Motif Widget Creation Routines .................................................................................. 75 
3.3.2 Building a Main Window .............................................................................................. 75 
3.4 Using Popups ........................................................................................................................ 78 
3.4.1 Creating a Basic Menu .................................................................................................. 79 
3.4.2 Creating a Basic Dialog Box ........................................................................................ 81 
3.4.3 Popup Window Hierarchy ............................................................................................. 85 
3.5 More About Callbacks ......................................................................................................... 86 
3.5.1 Passing Data to Callback Functions ............................................................................. 87 
3.5.1.1 The client_data Argument ....................................................................................... 87 
3.5.1.2 The call_data Argument ........................................................................................... 89 
3.5.2 Callback Lists ................................................................................................................ 90 
3.6 Application Resources ......................................................................................................... 91 
3.6.1 The Application Data Structure .................................................................................... 92 
3.6.2 The Resource List .......................................................................................................... 92 
3.6.3 Getting the Resources ................................................................................................... 96 
3.7 Command-line Options ........................................................................................................ 97 
3.7.1 Standard Command-line Options ................................................................................. 98 
3.7.2 Defining Your Own Command-line Options ............................................................... 99 
3.8 Preventing User Customization of Widget Resources ..................................................... 103 
3.8.1 Using the Varargs Interfaces ...................................................................................... 104 
3.8.2 Using the Argument List Interfaces ........................................................................... 106 
3.8.2.1 Another Way to Set Arguments ............................................................................. 107 
3.8.2.2 Merging Argument Lists ........................................................................................ 109 
3.9 More About Application Contexts .................................................................................... 109 



4 An Example Application .......................................................................................... 113 

4.1 xbitmapl: Bitmap Editor Using a BitmapEdit Widget ................................................... 114 
4.1.1 XBitmapl App-defaults File ...................................................................................... 118 
4.2 xbitmap2: Adding Graphics to Display the Bitmap ........................................................ 119 
4.2.1 Exposure Strategy ........................................................................................................ 121 
4.2.2 Graphics from the Application ................................................................................... 124 
4.2.3 Writing a Bitmap File .................................................................................................. 127 
4.3 xbitmap3: Another Way to Create a Custom Window ................................................... 129 
4.3.1 Actions ......................................................................................................................... 129 
4.3.1.1 The Actions Table .................................................................................................. 131 
4.3.1.2 Format of an Action Function ............................................................................... 132 
4.3.2 Translations .................................................................................................................. 133 
4.3.2.1 The Translation Table ............................................................................................. 133 
4.3.2.2 Hardcoding Translations ........................................................................................ 136 
4.3.2.3 Action Parameters .................................................................................................. 137 
4.3.3 Adding Actions to Existing Widgets ......................................................................... 137 
4.4 xbitmap4: A Bitmap Editor Without a BitmapEdit Widget ........................................... 138 

5 More About Motif ....................................................................................................... 151 

5.1 The Remaining Motif Widgets and Gadgets .................................................................... 151 
5.1.1 Geometry Managing Widgets ..................................................................................... 157 
5.1.2 Dialog Widgets ............................................................................................................ 159 
5.2 Widget Creation Functions ................................................................................................ 160 
5.3 Compound Strings and Font Lists ..................................................................................... 162 
5.3.1 Simple Compound Strings .......................................................................................... 162 
5.3.2 Character Sets and Font Lists ..................................................................................... 164 
5.3.3 Strings with Multiple Fonts ........................................................................................ 166 
5.3.4 Manipulating Compound Strings ............................................................................... 168 
5.3.5 Converting Compound Strings to Text ...................................................................... 169 
5.3.6 Rendering Compound Strings .................................................................................... 169 
5.4 Pixmap and Image Caching Functions ............................................................................. 169 
5.5 Dynamic Resource Defaulting .......................................................................................... 171 
5.6 Resolution Independence ................................................................................................... 172 
5.7 Keyboard Traversal and Focus .......................................................................................... 173 
5.8 Motif Virtual Keyboard Bindings ..................................................................................... 174 
5.9 The Motif User Interface Language .................................................................................. 175 

6 Inside a Widget ............................................................................................................. 183 

6.1 Widget Source File Organization ...................................................................................... 184 
6.2 The Private Header File--BitmapEdiP.h ......................................................................... 185 
6.2.1 Parts and Records ........................................................................................................ 185 
6.2.2 Class Part and Class Record ....................................................................................... 186 
6.2.3 Instance Part and Instance Record ............................................................................. 187 



6.3 The Widget Implementation FilemBitmapEdit.c ........................................................... 189 
6.3.1 Obligatory Include Files ............................................................................................. 190 
6.3.2 Defining the Resource List ......................................................................................... 191 
6.3.3 The Translation Table and Actions Table .................................................................. 194 
6.3.4 Declaring Methods ...................................................................................................... 196 
6.3.5 Initializing the Class Record ...................................................................................... 197 
6.3.5.1 The Core Class Part ................................................................................................ 197 
6.3.5.2 Initializing the Core Methods ................................................................................ 200 
6.3.6 Description of Core Methods ..................................................................................... 202 
6.3.7 Packaging the Class Record for Application Use ..................................................... 204 
6.3.8 A Sample Method ........................................................................................................ 204 
6.4 The Public Header FilemBitmapEdit.h ........................................................................... 207 
6.5 The Process of Widget Writing ......................................................................................... 209 
6.6 Summary of Conventions ................................................................................................... 211 

7 Basic Widget Methods ............................................................................................... 215 

7.1 The 
7.2 The 
7.2.1 
7.3 The 
7.4 The 
7.5 The 
7.6 The 

X Graphics Model Inside Widgets ............................................................................. 216 
initialize Method ......................................................................................................... 216 
Creating GCs ............................................................................................................... 219 
expose Method ............................................................................................................ 221 
set_values Method ...................................................................................................... 225 
resize Method .............................................................................................................. 227 
query_geometry Method ............................................................................................ 230 

7.7 The destroy Method ............................................................................................................ 233 
7.8 Actions in the Widget Framework .................................................................................... 234 

8 Events, Translations, and Accelerators .............................................................. 239 

8.1 Translation Table Syntax .................................................................................................... 240 
8.1.1 The Directive ............................................................................................................... 241 
8.1.2 Selecting the Events to Translate ............................................................................... 241 
8.1.3 Details in Keyboard Events ........................................................................................ 244 
8.1.4 Details in Other Event Types ...................................................................................... 245 
8.1.5 Modifiers ...................................................................................................................... 247 
8.1.5.1 Physical Keys Used as Modifiers .......................................................................... 248 
8.1.5.2 Default Interpretation of the Modifier List ........................................................... 250 
8.1.5.3 Prohibiting a Modifier ............................................................................................ 250 
8.1.5.4 Requiring an Exact Match ..................................................................................... 251 
8.1.5.5 Paying Attention to the Case of Keysyms ............................................................ 251 
8.1.6 Event Sequences .......................................................................................................... 252 
8.1.6.1 Special Considerations Involving Motion Events ............................................... 253 
8.1.6.2 Modifiers and Event Sequences ............................................................................ 253 
8.1.6.3 Using Modifiers to Specify Button Event Sequences .......................................... 254 
8.1.6.4 Key Event Sequences ............................................................................................. 254 
8.1.7 Interactions Between Translations ............................................................................. 254 

viii 



8.1.7.1 Translations in Multiple Resource Files ............................................................... 255 
8.1.7.2 Order of Translations .............................................................................................. 255 
8.1.7.3 Event Sequences Sharing Initial Events ............................................................... 256 
8.1.7.4 Event Sequences Sharing Noninitial Events ........................................................ 256 
8.2 Accelerators and Mnemonics ............................................................................................ 257 
8.2.1 Xt Accelerators ............................................................................................................ 257 
8.2.2 Event Propagation ....................................................................................................... 259 
8.2.3 Installing Accelerators in Multiple Widgets ............................................................. 261 
8.2.4 Defining the Accelerator Table in the Code .............................................................. 262 
8.2.5 Motif Accelerators and Mnemonics ........................................................................... 263 
8.2.5.1 Mnemonics .............................................................................................................. 263 
8.2.6 The display_accelerators Method .............................................................................. 264 

9 More Input Techniques ............................................................................................. 267 

9.1 Event Handlers .................................................................................................................... 268 
9.1.1 Adding Event Handlers ............................................................................................... 271 
9.1.2 Adding Nonmaskable Event Handlers ....................................................................... 272 
9.1.3 Removing Event Handlers .......................................................................................... 273 
9.1.4 Adding Raw Event Handlers ...................................................................................... 274 
9.2 Writing Routines That Use Specific Event Data .............................................................. 274 
9.2.1 Event Types and Structure Names .............................................................................. 276 
9.3 File, Pipe, and Socket Input ............................................................................................... 278 
9.3.1 Geuing File Input ........................................................................................................ 278 
9.3.2 Getting Pipe Input ....................................................................................................... 280 
9.4 Timeouts .............................................................................................................................. 281 
9.4.1 Visibility Interest ......................................................................................................... 284 
9.5 Work Procedures ................................................................................................................. 286 
9.6 Low-level Management of the Event Queue .................................................................... 288 
9.6.1 XtPending and XtPeekEvent ...................................................................................... 288 
9.6.2 Event Filters ................................................................................................................. 289 
9.6.3 Input Sensitivity .......................................................................................................... 290 

10 Resource Management and Type Conversion .............................................. 293 

10.1 Review of Resource Fundamentals ................................................................................. 294 
10.2 How the Resource Database Works ................................................................................ 297 
10.2.1 Form of Resource Specifications ............................................................................. 298 
10.2.2 Merging of Resource Files ....................................................................................... 300 
10.2.3 The Language String ................................................................................................. 302 
10.2.4 Fallback Resources ................................................................................................... 304 
10.2.5 Resource Matching Algorithm ................................................................................. 305 
10.2.6 Resource Precedence Rules ...................................................................................... 307 
10.3 Type Conversion ............................................................................................................... 311 
10.3.1 Conversions from XmRString .................................................................................. 311 
10.3.2 Other Built-in Type Conversions ............................................................................. 313 



10.3.3 Special Resource Defaults That Do Not Use Conversion ...................................... 314 
10.3.4 Registering Type Converters .................................................................................... 316 
10.3.4.1 Passing Arguments to a Type Converter ............................................................ 319 
10.3.5 Explicitly Invoking a Converter ............................................................................... 321 
10.3.6 Writing a Type Converter ......................................................................................... 323 
10.3.6.1 Defining the Default Value .................................................................................. 324 
10.4 Subparts and Subresources .............................................................................................. 325 
10.4.1 The Hook Methods .................................................................................................... 325 
10.4.2 Managing Subresources ............................................................................................ 326 

11 Interclient Communications ................................................................................ 331 

11.1 Window Manager Interactions ........................................................................................ 332 
11.1.1 Shell Subclasses ........................................................................................................ 332 
11.1.2 Setting Shell Resources ............................................................................................ 333 
11.1.3 Screen Space .............................................................................................................. 335 
11.1.4 Input Model ............................................................................................................... 337 
11.1.5 Colormaps .................................................................................................................. 338 
11.1.6 Icons ........................................................................................................................... 340 
11.1.7 Window Manager Decorations ................................................................................. 342 
11.1.8 Interacting With the Motif Window Manager ........................................................ 342 
11.1.8.1 WM_PROTOCOLS ............................................................................................. 343 
11.1.8.2 _MOTIF_WM_MESSAGES ............................................................................... 343 
11.1.8.3 _MOTIF_WM_HINTS ........................................................................................ 344 
11.2 Selections: Widget-to-Widget Communication ............................................................ 344 
11.2.1 How Atomic Selection Works .................................................................................. 346 
11.2.2 Highlighting the Selected Data (Owner) ................................................................. 349 
11.2.3 Making the Selection with XtOwnSelection (Owner) ........................................... 354 
11.2.4 Requesting the Selection (Requestor) ..................................................................... 355 
11.2.4.1 Possible Target Type Atoms ................................................................................ 356 
11.2.4.2 The Paste Action from BitmapEdit ..................................................................... 358 
11.2.5 Converting the Selection (Owner) ........................................................................... 358 
11.2.6 Finally Pasting the Selection (Requestor) ............................................................... 360 
11.2.7 If the Selection is Lost (Owner) ............................................................................... 362 
11.2.8 When the Selection Transfer is Complete (Owner) ................................................ 363 
11.2.9 ICCCM Compliance ................................................................................................... 363 
11.2.9.1 Xmu Atom Caching ............................................................................................. 365 
11.2.9.2 Converting the Standard Selections .................................................................... 365 
11.2.10 How Incremental Selection Works ........................................................................ 367 
11.2.11 Miscellaneous Selection Routines ......................................................................... 368 
11.3 Motif Cut and Paste Functions and the Clipboard ......................................................... 369 



12 Geometry Management ......................................................................................... 373 

12.1 How Composite Management Works ............................................................................. 374 
12.1.1 Initial Geometry Negotiation ................................................................................... 376 
12.1.2 User Resizes the Application ................................................................................... 379 
12.1.3 Widget Desires a Size Change ................................................................................. 379 
12.1.4 Application Resizes a Widget .................................................................................. 381 
12.2 Writing a Composite Widget ........................................................................................... 382 
12.2.1 Basic Core Methods in Composite Widgets ............................................................ 384 
12.2.2 Laying Out Child Widgets ........................................................................................ 386 
12.2.3 The change_managed Method ................................................................................. 388 
12.2.4 The geometry_manager Method .............................................................................. 388 
12.2.5 XtQueryGeometry and the query_geometry Method ............................................. 389 
12.2.6 XtMakeGeometryRequest and the geometry_manager Method ........................... 390 
12.2.7 The insert_child and delete_child Methods ............................................................ 391 
12.3 How Constraint Management Works .............................................................................. 392 
12.4 Writing a Constraint Widget ............................................................................................ 392 
12.4.1 The Core Resource List ............................................................................................ 393 
12.4.2 The Constraint Resource List ................................................................................... 394 
12.4.3 Class Structure Initialization .................................................................................... 396 
12.4.4 The Constraint initialize Method ............................................................................. 398 
12.4.5 The class_part_init Method ...................................................................................... 399 
12.4.6 The geometry_manager Method .............................................................................. 400 
12.4.7 The resize Method ..................................................................................................... 404 
12.4.8 The Core and Constraint set_values Methods ......................................................... 406 
12.4.9 The change_managed Method ................................................................................. 407 
12.4.10 The query_geometry Method ................................................................................. 408 
12.4.11 Delaying. Geometry Recalculation ......................................................................... 408 
12.5 Compound Widgets .......................................................................................................... 409 
12.6 Stacking Order .................................................................................................................. 410 

13 Menus, Gadgets, and Cascaded Popups .......................................................... 413 

13.1 Menu Styles and Implementation .................................................................................... 415 
13.2 Using Motif Menus .......................................................................................................... 416 
13.2.1 Popup Menus ............................................................................................................. 417 
13.2.2 Cascaded Menus ........................................................................................................ 418 
13.3 Basic Xt Popup Support ................................................................................................... 419 
13.3.1 A Spring-loaded Menu: Pointer Grabbing ............................................................. 420 
13.3.2 A Pulldown Menu ..................................................................................................... 428 
13.3.3 Cascaded Menus ........................................................................................................ 431 
13.3.4 Using the R4 SimpleMenu Widget .......................................................................... 436 
13.3.5 Delayed Popup Creation ........................................................................................... 440 
13.4 About Dialog Boxes ......................................................................................................... 441 
13.5 Gadgets .............................................................................................................................. 442 
13.5.1 Inside a Gadget .......................................................................................................... 445 
13.5.2 Private Header File .................................................................................................... 445 



13.5.3 The Gadget Source File ............................................................................................ 447 
13.5.4 The Public Header File ............................................................................................. 448 
13.5.5 The Gadget Parent ..................................................................................................... 448 

14 Miscellaneous Toolkit Programming Techniques ....................................... 455 

14.1 
14.2 
14.3 
14.4 
14.5 
14.6 
14.7 
14.8 

Errors and Warnings ......................................................................................................... 455 
Objects ............................................................................................................................... 458 
Macros For Getting Information ..................................................................................... 459 
The accept_focus Method and the Keyboard Focus ...................................................... 461 
Keyboard Interpretation ................................................................................................... 462 
Memory Allocation .......................................................................................................... 463 
Action Hooks and Calling Actions Directly .................................................................. 464 
Xt Grabbing Functions ..................................................................................................... 464 

14.9 File Finding and Internationalization ............................................................................. 465 
14.10 Application Contexts ..................................................................................................... 465 
14.10.1 Multiple Application Contexts ............................................................................... 466 
14.10.2 Rewriting XtAppMainLoop for Multiple Application Contexts ......................... 467 
14.10.3 Functions Used with Multiple Application Contexts ........................................... 468 
14.11 Multiple Top-level Shells .............................................................................................. 468 
14.12 Connecting to Multiple Servers .................................................................................... 468 
14.13 Class Extension Structures ............................................................................................ 469 

A Athena, OPEN LOOK, and Motif ........................................................................ 473 

A. 1 The AT&T OPEN LOOK Widgets ..................................................................................... 477 
A. 1.1 Application Controls .................................................................................................. 478 
A. 1.1.1 Command Buttons ................................................................................................. 478 
A. 1.1.2 Exclusive and Nonexclusive Settings .................................................................. 480 
A. 1.1.3 Analog Controls ..................................................................................................... 482 
A.1.2 Composite Widgets .................................................................................................... 482 
A.1.2.1 Menus and Control Areas ..................................................................................... 482 
A. 1.2.2 General Purpose Composite Widgets .................................................................. 483 
A.1.2.3 Scrollbars and Scrollable Windows ..................................................................... 483 
A.1.3 Popups ......................................................................................................................... 485 
A. 1.4 Text Widgets ............................................................................................................... 487 
A.1.5 Drawing Areas ............................................................................................................ 487 
A.2 The OSF/Motif Widgets .................................................................................................... 487 
A.2.1 Application Controls .................................................................................................. 490 
A.2.1.1 Command Buttons ................................................................................................. 490 
A.2.1.2 Analog Controls ..................................................................................................... 490 
A.2.2 Composite Widgets .................................................................................................... 491 
A.2.2.1 Menus and Control Areas ..................................................................................... 491 
A.2.2.2 General Purpose Composite Widgets .................................................................. 494 
A.2.2.3 Scrollable Windows .............................................................................................. 495 
A.2.3 Popups ......................................................................................................................... 496 



A.2.4 Text Widgets ............................................................................................................... 497 
A.2.5 Drawing Areas ............................................................................................................ 497 

B Specifying Fonts and Colors .................................................................................. 501 

B.1 Color Specification ............................................................................................................ 501 
B.I.1 Color Names ................................................................................................................ 501 
B. 1.2 Hexadecimal Color Specification .............................................................................. 502 
B. 1.2.1 The RGB Color Model .......................................................................................... 503 
B. 1.2.2 How Many Colors are Available? ........................................................................ 504 
B.2 Font Specification .............................................................................................................. 506 
B.2.1 Font Naming Conventions ......................................................................................... 507 
B.2.2 Font Name Wildcarding ............................................................................................. 508 
B.2.3 Font Name Aliasing .................................................................................................... 510 
B.2.4 Making the Server Aware of Aliases ........................................................................ 511 
B.2.5 The fonts.dir Files ....................................................................................................... 511 
B.3 Window Geometry ............................................................................................................. 512 

C Naming Conventions ................................................................................................. 517 

D Release Notes ................................................................................................................ 521 

D.1 Summary of New Functions and Procedure Types ......................................................... 521 
D.2 Application Writing ........................................................................................................... 524 
D.2.1 New Function for Initializing an Application .......................................................... 524 
D.2.2 Varargs Interfaces ....................................................................................................... 524 
D.2.2.1 Special Types for Varargs List Members ............................................................. 525 
D.2.3 Loading the Resource Database ................................................................................ 525 
D.2.3.1 The Language String ............................................................................................. 525 
D.2.3.2 New Built-In Application Resources ................................................................... 526 
D.2.3.3 Fallback Resources ................................................................................................ 526 
D.2.4 Parsing the Command Line ........................................................................................ 526 
D.3 Changes Affecting Both Application and Widget Writing ............................................ 527 
D.3.1 Actions ........................................................................................................................ 527 
D.3.1.1 Directly Invoking Actions .................................................................................... 527 
D.3.1.2 Action Hook Regislxation ..................................................................................... 527 
D.3.1.3 Obtaining Event Information in an Action Procedure ........................................ 527 
D.3.1.4 Registering Button and Key Grabs For Actions ................................................. 528 
D.3.1.5 Action Functions and Unrealized Widgets .......................................................... 528 
D.3.2 Reserved Names for Resources and Actions ............................................................ 528 
D.3.3 Resource String Identifier Convention ..................................................................... 528 
D.3.4 Resource File Format ................................................................................................. 528 
D.3.5 Modifier Names .......................................................................................................... 529 
D.3.6 Determining Specification Revision Level ............................................................... 529 

x 



D.4.13.6 Finding File Names ............................................................................................. 548 
D.4.13.7 Improved Multi-display Support in Xmu .......................................................... 548 

E The xbitmap Application ........................................................................................ 551 

E.1 The BitmapEdit Widget ..................................................................................................... 551 
E.2 The BitmapEdiP.h Private Header File ............................................................................ 564 
E.3 The BitmapEdit.h Public Header File ............................................................................... 566 
E.4 xbitmap5 ............................................................................................................................. 567 

F Sources of Additional Information ..................................................................... 575 

F.1 Getting the X Software ...................................................................................................... 575 
F.I.1 Bug Fixes ..................................................................................................................... 576 
F. 1.1.1 Notes ....................................................................................................................... 578 
F. 1.1.2 Fairness ................................................................................................................... 578 
F.2 Nemews ............................................................................................................................... 579 
F.3 Training and Consulting ..................................................................................................... 579 
F.3.1 Phone Support ............................................................................................................. 580 
F.4 The X Consortium .............................................................................................................. 580 
F.5 Finding Out for Yourself .................................................................................................... 581 

Glossary .................................................................................................................................. 585 

Master Index .....  .................................................................................................................. 607 

XV 



Figures 

Page 

1-1 An X application, and an application on a traditional text terminal ................................. 4 
1-2 A three-button mouse directing the pointer to select a menu item .................................... 5 
1-3 Screen layout of a typical user's X Window System .......................................................... 6 
1-4 Applications can run on any system across the network .................................................... 8 
1-5 The software architecture of Xt Intrinsics-based applications ........................................ 10 
2-1 A widget-based application ................................................................................................ 18 
2-2 A Motif widget-based application ..................................................................................... 21 
2-3 Two ways to think about a class ......................................................................................... 23 
2-4 Class hierarchy of the Motif widget set ............................................................................. 24 
2-5 Several Label widgets configured using resources ........................................................... 26 
2-6 Widgets operate independently of the application ........................................................... 28 
2-7 XtSetValues lets the application set how a widget will operate itself ............................ 29 
2-8 Application registers a function with Xt during startup phase ........................................ 30 

2-9 Xt calls the function during the event-loop phase in response to an occurrence ........... 31 
2-10 xhello: appearance on screen .......................................................................................... 35 
2-11 The appearance of xgoodbye when the pointer is in the window ................................. 46 
2-12 xgoodbye run with new resource settings ....................................................................... 58 
3-1 xrowcolumn: appearance on the screen ............................................................................ 64 
3-2 Two configurations of xrowcolumn ................................................................................... 67 
3-3 Results upon resize of ScrollBar widgets inside a RowColumn widget ......................... 69 
3-4 The xmh application and its instance hierarchy ............................................................... 70 
3-5 Effect of the Form XmATI'ACH_WIDGET constraint resource .................................... 73 
3-6 xmainwindow: an application with standard Motif screen layout .................................. 74 
3-7 xmainwindow with the File pulldown menu displayed .................................................... 79 
3-8 xmainwindow with the Help dialog box displayed .......................................................... 82 
3-9 The widget instance and X window hierarchies are different only for popups .............. 86 
4-1 xbitmapl: how it looks on the screen ............................................................................. 114 
4-2 xbitmap2: true-scale normal and reverse bitmaps added .............................................. 120 
4-3 Application draws into Pixmap and copies it to widget window .................................. 121 
4-4 Two-stage mapping with translation table and action table .......................................... 130 
5-1 A Command widget .......................................................................................................... 152 
5-2 A FileSelectionBox widget .............................................................................................. 153 
5-3 A SelectionBox widget ..................................................................................................... 154 
5-4 A Text and TextFicld widgcts .......................................................................................... 154 
5-5 A menu containing buttons separated by Separator widgets ......................................... 155 
5-6 ToggleButton widgets used in a RadioBox and a CheckBox ........................................ 156 
5-7 A Scale widget .................................................................................................................. 156 
5-8 A List widget containing PushButtonGadgets ................................................................ 158 
5-9 Dialog boxes with the five standard symbols .................................................................. 159 
5-10 multi_font: how it looks on the screen .......................................................................... 167 
6-1 The class hierarchy of the BitmapEdit widget (with other classes shown dotted) ....... 186 
6-2 Order of code in widget .c file .......................................................................................... 190 



7-1 

8-1 
8-2 
9-1 
10-1 
10-2 
10-3 
11-1 
11-2 
12-1 
12-2 
12-3 
12-4 
12-5 
12-6 
13-1 

compress_exposure: 2 rectangles if XtExposeNoCompress; bounding box 
and region if XtExposeCompressSeries or XtExposeCompressMultiple ...................... 224 
xbox 1: two Command widgets in a Box ........................................................................ 258 
Key event propagation in xbox ........................................................................................ 260 
xtetris in play ..................................................................................................................... 282 
Typical resource setting search path on UNIX-based systems .................................... 302 
The quit widget in a sample widget hierarchy .............................................................. 305 
Steps in matching resource entries for one resource of widget being created ........... 310 
An icon with and without an icon pixmap .................................................................... 340 
The process of selection transfer ................................................................................... 348 
Role of border width in widget geometry ..................................................................... 375 
Initial geometry negotiation, assuming sufficient shell space ..................................... 377 
Initial geometry negotiation, if resizing is necessary ................................................... 378 
A widget requesting a size change ................................................................................ 380 
A ScrollBox widget at two different sizes .................................................................... 383 
Geometry negotiation by the set_values_almost method ............................................ 391 
Athena Command widgets in an Athena Box widget, 

and the same commands as a Motif menu ....................................................................... 414 

13-2 
13-3 
13-4 
13-5 
13-6 
A-1 
A-2 
A-3 
A-4 
A-5 
A-6 
A-7 
A-8 
A-9 
A-10 
A-11 
A-12 
A-13 
A-14 
A-15 
A-16 
A-17 
A-18 
A-19 
A-20 
B-1 
B-2 

xmenul: application with spring-loaded popup menu ................................................ 423 
xmenu2: a pulldown menu ............................................................................................ 428 
xmenu5: cascaded spring-loaded menus ...................................................................... 432 
xmenu7: a menu using the Athena SimpleMenu widget ............................................ 437 
Class hierarchy derivation of Core ................................................................................ 444 
An OPEN LOOK application ............................................................................................ 477 
Class inheritance hierarchy of the AT&T OPEN LOOK widgets .................................. 479 
An OPEN LOOK ControlArea with OblongButton and ButtonStack widgets ............. 480 
OPEN LOOK RectButtons controlled by Exclusives and Nonexclusives widgets ....... 481 
An OPEN LOOK CheckBox widget ................................................................................. 482 
An OPEN LooK Slider widget ........................................................................................ 482 
An OPEN LOOK Scrollbar ................................................................................................ 484 
An OPEN LOOK ScrollingList widget ............................................................................. 484 
An OPEN LOOK Notice .................................................................................................... 485 
An OPEN LOOK PopupWindow .................................................................................... 486 
An OPEN LOOK Help window ...................................................................................... 486 
Look and feel of a Motif application ............................................................................ 488 
Class inheritance hierarchy of the Motif widget set .................................................... 489 
Motif DrawnButton and PushButton widgets .............................................................. 490 
A Motif RowColumn widget configured as a MenuBar ............................................. 492 
A Motif RowColumn widget configured with four RadioBoxes ................................ 492 
A Motif RowColumn widget configured as a pulldown menu ................................... 493 
A Motif Form widget and children ............................................................................... 494 
A Motif ScrollBar .......................................................................................................... 495 
A Motif SelectionBox .................................................................................................... 496 
Multiple planes used to index a colormap ...................................................................... 505 
A font name ....................................................................................................................... 507 

xv// 



Examples 

Page 

2-2 XHello: the app-defaults file ............................................................................................. 41 
2-3 xgoodbye.c: complete code ............................................................................................... 46 
2-4 XGoodbye: the app-defaults file ....................................................................................... 47 
2-5 Using XtVaSetValues to set a widget resource ................................................................. 51 
2-6 Using XtSetValues to set a widget resource ..................................................................... 52 
2-7 Code fragment to set multiple resources of a widget ....................................................... 52 
2-8 Code fragment to get a widget resource using XtVaGetValues ...................................... 53 

2-9 Code fragment to get a widget resource using XtGetValues ........................................... 54 
2-10 Alternate resource settings for xgoodbye ........................................................................ 57 
3-1 xrowcolumn.c: complete code .......................................................................................... 64 
3-2 XRowColumn: app-defaults file ....................................................................................... 66 
3-3 xform: constraint resource settings added ........................................................................ 72 
3-4 xmainwindow.c: code for implementing standard Motif screen layout .......................... 76 
3-5 Adding a File menu to an existing menubar ..................................................................... 80 
3-6 xmainwindow: creating a Help button and Help dialog box ........................................... 83 
3-7 XMainWindow: setting help text in the app-default file .................................................. 85 
3-8 Passing a single value to a callback function .................................................................... 87 
3-9 Passing a pointer to a structure to a callback function ..................................................... 88 
3-10 ANSI non-conformant callback function definition ....................................................... 89 
3-11 The XmPushButtonCallbackStruct structure .................................................................. 89 
3-12 Initializing a callback list ................................................................................................. 91 
3-13 xbitmap: getting application resources ........................................................................... 92 
3-14 The resource list for xbitmap4 ......................................................................................... 93 
3-15 Calling XtGetApplicationResources and checking values ............................................ 96 
3-16 xbitmap: specifying command-line options ................................................................... 99 
3-17 The R4 varargs interface to creating a widget .............................................................. 104 
3-18 An argument list .............................................................................................................. 106 
3-19 Using an argument list in widget creation .................................................................... 107 
3-20 Setting the argument list with XtSetArg ....................................................................... 108 
3-21 Incorrectly setting the argument list with XtSetArg .................................................... 108 
4-1 xbitmapl: complete code ................................................................................................. 115 
4-2 XBitmapl: app-defaults file ............................................................................................ 118 
4-3 xbitmap2: implementing small pixmaps with DrawingArea widgets .......................... 122 
4-4 xbitmap2: creating pixmaps and GCs .............................................................................. 124 
4-5 xbitmap2: the CellToggled routine ................................................................................. 126 
4-6 xbitmap2: the RedrawSmallPicture routine ................................................................... 127 
4-7 xbitmap2: writing a bitmap file ....................................................................................... 128 
4-8 xbitmap3.c: adding a feature to a Primitive widget ....................................................... 131 
4-9 An XtActionProc with widget and event arguments ...................................................... 132 
4-10 A simple translation table ............................................................................................... 134 
4-11 A complex translation table ........................................................................................... 134 
4-12 XBitmap3: specifying translations in the app-defaults file ........................................ 135 

o.. 
XVIII 



4-13 Code fragment: specifying translations in the program .............................................. 137 
4-14 A translation table with action parameters ................................................................... 137 
4-15 xbitmap4: implementing the bitmap editor from the application ............................... 139 
5-1 multi_font: code to use multiple fonts in a compound string ........................................ 166 
5-2 The .c file for a simple UIL application ........................................................................... 175 
5-3 The .uil file for a simple UIL application ........................................................................ 177 
6-1 BitmapEdiP.h: the class part and class record ............................................................... 186 
6-2 BitmapEdiP.h: the instance part and instance record .................................................... 188 
6-3 BitmapEdiP.h: declaring the external class record ........................................................ 189 
6-4 BitmapEdit.c: include files .............................................................................................. 190 
6-5 BitmapEdit's resource list ................................................................................................ 192 
6-6 Setting the resource list into the class structure .............................................................. 194 
6-7 The default translation table and the actions table ......................................................... 195 
6-8 Translations in the Core class record ............................................................................... 196 
6-9 BitmapEdit.c: function type declarations ....................................................................... 197 
6-10 BitmapEdit.c: initialization of Core class record ........................................................ 197 
6-11 BitmapEdit.c: declaring the class record pointer ......................................................... 204 
6-12 BitmapEdit.c: inheriting a self-contained method ....................................................... 205 
6-13 Inheriting by invoking the superclass method from a widget method ........................ 206 
6-14 BitmapEdit.h: incidental declarations .......................................................................... 208 
7-1 The initialize method ........................................................................................................ 217 
7-2 Creating GCs from the initialize method ........................................................................ 220 
7-3 The expose method ........................................................................................................... 222 
7-4 The set_values method ..................................................................................................... 225 
7-5 BitmapEdit: the resize method ........................................................................................ 228 
7-6 The XtWidgetGeometry structure ................................................................................... 231 
7-7 BitmapEdit: the query_geometry method ...................................................................... 232 
7-8 The destroy method ........................................................................................................... 233 
7-9 BitmapEdit: action routines ............................................................................................. 234 
8-1 Installing accelerators in an application .......................................................................... 258 
8-2 Specifying the XtNaccelerators resource from the app-defaults file ............................ 259 
8-3 Conflicting translations and accelerators ........................................................................ 261 
8-4 Installing accelerators from both command widgets ...................................................... 261 
8-5 Accelerators resource settings for two widgets .............................................................. 262 
9-1 Using an event hander to pop up a popup menu ............................................................. 268 
9-2 Registering an event handler, and the handler function itself ....................................... 271 
9-3 Adding a nonmaskable event handler .............................................................................. 273 
9-4 Casting the event structure by declaring action routine arguments .............................. 275 
9-5 Handling multiple event types in an action routine ........................................................ 275 
9-6 Getting file input with XtAppAddlnput .......................................................................... 279 
9-7 Reading stdin from an Xt application .............................................................................. 281 
9-8 xtetris: registering a timeout and the timeout function ................................................. 283 
9-9 xtetris: calling XtRemoveTimeOut ................................................................................ 284 
9-10 Registering an Xt work procedure ................................................................................. 286 
9-11 A work procedure to create a popup widget ................................................................. 287 
9-12 Skeleton of a custom main loop ..................................................................................... 288 
10-1 Three resources defined by the Motif Primitive widget ............................................... 294 
10-2 An app-defaults file for the Spanish language .............................................................. 303 



10-3 Setting fallback resources in XtApplnitialize ............................................................... 304 
10-4 A sample merged resource database .............................................................................. 306 
10-5 Sample resource database with eliminated entries and components .......................... 306 
10-6 Resource database after final elimination of entries and components ........................ 307 
10-7 Resource database finalists in original form ................................................................. 308 
10-8 A resource definition converting an integer to a pixmap ............................................. 314 
10-9 A resource definition using XmRImmediate ................................................................ 314 
10-10 A resource definition using XmRCallProc .................................................................. 315 
10-11 An example of an XtResourceDefaultProc ................................................................. 315 
10-12 Registering a type converter ........................................................................................ 317 
10-13 Adding a converter with arguments ............................................................................ 319 
10-14 Manually invoking a type converter ............................................................................ 322 
10-15 A simple type converter ............................................................................................... 323 
10-16 Testing for a special-case default value ...................................................................... 324 
10-17 Simplified get_values_hook method of the AsciiSrc subpart of the Text widget .... 326 
11-1 Setting the XmNinput resource of a Shell widget ........................................................ 338 
11-2 Creating an icon pixmap, and setting XmNiconPixmap .............................................. 341 
11-3 BitmapEdit: actions that highlight selection ................................................................ 349 
11-4 BitmapEdit: getting the atom for a widget-specific target type ................................. 357 
11-5 BitmapEdit: action to paste a selection ........................................................................ 358 
11-6 BitmapEdit: converting the selection value ................................................................. 359 
11-7 BitmapEdit: pasting selection in requestor_callback function ................................... 361 
11-8 BitmapEdit: the lose_ownership_proc ......................................................................... 362 
11-9 BitmapEdit: initializing Xmu's atom caching mechanism in the initialize method. 365 
11-10 BitmapEdit: converting standard targets in the convert_proc .................................. 365 
12-1 ScrollBox: the set_values method ................................................................................ 384 
12-2 ScrollBox: the resize method ........................................................................................ 385 
12-3 ScrollBox: the query_geometry method ...................................................................... 385 
12-4 ScrollBox: private routine to lay out child widgets .................................................... 386 
12-5 A basic change_managed method ................................................................................. 388 
12-6 A simple geometry_manager method ............................................................................ 388 
12-7 Form: the Core resource list .......................................................................................... 393 
12-8 Form: constraint resource list ........................................................................................ 394 
12-9 Form: constraint data structure ..................................................................................... 395 
12-10 Form: class structure initialization ............................................................................. 396 
12-11 Form: the Constraint initialize method ...................................................................... 399 
12-12 Form: the class_part_init method ............................................................................... 399 
12-13 Form: the geometry_manager method ....................................................................... 400 
12-14 Form: private functions: RefigureLocations and the layout method ...................... 401 
12-15 Form: the LayoutChild private function .................................................................... 403 
12-16 Form: the resize method .............................................................................................. 405 
12-17 Form: the change_managed method ........................................................................... 407 
12-18 Form: the query_geometry method ............................................................................ 408 
12-19 Form: the public function for delaying calls to change_managed ........................... 409 
13-1 Creating, placing, and popping up a popup menu ........................................................ 417 
13-2 Adding a cascading submenu ......................................................................................... 419 
13-3 xmenul" complete code ................................................................................................. 422 
13-4 XMenul: the app-defaults file ...................................................................................... 426 

XX 



13-5 xmenu2: code to place pulldown menu ........................................................................ 429 
13-6 XMenu2: translation portion of the app-defaults file .................................................. 430 
13-7 xmenu5: actions that place, pop up, and pop down main menus and submenus ....... 432 
13-8 XMenu5: translation portion of app-defaults file ........................................................ 434 
13-9 xmenu7: using the SimpleMenu widget and its children ............................................ 436 
13-10 XMenu7: app-defaults file ........................................................................................... 439 
13-11 Sine gadget: class part and complete class structure declaration ............................. 445 
13-12 Sine gadget: instance part and complete instance structure declaration ................. 446 
13-13 SimpleMenu: expose method calling gadget children's expose methods ............... 448 
13-14 SimpleMenu: resize method ........................................................................................ 450 
13-15 SimpleMenu: the Notify action routine ..................................................................... 450 
13-16 SimpleMenu.c: Setting accepts_objects in the Composite extension structure ....... 451 
14-1 How to invoke XtAppErrorMsg (from AsciiSrc.c) ...................................................... 457 
14-2 Common fields in a class extension record ................................................................... 469 
B-1 Sample fonts.alias file ...................................................................................................... 510 
B-2 fonts.dir file in/usr/lib/X11/fonts/100dpi ....................................................................... 512 
E-1 BitmapEdit: complete widget code ................................................................................. 551 
E-2 BitmapEdiP.h: complete private header file .................................................................. 564 
E-3 BitmapEdit.h: complete public header file .................................................................... 566 
E-4 xbitmap5: complete application code ............................................................................ 567 

xxi 



Tables 

Page 

2-1 Functions that Set Resources: ArgList and varargs Counterparts ................................... 50 
2-2 Compound String Resources That Must Not Be Freed After Querying ......................... 54 
2-3 Core Resources .................................................................................................................... 55 
2-4 Label Resources .................................................................................................................. 57 
3-1 Motif Resource Type Strings .............................................................................................. 95 
3-2 Standard Command-line Parameters ................................................................................. 98 
3-3 XrmOptionKind: Command-line Option Style Constants ............................................ 101 
5-1 XmCreate Functions ......................................................................................................... 160 
5-2 Built-in MotifPixmaps ..................................................................................................... 171 
6-1 Resource List Constant Conventions ............................................................................... 194 
6-2 Inheritance Style of Various Methods ............................................................................. 202 
6-3 Summary of Xt Structure Name Conventions ................................................................ 211 
7-1 XtWidgetGeomelyy request_mode Symbols ................................................................... 231 
7-2 XtWidgetGeometry stack_mode Symbols ...................................................................... 231 
8-1 Event Type Abbreviations in Translation Tables ............................................................ 242 
8-2 Notify Mode Values for Enter, Leave, and Focus Events .............................................. 2z6 
8-3 Atom Details for Various Events ..................................................................................... 247 
8-4 Event Structure Fields Used As Translation Table Hints ............................................... 247 
8-5 Modifiers Used in Translation Tables .............................................................................. 248 
8-6 Modifier Symbols .............................................................................................................. 250 
9-1 Event Masks and Event Types .......................................................................................... 270 
9-2 Event Types and Event Structures ................................................................................... 277 

9-3 Other Input Source Masks ................................................................................................ 278 
10-1 Resource Type Strings .................................................................................................... 296 
10-2 Built-in Type Converters from XmRString ................................................................... 311 
10-3 Other Built-in Converters ............................................................................................... 313 
10-4 Xmu Converters .............................................................................................................. 316 
11-1 Shell Resources ............................................................................................................... 333 
11-2 Target Types Suggested in ICCCM ................................................................................. 363 
14-1 Xt Error and Warning Message Utilities ....................................................................... 457 
14-2 Xt Routines That Use Default and Explicit Application Contexts ............................. 465 
A- 1 Comparison of Athena, OPEN LOOK, and Motif Widgets ............................................ 474 
B-1 Geometry Specification: x and y Offsets ....................................................................... 513 
D-1 ArgList Functions and Varargs Counterparts ................................................................. 524 
D-2 New Naming for Core Class Symbols and Variables .................................................... 531 
D-3 New Representation Types .............................................................................................. 537 
D-4 Flags for compress_exposure Field of Core Class Structure ........................................ 545 
D-5 Optional OR Flags for compress_exposure Field of Core Class Structure .................. 546 

xx# 



Preface 

Note that while Motif is used for the examples in this book, the techniques 
described are equally applicable to and provide a good introduction to pro- 
gramming with any other widget set based on Xt. It is not difficult to convert 
an application between any of the widget sets listed above, since all of them 
use the same Xt Intrinsics programming interface. 

In This Chapter: 

Summary of Contents .......................................................................... xxv 
Assumptions ........................................................................................ xxvi 
Related Documents ............................................................................. xxvi 
How to Use This Manual ..................................................................... xxvii 
Font Conventions Used in This Manual ................................................ xxx 
Request for Comments ........................................................................ xxx 
Bulk Sales Information ......................................................................... xxxi 
Obtaining the X Window System Software ........................................... xxxi 
Obtaining Motif .................................................................................... xxxi 
Obtaining the Example Programs ........................................................ xxxi 
Ackn owledg men ts ............................................................................... xxxii 



Preface 

This book describes how to write X Window System programs using the Xt Intrinsics library 
(or simply Xt). Xt is a standard established by the X Consortium that provides an object-ori- 
ented programming style in the C language. 

OSF's Motif library provides user-interface objects to be used with Xt. Motif is not an X 
Consortium standard, though it may nevertheless become a de-facto industry standard. This 
book primarily describes the Xt Intdnsics, but it also provides an introduction to Motif and 
uses Motif for many of the examples. 

The Xt Intrinsics together with a second library such as Motif are collectively called the X 
Toolkit. 

Summary of Contents 

The discussion of the X Toolkit is divided into two volumes, Volumes Four and Five of the X 
Window System Series available from O'Reilly & Associates, Inc. 
This is Volume Four, X Toolkit lntrinsics Programming Manual, Motif Edition. It provides 
an explanation of the X Toolkit, including tutorial material and numerous programming 
examples. Arranged by task or topic, each chapter brings together a group of Xt functions, 
describes the conceptual foundation on which they are based, and illustrates how they are 
most often used in writing applications. This volume is structured to be useful as a tutorial 
and also as a task-oriented reference. 
Volume Five, X Toolkit lntrinsics Reference Manual, includes reference pages for each of the 
Xt functions, as well as for the widget classes defined by Xt, organized alphabetically for 
ease of reference; a permuted index; and numerous appendices and quick reference aids. 
The two volumes are designed to be used together. To get the most out of the examples in 
Volume Four, you will need the exact calling sequences of each function from Volume Five. 
To understand fully how to use each of the functions described in Volume Five, all but the 
most experienced Toolkit "hacker" will need the explanation and examples in Volume Four. 
Both volumes include material from the original Toolkit documentation provided by MIT, 
though in Volume Four this material is mostly limited to the appendices. We have done our 
best to incorporate all the useful information from the MIT documentation, to reorganize and 
present it in a more useful form, and to supplement it with conceptual material, tutorials, ref- 

Preface xxv 



erence aids, and examples. In other words, this manual is not only a replacement but is a 
superset of the MIT documentation. 

Those of you familiar with the MIT documentation will recognize that each reference page in 
Volume Five includes the detailed description of the routine found in X Toolkit lntrinsicsmC 
Language Interface, plus in many cases additional text that clarifies ambiguities and 
describes the context in which the routine would be used. We have also added the definitions 
of structures and symbolic constants used as arguments or returned values by the function, as 
well as cross-references to related reference pages and to where additional information can 
be found in Volume Four. 

Assumptions 

This book makes no assumptions about the reader's knowledge of object-oriented program- 
ming or the X Window System. Readers should be proficient in the C programming lan- 
guage, although examples are provided for infrequently used features of the language that are 
necessary or useful when programming with the X Toolkit. In addition, general familiarity 
with the principles of raster graphics will be helpful. 
However, even though the Toolkit is intended to hide the low-level X interface provided by 
Xlib, there are times in writing applications or widgets when Xlib functions will be necessary 
because no Xt feature exists to do the same thing. This book describes the most common 
occasions for using Xlib, but does not provide a reference to the particular functions 
involved. Additional documentation on Xlib, such as that provided by Volume One, Xlib 
Programming Manual, and Volume Two, Xlib Reference Manual, will be indispensable. 

Related Documents 

Eight other books on the X Window System are available from O'Reilly & Associates, Inc.: 
Volume Zero X Protocol Reference Manual 
Volume One Xlib Programming Manual 
Volume Two Xlib Reference Manual 
Volume Three X Window System User's Guide, Motif Edition 
Volume Five X Toolkit Intrinsics Reference Manual 
Volume Six Motif Programming Manual (Spring '91) 
Volume Seven XView Programming Manual 
Quick Reference The X Window System in a Nutshell 
The following book published by Prentice Hall will be necessary to obtain details of the 
Motif widgets: 
OSF/Motif Programmer' s Reference 

xxvi X Toolkit Intrinsics Programming Manual, Motif Edition 



The following documents are included on the X11 source tape (the X distribution from MIT): 
X Toolkit Intrinsics--C Language Interface, by Joel McCormack, Paul Asente, 
and Ralph Swick 
X Toolkit Athena Widgets--C Language Interface, by Ralph Swick and 
Terry Weissman 
Xlib--C Language X Interface, by Jim Gettys, Ron Newman, and Robert Scheifler 
The following Nutshell Handbooks published by O'Reilly and Associates, Inc. are useful 
when programming in C: 
Checla'ng C Programs with lint, by Ian Darwin 
Managing Projects with make, by Steve Talbott 
Using C on the UNIX System, by Dave Curry 

The following is the classic introduction to C programming: 
The C Programming Language, by B. W. Kernighan and D. M. Ritchie 

How to Use This Manual 

Volume Four explains both application programming with widgets and widget programming 
(the design and coding of new widgets). 

The first five chapters treat widgets largely as "black boxes," which is appropriate consider- 
ing the object-oriented philosophy of the Toolkit. These chapters also provide an overview 
of many elements of the X Toolkit, and so are appropriate for all readers. 

Chapter 1 

Introduction to the X Window System, provides a discussion of the context in 
which X programs operate. Programmers who are comfortable programming 
withXlib can skip Chapter 1. 

Chapter 2 

Introduction to the X Toolkit and Motif, describes the conceptual foundations 
underlying Toolkit programming, and shows how to write simple programs 
that use widgets from existing widget sets. It introduces such fundamental 
Toolkit programming concepts as resources, the Translation Manager, call- 
backs, and actions. 

Chapter 3 

More Techniques for Using Widgets, describes how to use some of the more 
complex widgets found in applications, including composite widgets, con- 
straint widgets, and popups. It also describes how to define application 
resources and command-line options, and how to hardcode the value of widget 
resources when you create a widget. Finally, it describes how to create multi- 
ple top-level windows, and how to use application contexts to create applica- 
tions that are more portable. 

Chapter 4 

An Example Application, describes a complete application, in several itera- 
tions. First, it shows a simple version of the program, a bitmap editor, as it 
would be written assuming the existence of a BitmapEdit widget (which is 
actually developed in Chapter 6). Then, two refined versions are developed, 
each demonstrating additional Toolkit programming techniques. Finally, the 

Preface xxvii 



same application is shown as it would be written if the bitmap editor were 
implemented in an application window rather than with the BitmapEdit 
widget, as it would be written if no BitmapEdit widget existed. 
Chapter 5 More About Motif, describes and illustrates the widgets available in the Motif 
1.1 widget set, and introduces the features and functions provided by Motif 
that add to the programming model defined by Xt. As mentioned earlier, this 
volume does not contain detailed reference information on each widget, and it 
gives examples using only a few of the widgets in the Motif widget set. Addi- 
tional information on each Motif widget is presented in Volume Six, X Motif 
Programming Manual (available Spring '91). 
The next two chapters describe widget internals, and the process of creating new widgets. 
While this information is not essential for all application programmers, many applications 
require a custom widget to implement their special graphics capabilities. 
Chapter 6 Inside a Widget, describes the code inside a widget. Much of this code is 
common to all widgets. You can think of it as a framework that Xt uses to 
implement a widget's features. After reading this chapter, you should under- 
stand the procedure for creating your own widget around this framework. 
Chapter 7 Basic Widget Methods, describes a widget's initialize, expose, 
set_values, destroy, resize, and query_geometry methods. (A 
widget's methods are internal routines called automatically by Xt to give the 
widget a degree of independence from the application.) The chapter explains 
when Xt calls each method, and describes in detail what should be in each of 
these methods. Among other things, these methods prepare for and do the 
drawing of graphics that appear in a widget. This chapter describes what the 
Toolkit adds to the graphics model provided by Xlib but does not describe in 
detail how to draw using Xlib; this topic is described in Chapters 5, 6, and 7 of 
Volume One, Xlib Programming Manual. 
Later chapters treat various topics of interest to either application or widget programmers, or 
both. Some of these topics have been introduced in the earlier chapters and are explored 
more completely in the following ones. 
Chapter 8 Events, Translations, and Accelerators, describes the complete syntax of 
translation tables, which allow the user to configure the mapping of event 
sequences into widget actions. It also describes accelerators, a mechanism for 
mapping events in one widget to actions in another. 
Chapter 9 More Input Techniques, describes how to handle events with event handlers 
and how to use information from the event structure inside an event handler or 
action routine. It also describes how to get file, pipe, or socket input, how to 
use timeouts to call a function after a delay or at particular intervals, and how 
to use work procedures to do background processing. Finally, it discusses 
some low-level features of Xt for directly interacting with the event queue. 
Chapter 10 Resource Management and Type Conversion, is a more thorough discussion of 
how resources work and how they should be used. This chapter describes in 
detail the resource file format and the rules that govern the precedence of 
resource settings. It also describes how to add your own type converter so that 

xxviii X Toolkit Intrinsics Programming Manual Motif Edition 



Chapter 11 

Chapter 12 

Chapter 13 

Chapter 14 

Appendix A 

Appendix B 

Appendix C 

Appendix D 

Appendix E 

Appendix F 

Glossary 

you can set application- or widget-specific data through resources. Finally, it 
describes subresources and how to use them. 
Interclient Communications, discusses communication through the X server 
between an application and the window manager, and between two applica- 
tions. The application-window manager communication is performed by code 
in the Shell widget. The application sets shell resources to control this com- 
munication with the window manager. Application-application communica- 
tion is usually done with a process called selections. This form of commu- 
nication is already implemented in most widgets that display text, but you 
may want to implement it in your own custom widgets. Selections can also 
pass other kinds of data such as graphics. 
Geometry Management, discusses how composite and constraint widgets man- 
age the layout of widgets, and how to write your own simple composite and 
constraint widgets. 
Menus, Gadgets, and Cascaded Popups, describes how menus work and 
describes several ways to create menu widgets. One of these ways involves 
the use of windowless widgets, or gadgets. This chapter also describes how to 
use more advanced features of the Xt popup mechanism, including modal cas- 
cades, to implement cascading popup menus. 
Miscellaneous Toolkit Programming Techniques, describes various Xt func- 
tions that have not been treated elsewhere in the book. These include func- 
tions for error and warning handling, case conversion, and so on. 
Athena, OPEN LOOK, and Motif, provides a comparison of the widgets avail- 
able in AT&T's OPEN LOOK widget set and OSF's Motif. These widgets are 
contrasted with those in the Athena widget set. 
Specifying Fonts and Colors, gives information on the values that can be used 
when specifying fonts and colors as resources. 
Naming Conventions, describes a suggested set of conventions for naming 
widgets and elements within widget code. 
Release Notes, describes the changes between Release 3 and Release 4. This 
manual describes Release 4, but notes the most important changes since 
Release 3 for those familiar with that release. 
The xbitmap Application, shows the complete code for an advanced version of 
the xbitmap application and the BitmapEdit widget, which are described in 
Chapters 5 and 6. 
Sources of Additional Information, lists where to get the X software, lists com- 
panies that offer training in X programming, and describes additional books 
on the subject that have been or soon will be published. 
gives you somewhere to turn should you run across an unfamiliar term. Some 
care has been taken to see that all terms are defined where they are first used 
in the text, but not everyone will read the manual in sequential order. 

Preface xxix 



Request for Comments 

To help us provide you with the best documentation possible, please write to tell us about any 
flaws you find in this manual or how you think it could be improved. 

Our U.S. mail address, e-mail address, and phone numbers are as follows: 

O'Reilly & Associates, Inc. 
632 Petaluma Avenue 
Sebastopol, CA 95472 
800-338-6887 
international +1 707-829-0515 

UUCP: uunet!ora!adrian Internet: adrian@ora.com 

Bulk Sales Information 

This manual is being resold by many workstation manufacturers as their official X Window 
System documentation. For information on volume discounts for bulk purchase, call 
O'Reilly and Associates, Inc., at 800-338-6887 or send e-mail to linda@ora.com 
(uunet!ora!linda). 
For companies requiring extensive customization of the book, source licensing terms are also 
available. 

Obtaining the X Window System Software 

The X Window system is copyrighted but freely distributed. The only resiction this places 
on its use is that the copyright notice identifying the author and the terms of use must accom- 
pany all copies of the software or documentation. Thanks to this policy, the software is avail- 
able for a nominal cost from a variety of sources. See Appendix F, Sources of Additional 
Information, for a listing of these sources. 

Obtaining Motif 

If your hardware vendor is an OSF member, they may be able to provide Motif binaries for 
your machine. Various independent vendors also provide binaries for some machines: see 
Appendix F, Sources of Additional Information, for a listing of a few of these. Source 
licenses must be obtained directly from OSF. Call OSF at 617-621-7300 for ordering infor- 
mation. 

Preface xxxi 



Obtaining the Example Programs 

The example programs in this book are available free from UUNET (that is, free except for 
UUNET's usual connect-time charges). If you have access to UUNET, you can retrieve the 
source code using uucp or ftp. For uucp, find a machine with direct access to UUNET, and 
type the following command: 
uucp uunet\ ! -/nutshell/xt/motifpgs. tar. Z yourhos-/yourname/ 
The backslashes can be omitted if you use the Bourne shell (sh) instead of csh. The file 
should appear some time later (up to a day or more) in the directory lusrlspoolluucppub- 
lic/yourname. 
You don't need to have opened an account to UUNET to be able to access their archives via 
UUCP from within the United States of America. By calling 1-900-468-7727 and using the 
login "uucp" with no password, anyone may uucp any of UUNET's online source collection. 
(Start by copying uunet!/usr/spool/ftp/ls-lR.Z, which is a compressed index of every file in 
the archives.) As of this writing, the cost is 40 cents per minute. The charges will appear on 
your next telephone bill. 
To useftp,ftp to uunet.uu.net and use anonymous as your user name and guest as your pass- 
word. Then type the following: 
cd nutshell/xt 
binary (you must specify binary transfer for compressed.hies) 
get motifpgs.tar. Z 
bye 
The file is a compressed tar archive. To extract files once you have retrieved the archive, 
type: 
uncompress motifpgs.tar 
tar xf motifpgs.tar 

The examples will be installed in subdirectories under the current directory, one for each 
chapter in the book. Imakefiles are included. (Imakefiles are used with imake, a program 
supplied with the X 11 disla-ibution that generates proper Makefiles on a wide variety of sys- 
tems.) 
All the app-defaults files are in the main examples directory. The app-defaults files are not 
automatically installed in the system app-defaults directory (/usr/lib/Xll/app-defaults on 
most UNIX systems). (See Chapter 10, Resource Management and Type Conversion, for 
details.) If you have permission to write to that directory, you can copy them there yourself. 
Otherwise, you can set the XAPPLRESDIR environment variable to the complete path of the 
directory where you installed the examples. The value of XAPPLRESDIR must end with a / 
(slash). (Most of the examples will not function properly without the app-defaults files.) 

xxxii X Toolkit Intrinsics Programming Manual, Motif Edition 



Acknowledgments 

As mentioned above, this manual includes some material from the X Toolkit Intrinsics--C 
Language Interface, by Joel McCormack, Paul Asente, and Ralph Swick. This is the docu- 
ment that defines the X Consortium standard for Xt, known as the Xt specification. Overt 
borrowings from the Xt specification are rare in this volume. However, the Xt specification 
document, as well as the sample code of Xt distributed with releases of X, provides the intel- 
lectual basis for most of what appears here. 
We'd like to thank Sony Microsystems for the loan of a Sony NEWS workstation running 
their implementation of the X Window System. The speed and power of the Sony work- 
station, and the support of Sony's staff, were a great help in developing these books. Addi- 
tional development was done on a Sun-3 workstation running MIT's sample server, a Visual 
640 X Display Station, and an NCD16 Network Display Station. 
We would also like to thank the reviewers of the Alpha draft of this book, even though we 
almost had to start over because of their comments. They were David Lewis of Integrated 
Computer Solutions (ICS), Wendy Eisner of Sunquest Information Systems, Dan Heller of 
Island Graphics, Inc. (now working with O'Reilly and Associates), Miles O'Neal of Systems 
and Software Solutions, Inc., and Chris Peterson of MIT Project Athena (now of the X Con- 
sortium). Ian Darwin of SoftQuad and Bradley Ross of Cambridge Computer Associates 
reviewed the Beta draft. Extra thanks are due to Ralph Swick, Chris Peterson, and Robert 
Scheifler, who answered many questions during the development of this book. 
Of course, we alone take responsibility for any errors or omissions that remain. 
Special thanks go to Mark Langley, who wrote an early draft of this book. He helped to edu- 
cate us about the Toolkit, and his efforts to make the book a success did not go unnoticed. 
Special thanks also go to Integrated Computer Solutions, for their assistance in preparing this 
Motif edition. 
Of course, the authors would like to thank the entire staff of O'Reilly and Associates for pro- 
ducing the book, and the staff of Cambridge Computer Associates, Inc., for lending their sup- 
Perhaps most of all, we would like to thank our readers and customers for their patience, 
which we tested by promising that this book would be finished next month--every month for 
the last eight months. These days, with word processors, it is easy to generate a book-length 
manuscript, but no easier than it ever was to carve that text into something worth reading. 
We have had that book-length manuscript for a year, but have not been satisfied until now 
that it presented the material in a clear, friendly, and authoritative manner. We hope that the 
extra time we have spent boiling down the facts about this very new and continuously 
advancing subject will prove worthwhile to you, the reader. 

--Adrian Nye and Tim O'Reilly 

Preface xxxiii 



1 

Introduction to the X Window System 

This chapter introduces many of the most important concepts on which the X 
Window System is based, and describes the environment in which the X 
Toolkit operates. This chapter assumes that you are new to programming 
the X Window System. If you already have some experience programming 
the X Window System, you may wish to skim this chapter for a brief review 
or even begin with Chapter 2. 

In This Chapter: 

The Server and Client ............................................................................ 7 
The Software Hierarchy ......................................................................... 9 
Event-driven Programming .................................................................. 11 
The Window Manager .......................................................................... 12 
Extensions to X ................................................................................... 13 



1 
Introduction to the X Window System 

The X Window System (or simply X)* is a hardware- and operating system-independent win- 
dowing system. It was developed jointly by MIT and Digital Equipment Corporation, and 
has been adopted by the computer industry as a standard for graphics applications. 

X controls a "bit-mapped" display in which each pixel on the screen is individually controll- 
able. This allows applications to draw pictures as well as text. Until recently, individual 
control of screen pixels was widely available only on personal computers (PCs) and high- 
priced technical workstations. Most general-purpose machines were limited to output on 
text-only terminals. X brings a consistent world of graphic output to both PCs and more 
powerful machines. Figure 1-1 compares an X application to an application running on a tra- 
ditional text terminal. 

*The mmae "X Windows" is frowned upon by the developers of X. 

Introduction to the X Window System 3 



I [] colorfuh/usr  J --'J Workspace 
1 I11 Utilities 
1 l 1 5include 1 hosts/ 1 pub/ 
1 II    "' 
I II ld .... 1man@ Isys@ 
1 II  ,  oc, 
1 ]I , o,c, ,o, uc, 

Figure 1-2. A three-button mouse directing the pointer to select a menu item 

Of course, X also handles keyboard input. The pointer directs keyboard input from window 
to window. Only one window at a time can receive keyboard input. 
In X, as in many other window systems, each application need not (and usually does not) 
consist of a single window. Any part of an application can have its own separate subwindow, 
which simplifies the.management of input and output within the application code. Such child 
windows are visible only within the confines of their parent window. 
Windows are rectangular and oriented along the same axes as the edges of the display. Each 
window has its own coordinate system, with the origin in the upper-left comer of the window 
inside its border. The application or the user can change the dimensions of windows. Figure 
1-3 shows a typical screen with several virtual terminals running. The screen also shows 
some applications, such as xmh, xclock, and xload, that run in their own windows. 

Introduction to the X Window System 5 



xterrn window 
(typical of 3) 

root 
window 

O,e, Mr Ho.mao" o.O,o host2 
YOU called yesterday for 
informahon about X [] 

X 
]llJ The X window system s a | 
IHI oetwo,, bas graphic window 
1 II system that was developed al MIT 
II II ' t. Several vers,Ofls of X 
. II II have l0een developed, themost 
il II reeotowh,:h,sXVeroo. I 
II II (X11). tirst released ,n1987. Xll I 
iLJl has been adopted as an industry- I 

-- oclock 
window 

--iconified 
xterrn 
window 
xcalc 
window 

Figure 1-3. Screen layout of a typical user's X Window System 

X supports both color and black-and-white displays. 
Many of the above characteristics are also true of several other window systems. What is 
unusual about X is that it is based on a network protocol instead of on system-specific proce- 
dure and system calls. This network protocol enables X to be ported to different computer 
architectures and operating systems; it also allows programs to run on one architecture or 
operating system while displaying on another. Because of its unique design, X can make a 
network of different computers cooperate. For example, a computationally intensive applica- 
tion might run on a supercomputer, but take input from and display output on a workstation 
connected across a local area network. To the user, the application would simply appear to 
be running on the workstation. 

6 X Too&# Intrinsics Programming Manual, Motif Edition 



uses the X Protocol. The communication path between a client and the server is called a con- 
nection. 

It is common for a user to have programs running on several different hosts in the network, 
all invoked from and displaying their windows on a single screen (see Figure 1-4). Clients 
running remotely can be started from the remote machine or from the local machine using the 
network utilities rlogin or rsh. 

 Supercomputer 
Personal Computer 
Large Minicomputer 

Display Server 

Figure 1-4. Applications can run on any system across the network 

This use of the network is known as distributed processing. It allows graphic output for pow- 
erful systems that don't have their own built-in graphics facilities. Distributed processing 
can also help solve the problem of unbalanced system loads. When one host machine is over- 
loaded, users running clients on that machine can arrange for some of their clients to run on 
other hosts. Eventually there may be automatic load-balancing applications, but currently 
such remote execution is performed manually. It is not unusual to see users in the X environ- 
ment having several xload load monitor applications running on various systems throughout 
the network but displaying on their screen, so that they can see the balance of loads through- 
out the network. 

8 X Toolkit Intrinsics Programming Manual, Motif Edition 



Application 

Widget Set 

Xt Intrinsics 
Xlib 

X Protocol 
......... 
. 
X Server 

Device Drivers 

Figure 1-5. The software architecture of Xt Intrinsics-based applications 

Xt is built upon Xlib. The purpose of Xt is to provide an object-oriented layer that supports 
the user-interface absla'action called a widget. A widget is a reusable, configurable piece of 
code that operates independently of the application except through prearranged interactions. 
A widget set is a collection of widgets that provide commonly used user-interface compo- 
nents tied together with a consistent appearance and user interface (also called look and feel). 
Several different widget sets are available from various vendors that are designed to work 
with Xt. The use of widgets separates application code from user-interface code and pro- 
vides ready-to-use user-interface components such as buttons and scrollbars. Xt, widgets, 
and widget sets are described in much more detail in Chapter 2, Introduction to the X 
Toolkit and Motif. 
In this book, we'll refer to the combination of the Xt Intrinsics and one widget set as the X 
Toolkit or just the Toolkit. When referring to the Xt Intrinsics layer alone, we'll use Xt, or the 
Intrinsics. 
Applications often need to call Xlib directly to accomplish certain tasks such as drawing. Xt 
does not provide its own graphics calls, nor does it provide access to every X protocol fea- 
ture. This book describes the features of Xlib that you may need from an Xt application, but 
it will not repeat the detailed description of Xlib programming found in Volume One, Xlib 
Programming Manual. You will find Volume One and Volume Two, Xlib Reference Man- 
ual, invaluable when you need to make Xlib calls. 
Xlib, Xt, and several widget sets are available on MIT's public software distribution. The 
Motif and OPEN LOOK widget sets are not on the Release 3 or Release 4 distributions from 
MIT, but they are available for minimal cost from the vendors themselves (OSF, AT&T, or 

10 X TooAkit Intrinsics Programming Manual Motif Edition 



Sun, respectively.) The darkly shaded areas of Figure 1-5 indicate interfaces that are exclu- 
sive standards of the X Consortium. That Xlib is an exclusive standard means that computer 
manufacturers wishing to comply with the X Consortium standard must offer Xlib and cannot 
offer any other low-level X interface in C. The lightly shaded areas (such as the Xt Inlxin- 
sics) are nonexclusive standards--vendors are required to provide Xt but are also allowed to 
provide other toolkit-level layers for the C Language. For example, Sun and AT&T offer Xt, 
but they also offer XView as an alternate C-Language toolkit-level layer. XView was origi- 
nally designed for porting existing SunView TM applications to X, but it can also be used for 
writing new applications. Volume Seven, XView Programming Manual, describes program- 
ming with XView. 
X software is unlike that of many other window systems in that it was designed to provide 
mechanism without mandating any certain style of user interface. In the words of its design- 
ers, X provides "mechanism without policy." The Xlib and Xt layers are standard because 
they can support any kind of interface. It is the widget set that actually imposes user-inter- 
face conventions, and it is this layer for which no standard has yet been considered by the X 
Consortium. However, because there is a strong need in the market for one or two standard 
widget sets that provide consistent appearance and user-interface conventions, it is likely that 
one or two widget sets will emerge as de-facto standards in the near future. 
It is important to note that the X Consortium standards for Xlib and Xt define the program- 
ming interface to each library (often referred to as the Application Programmer's Interface, 
or API), not the underlying code. This means that vendors are allowed to modify or rewrite 
the code to gain the best performance from their particular system, as long as they keep the 
programming interface the same. To you, the application writer and user of the Intrinsics, 
this means that you must always rely on documented behavior if you want your application to 
run on different systems. You must avoid accessing private structures, because they may be 
different in another vendor's release of the library, or they may be changed in a future release 
of X. 

1.3 Event-driven Programming 

Programming a graphically-based window system is fundamentally different from standard 
procedural programming. In traditional character-based interfaces, once the application 
starts, it is always in control. It knows only what kind of input it will allow, and may define 
exclusive modes to limit that input. For example, the application might ask the user for input 
with a menu, and use the reply to go down a level to a new menu, where the actions that were 
possible at the previous level are no longer available. Or a text editor may operate in one 
mode in which keyboard input is interpreted as editor commands, and another in which it is 
interpreted as data to be stored in an editor buffer. In any case, only keyboard input is 
expected. 

In a window system, by contrast, multiple graphic applications may be running simulta- 
neously. In addition to the keyboard, the user can use the pointer to select data, click on but- 
tons or scrollbars, or change the keyboard focus from one application to another. Except in 
special cases (for example, where a "dialog box" will not relinquish control until the user 
provides some necessary information), applications are modeless--the user can suddenly 

Introduction to the X Window System 11 



switch from the keyboard to the mouse, or from one application area to another. Further- 
more, as the user moves and resizes windows on the screen, application windows may be 
obscured or redisplayed. The application must be prepared to respond to any one of many 
different events at any time. 
An X event is a data structure sent by the server that describes something that just happened 
that may be of interest to the application. There are two major categories of events: user 
input and window system side effects. For example, the user pressing a keyboard key or 
clicking a mouse button generates an event; a window being moved on the screen also 
generates events--possibly in other applications as well if the movement changes the visible 
portions of their windows. It is the server's job to distribute events to the various windows 
on the screen. 
Event-driven window programming reduces modes to a minimum, so that the user does not 
need to navigate a deep menu structure and can perform any action at any time. The user, not 
the application, is in control. The application simply performs some setup and then goes into 
a loop from which application functions may be invoked in any order as events arrive. 

1.4 The Window Manager 

Because multiple client applications can be running simultaneously, rules must exist for arbi- 
trating conflicting demands for input. For example, does keyboard input automatically go to 
whichever window the pointer is in, or must the user explicitly select a window? How does 
the user move or resize windows? 
Unlike most window systems, X itself makes no rules about this kind of thing. Instead, there 
is a special client called the window manager that manages the positions and sizes of the 
main windows of applications on a server's display. The window manager is just another cli- 
ent, but by convention it is given special responsibility to mediate competing demands for the 
physical resources of a display, including screen space, color resources, and the keyboard. 
The window manager allows the user to move windows around on the screen, resize them, 
and usually start new applications. The window manager also defines much of the visible 
behavior of the window system, such as whether windows are allowed to overlap or are 
forced to tile (side by side), and whether the keyboard focus simply follows the pointer from 
one window to the next window, or whether the user must click a pointer button in a window 
to change the keyboard focus. 
Applications are required to give the window manager certain information to help it mediate 
competing demands for screen space or other resources. For example, an application speci- 
fies its preferred size and size increments. These are known as window manager hints 
because the window manager is not required to honor them. The Toolkit provides an easy 
way for applications to set window manager hints. 
The conventions for interaction with the window manager and with other clients have been 
standardized by the X Consortium as of July 1989 in a manual called the Inter-Client Com- 
munication Conventions Manual (ICCCM for short). The ICCCM defines basic policy inten- 
tionally omitted from X itself, such as the rules for transferring selections of data between 
applications, for transferring keyboard focus, for installing colormaps, and so on. 

12 X Toolkit Intrinsics Programming Manual, Motif Edition 



As long as applications and window managers follow the conventions set out in the ICCCM, 
applications created with different toolkits will be able to coexist and work together on the 
same server. Toolkit applications should be immune to the effects of changes from earlier 
conventions because the conventions are implemented by code hidden in a standard widget 
called Shell. However, you should be aware that some older applications and window man- 
agers do not play by the current rules. 

1.5 Extensions to X 

X is also extensible. The code includes a defined mechanism for incorporating extensions, so 
that vendors aren't forced to modify the existing system in incompatible ways when adding 
features. An extension requires an additional piece of software on the server side and an 
additional library at the same level as Xlib on the client side. After an initial query to see 
whether the server portion of the extension software is installed, these extensions are used 
just as Xlib routines and perform at the same level. 
As time goes on, some extensions will become a basic part of what is called "X," and perhaps 
will become X Consortium standards themselves. For example, MIT has developed a pack- 
age of extensions that includes support for non-rectangular windows, which has become 
widely available. The C programming library used to access these features is -lXext. 
Among the extensions currently being developed are support for 2-D spline curves, 3-D 
graphics, and display PostScript TM. These extensions can be used in Toolkit applications just 
as Xlib can. 

Introduction to the X Window System 13 



2 

Introduction to the 
X Toolkit and Motif 

This chapter provides a conceptual introduction to the X Toolkit (including the 
Motif widget set), followed by a practical tutorial that starts with the most fun- 
damental toolkit program, a "hello world" type application consisting of only a 
single widget. This application is successively refined until the major ele- 
ments of any X Toolkit program have been introduced. 

In This Chapter: 

Programming with Widgets .................................................................. 17 
About Widget Sets ........................................................................... 20 
Widget Classes and Instances ......................................................... 22 
Widget Configurability with Resources ............................................. 25 
Widget Independence ...................................................................... 27 
Widget-Application Interaction .......................................................... 29 
Xt and Object-oriented Programming (OOP) .................................... 32 
The Object ..................................................................................... 32 
Methods ........................................................................................ 33 
Messages ..................................................................................... 33 
Encapsulation ................................................................................ 33 
Structure of Motif Applications ............................................................. 34 
A Simple X Toolkit Application .............................................................. 35 
The Code ........................................................................................ 36 
Compiling the Application ................................................................. 39 
The App-defaults File ....................................................................... 39 
To Hardcode or Not to Hardcode ..................................................... 43 
Connecting Widgets to Application Code .............................................. 44 
Callbacks ......................................................................................... 45 



More About Resources ........................................................................ 49 
Setting and Getting Resources from the Application ......................... 49 
Setting Resources with the Varargs Interfaces ............................... 50 
Setting Resources with the ArgList Interfaces ................................ 51 
Getting a Resource Value .............................................................. 53 
Core Resources ............................................................................... 54 
Other Inherited Resources ............................................................... 57 
Advice on X Programming ................................................................... 60 



2.1.1 About Widget Sets 

Shell widgets, and a few other base widget classes (Core, Composite, and Constraint) that are 
used to build more complex widgets, are defined by Xt. The special-purpose application win- 
dow is written by the application programmer. All of the other widgets shown in Figure 2-1 
come from a widget setna library of pre-built user-interface components. Specifically, they 
are from the Athena widget set, developed at MIT. 
The Athena widget set is distributed free along with the MIT X Window System distribution, 
and as a result, is the basis for many of the demonstration applications shipped by MIT and a 
great deal of public-domain X software. However, the Athena widget set was not intended to 
be complete Bit was built mainly for testing and demonstrating the Intrinsics. Furthermore, 
the Athena widgets do not have a particularly attractive appearance nor user-interface con- 
ventions. For these reasons, we suggest that serious application development efforts should 
begin with a commercial widget set. 
Two commercial widget sets that are easily available and quite complete are OSF's Motif 
and AT&T's OPEN LOOK widgets. Both Motif and OPEN LOOK contain menus, scrollbars, 
command buttons, dialog boxes, and a wide variety of composite widgets. Both have an 
attractive appearance and consistent, well defined user-interface conventions. Each comes 
with a style guide that contains suggestions for designing applications to blend in well with 
other applications using that widget set. 
In order to highlight some of the added value provided by a commercial widget set such as 
Motif, Figure 2-2 shows the same hypothetical application constructed with Motif widgets, 
and with a titlebar provided by the mwm window manager. 
As you can see, Motif has a distinctive appearance, using shadowed outlines to simulate a 
3-D appearance (buttons appear to be pushed in when you click on them, and so forth). What 
is more important, Motif has conventions about the use of its widgets that lead to a consistent 
look among all applications using Motif. The OSF/MotifStyle Guide contains recommenda- 
tions for application design and layout, and whenever possible, these recommendations are 
actually embodied in the design of the widget set. For example, the Motif MainWindow 
widget provides a menubar at the top of the application, which can contain titles for standard 
"pulldown" menus for file manipulation and on-line help, as well as for various application 
functions. 
Motif also provides many more widgets than Athena, making it easy to create control areas 
such as radio boxes (groups of buttons, of which only one can be chosen at a time) or check 
boxes (groups of buttons that may be set independently of each other, say for making applica- 
tion configuration choices.) There are also convenience functions for creating many common 
combinations of widgets. 
The mwm window manager provides similar functions to twm, but also always provides sup- 
port for a help feature (invoked by clicking on the box in the upper fight comer of the 
titlebar). 

*The Athena widgets are described on reference pages in Volume Five, X Toolkit lntrinsics Reference Manual. 

20 X Toolkit Intrinsics Programming Manual, Motif Edition 



provides a more complete description of how to use each Motif widget, how to properly 
design an application according to the Motif style guide, and how to use the Motif-specific 
features and functions. 

2.1.2 

Widget Classes and Instances 

A widget set defines classes of widgets. DrawingArea is a class of widget, as are Arrow- 
Button, PushButton, ScrollBar, and the various widgets shown in our hypothetical applica- 
tion.* Each time you create a widget, you create an instance of one of these predefined 
classes. For example, you might create several PushButton widgets, each with a unique 
name, containing a unique text label, and each invoking different application code when it is 
clicked on. All these widgets would be of class PushButton. They would have similar char- 
acteristics, but they would not necessarily look or act exactly the same since each could have 
been configured differently. 
A widget class has certain fixed features which are common to all instances of that class, and 
certain characteristics which can be changed from one instance to the next. 
How yot/view a class depends on whether you are using existing widget classes or are also 
writing new ones. Eventually you will thoroughly understand both these views of a class, 
since you will be competent in both using and writing widgets. For the first four chapters of 
this book, we will concentrate on the widget user's point of view. Both views are introduced 
here because we don't want to mislead you by telling you only the widget user's view, half 
the story of what a class is. 
For a user of existing widget classes (a widget set), a widget class is a black box that has cer- 
tain fixed features and certain configurable features, both of which are documented on the 
widget class's reference page. You need not know anything about how a class is imple- 
mented in Xt. You know that when you create an instance of that widget class, the instance 
will have the documented fixed features and that you can set the configurable features. A 
user of existing widget classes is most interested in the configurable features, since setting 
these is a big part of programming an Xt application. Each configurable feature is called a 
resource. Resources are more fully introduced in the next section. 
If you are writing a widget class, or if you have written one and see things from that perspec- 
tive, a class seems slightly different. To you, a widget class is a set of files in which the 
widget class is implemented. The widget class is no longer a black box--it is an open box. 
Knowing what widget class code looks like, you know that its fixed features and its configur- 
able features are implemented in distinct sections of the code. You know that each resource 
is actually represented by a field in a structure. You know that each class has a structure (the 
class structure) that contains all the fixed features (both code and data) of that class. Even 
though you don't necessarily have access to the source code for a widget class, your defini- 
tion of a class is based on how that class is implemented. 

*The names of all Motif widget classes actually begin with Xm. However, to make the text more readable, we have 
omitted the Xm prefix when referring to these widgets, except in examples and discussions of code where the prefix 
must actually be used. 

22 X Toolkit Intrinsics Programming Manual, Motif Edition 



Figure 2-3 illustrates these two ways of viewing what a class is. 

The widget user's view 

Documented 
Inputs 

(implementation hidden) 

Documented 
Outputs 

Documented 
Inputs 

The widget writer's view 

.c file 

.h file 

P.h file 

(implementation exposed) 

Documented 
Outputs 

Figure 2-3. Two ways to think about a class 

These two views of a class take on special relevance when looking at a characteristic of the 
Toolkit called class inheritance. Widget features and characteristics can be inherited from 
other, more basic classes of widgets. To a widget user, class inheritance is important only 
because it means that the resources (configurable features) of a widget class are defined not 
only by the class itself but also by the classes from which the class inherits features, called its 
superclasses. When you look up a widget class's features on its reference page, either all its 
superclass's resources will be described, or you will have to look up its superclass and look 
on that page also, and continue up the class inheritance hierarchy to the most basic widget, in 
order to get a complete list of its capabilities. This sounds difficult, but in reality you get to 
know the features of the most basic classes by heart, and the classes are not deeply nested. 

From the widget writer's point of view, inheritance means that a new class of widget needs to 
define only its own unique features, and need not re-implement features common to all widg- 
ets, or already implemented by an existing superclass. All classes exist in a single-inheri- 
tance hierarchy that defines which other classes each class inherits features. (Note that the 
class hierarchy is completely different from the parent-child relationship of widget instances 
you create in an application. The class hierarchy of a particular widget set is fixed by the cre- 
ators of the widget set, while the instance hierarchy is different in every application, and is 
determined solely by the writer of the application. The instance hierarchy specifies which 
widgets contain which other widgets on the screen.) 

Figure 2-4 shows the class inheritance hierarchy for the Motif widget set. Classes defined by 
Xt (which are the same for all widget sets) are shaded gray.* This section describes the Xt 
classes, as well as the most basic Motif classes, in order to clarify the concept of classing as 

Introduction to the X Toolkit and Motif 23 



The Motif Primitive widget class inherits basic widget features from Core and adds a few 
minor features of its own (for example, control of Motif style 3-D shadows) that are common 
to many Motif widgets. The Label widget in turn adds the ability to display a string or a pix- 
map, and adds mechanisms for changing the font and placement of the string. PushButton 
then inherits features from Label (including those already inherited from Core and Primitive) 
and adds more features, such as the ability to accept user input and highlight the button. 
PushButton is known as a subclass of Label, and Label is the superclass of PushButton. In 
general, lower classes in the hierarchy have more features. 
The Composite class adds geometry-management capabilities to the basic characteristics 
defined by Core. Consa'aint is a further refinement of Composite that allows the application 
or the user to supply instructions on how the size and position of each child should be man- 
aged. All Motif geometry-managing widgets are subclasses of Manager, which is itself a 
subclass of Consla'aint. Manager is Motif's equivalent of Primitive for geometry-managing 
widgetsmit adds features such as 3-D shadows so that they are available in virtually all 
Motif widgets. 
Shell is a special class of Composite widget designed for interaction with the window 
manager. 
New widgets can be subclassed by the widget programmer directly from Core, Composite, or 
Consa'aint, or can be subclassed from an existing widget in any widget set that has some of 
the desired behavior. For example, it is easy to imagine creating a subclass of Primitive in 
order to develop a custom graphics window. 
As long as appropriate widget classes are available, the application programmer needs to 
know little or nothing about widget internals. In fact, even if widget internals are known, it is 
unwise to depend on them. Widgets should be treated as black boxes with documented 
inputs and outputs. If only these documented interfaces are used, the widget internals can be 
modified without affecting the application, and the application can be modified without 
affecting the widget. 

Widget Configurability with Resources 

To serve their purpose as reusable user-interface components, widgets must be highly confi- 
gurable. For example, an application programmer must be able to define not only a separate 
label for each PushButton widget, but also the application function that is invoked when the 
button is clicked. The programmer will also want to let the user define additional atla'ibutes 
such as font and color. 

To support this degree of configurability, widget classes can declare variables as named 
resources of the widget. The application can pass the value of widget resources as arguments 
to the call to create a widget instance, or can set them after creation using the Ina'insics call 
xt:set:vaa_ues. Even before that, though, as an application starts up, a part of Xlib called 
the resource manager reads configuration settings placed in a series of ASCII files by the user 
and/or the application developer, and Xt automatically uses this information to configure the 
widgets in the application. The collection of resource name/value pairs contained in the vari- 
ous resource files and set directly by the application is collectively referred to as the resource 
database. 

Introduction to the X Toolkit and Motif 25 



Figure 2-5 shows several Label widgets configured with different resource settings, to show 
you how radically the appearance of even such a simple widget can be altered. Note that a 
widget's input characteristics can also be configured (although the Label class has no input 
characteristics to configure). 

Mu ndo ! I 

Figure 2-5. Several Label widgets configured using resources 

The resource manager provides a flexible mechanism for generalizing the behavior of widg- 
ets. The application developer can "hardcode" the value of those resources that must not be 
changed because they could cripple the application (as when changing the label of the Quit 
widget to Save), and can establish reasonable defaults for other resources, so that the user can 
configure all nonessential aspects of an application's look and feel. 
Note that the term "resource" is used somewhat ambiguously in X. First, in the original doc- 
umentation for Xlib and the X Protocol, various data structures that are maintained by the 
server and identified to clients only by an integer ID are referred to as resources. These data 
structures include windows, colormaps, fonts, and so forth. In this series, these are normally 
called server resources where there is possible confusion. 
Second, the term is commonly used to refer both to a widget variable publicly declared as a 
widget resource, and to the name/value pairs in the resource database. In this book, we will 
use the term resource to refer to the actual variable and its current value in a widget instance, 
and the term resource setting to refer to a name/value pair in the database. The two are 
closely related, but may not be identical. For example, separate settings for the same 
resource may be requested in an app-defaults file and in an individual's user-preference file.* 
Furthermore, the value of a resource may be set on the fly by a call to xt:Set:Va'l ues, but 
*There are several possible sources of resource settings. If two or more contain resource settings for the same re- 
source of the same widget, which will actually take effect is determined by rules of precedence that are described 

26 X Toolkit Intrinsics Programming Manual, Motif Edition 



this value is never saved in the resource database. (This value can be retrieved from within a 
widget or application by a call to Xt:Get:Va].ues.) 

2.1.4 

Widget Independence 

Each widget operates, to a large degree, independently of the application. Xt dispatches 
events to a widget, which performs the appropriate actions according to the design of its 
class, without application help. For example, widgets redraw themselves automatically when 
they become exposed after being covered by another window.* Widgets also handle the con- 
sequences when the values of their resources are changed. An instance of Label, for 
example, does not depend on the application that created it to determine its size. By default, 
Label will choose a size large enough to accommodate the current string in the current font. 
If the application changes the text or font in the Label widget with a call to xt:set:va].ues, 
the Label widget itself will attempt to keep its own window large enough to accommodate 
the current string. (Of course, if necessary, the application can also explicitly choose the 
Label widget's size.) When the application tells a Label widget what font to display its string 
in, the widget knows how to load a new font, recalculate its own size, and redraw its 
string--the application doesn't have to micro-manage any of this. The application simply 
sets the font resource of the widget, and the widget does the rest. 
Figure 2-6 and Figure 2-7 illustrate how a widget operates independently of the application 
and how xt: Set:va].ues lets the application set how a widget operates itself. 

(along with the various sources of resource settings) in Chapter 10, Resource Management and Type Conversion. 
*Redrawing is necessary because the contents of X windows are maintained by the X server only while they are visi- 
ble. When one window is obscured by another, the contents of the obscured area of one of the windows is lost and 
must be redrawn when it later becomes exposed. X clients are responsible for redrawing the contents of their win- 
dows when this happens. Fortunately, Xt automatically redraws correctly written widgets at the appropriate times so 
that your application doesn't have to worry about this. 

Introduction to the X Too/k# and Motif 27 



I Server " 
Network 

Widget 

Expose and user 
events 

lntrinsics 
routines 

Widgets operate independently of the application ... 

Figure 2-6. Widgets operate independently of the application 

28 X Toolkit Intrinsics Programming Manual, Motif Edition 



during the startup phase, and how Xt then calls the function during the event-loop phase in 
response to a particular occurrence in the widget. 

Server 

Network 

register callback routines 
(or, less often, action 
routines) 
Application Code 

Xt 
Intrinsics 
routines 

... and the application can provide and register callback or action 
functions with the widget o.. 

Figure 2-8. Application registers a function with Xt during startup phase 

There are three separate mechanisms that can be used to link widgets and application func- 
tions: callbacks, actions, and event handlers. 
Generally speaking, a widget expecting to interact with an application will declare one or 
more callback lists as resources; the application adds functions to these callback lists, which 
will be invoked whenever the predefined callback conditions are met. Callback lists are 
resources, so that the application can set or change the function that will be invoked. 
Callbacks are not necessarily invoked in response to any event; a widget can call the speci- 
fied routines at any arbitrary point in its code, whenever it wants to provide a "hook" for 
application interaction. For example, all widgets provide a dest:z:oyCal.'lback resource 
to allow applications to provide a routine to be executed when the widget is destroyed. All 
callbacks have what Motif calls a reason--a well-defined occurrence of some kind that 
causes the callback to be triggered. 

30 X Toolkit Intrinsics Programming Manual Motif Edition 



Server 
II 
Network 
t ents 
tl Intrinsics 
. routines 
.... ! Application Code, 

... which the widget will call when certain events occur The widget gives control 
back to the application for the duration of the callback or action routine. 

Figure 2-9. Xt calls the function during the event-loop phase in response to an occurrence 

Although a callback reason need not be an event, callbacks are often invoked by widgets 
from within actions, which are event-driven. Action routines are called directly by Xt in 
response to events specified in a translation table. Xt supports a high-level event-specifica- 
tion syntax, which allows easy specification of complicated event sequences (such as double- 
or triple-clicks, or key- and button-press combinations) as the trigger for actions. Further- 
more, the translation table is a resource, allowing the application developer or the user to 
configure the events that will invoke a given widget action. 

Actions are usually internal to the widget and require no interaction with the application. 
(For example, in the Text widget, all editing operations are carded out entirely by the widget, 
using functions defined as actions. The only role required of the application is to read and 
write files.) However, an application can also add actions to a widget, which can function in 
much the same way as callbacks, but without the widget class having made provision for 
them. 

Introduction to the X Toolkit and Motif 31 



The purpose of a well-designed widget set is to implement a particular user interface, which 
provides conventions designed to make all applications operate in the same way. A widget's 
callbacks are often designed to support the intended use of the widget, while adding actions 
to a widget can make it behave in ways the designer did not foresee and that the user might 
not expect. Nonetheless, there are cases in which the best way to implement the desired 
behavior is to add actions to an existing widget. 

In addition to callbacks and actions, it is also possible for an application (or a widget) to 
implement event handlers, which use an event-selection mechanism similar to that used in 
Xlib. Event handlers are rarely used by application programmers, since actions are simpler 
and configurable without recompiling. 

Some widgets also declare public routines, which can be used by an application to control 
aspects of the widget's behavior or to get widget data. Usually, the purpose of public rou- 
tines is to provide a more convenient means for setting or getting widget data that would 
otherwise have to be accessed through resources. 

2.1.6 

Xt and Object-oriented Programming (OOP) 

Xt provides an object-oriented programming (OOP) style, where the objects are widgets. 
However, since Xt is written in C, a language that provides no special support for OOP, Xt 
depends on programming conventions and programmer discipline to maintain the semblance 
of objects. It is very important that the programmer understand the goals and rules of OOP, 
because the language and the system won't enforce these rules. If you are familiar with 
another object-oriented system, you will need to understand Xt's particular implementation 
of OOP. On the other hand, if Xt is your first exposure to OOP, an explanation of its goals 
and concepts should make the whole system make a lot more sense. 
Traditionally, object-oriented programming is defined in terms of the five words object, 
method, message, class, and instance, and the concept of encapsulation. We've already 
talked about classes and instances. This section describes the remainder of these terms. 

2.1.6.1 

The Object 

In OOP, an object contains two elements: the data that represents a state, and code that reads 
or writes that data (called methods) and performs some action based on it. For example, the 
string displayed by a Label widget is part of its state data, and the code that actually draws 
the string on the window is a method that reads the state data and draws based on it. Inside 
widget code, the state data is represented as structure members, and the methods are repre- 
sented as pointers to functions. Some state data members are public; they are resources that 
can be set or retrieved from outside the object. Other state data members are private; they 
cannot be read or written from outside, but they help the widget keep its own house in order. 

32 X Toolkit Intrinsics Programming Manual, Motif Edition 



2.1.6.2 Methods 

2.1.6.3 

2.1.6.4 

What is called a method in traditional OOP is either a method or an action in Xt. In Xt, 
methods are a set of functions that are fixed for a particular class, triggered in fixed ways 
usually in response to Xt function calls made by the application (with one special case, the 
expose method, triggered directly by the Expose event). A widget's methods supply its 
most basic functions, such as the code needed to create a window, or to redraw itself. 
Actions, on the other hand, are called in response to the events specified in a translation table, 
aad thus the events that trigger actions are user configurable. Actions supply most of the fea- 
tures of widgets, and these features can be added to or replaced by the application, as demon- 
strated in Sections 4.3 and 4.4. 

From the widget writer's point of view, each method is just a function whose pointer has a 
place in the class structure. Each method has particular responsibilities in managing the 
basic functions necessary for a widget to be a widget. For example, every widget class must 
have a method that responds to calls to xt.set.val.ues. What each of the vital methods 
must do is described in Chapter 7, Basic Widget Methods. Each method has different argu- 
ments and returned values. 

Every action, on the other hand, has the same set of arguments. Actions generally perform 
the features of the widget that are triggered by events. You could say that actions are the 
widget's occupation: it needs them to do anything useful but not to exist. 

Messages 

In pure OOP, input to objects and communication between them are called messages. In Xt, 
however, the forms of communication are function calls, events, actions, and callbacks. As 
you have seen, applications can communicate with widgets using function calls, such as to 
set or get widget resources using xt.Set.va].ues and Xt.Get.Va]_ues. Widgets also 
respond directly to events from the user. Widgets contact the application when certain things 
occur using callbacks or actions. Widgets pass data back and forth using special kinds of 
events. All these types of communication can be thought of as forms of messages. 

Encapsulation 

Objects are intended to be black boxes with documented inputs and outputs. In other words, a 
program that uses an object must not depend on the internal implementation of the object, but 
instead only on the known inputs and outputs. This is called code encapsulation. The advan- 
tages of code encapsulation are that programmers can use the object without needing to 
understand its internal implementation (hiding details), and that the internal implementation 
of the object can be changed at any time because no other code depends on it. This can be 
stated in another way: it minimizes interdependencies. In large software projects, this one 
feature makes OOP worthwhile. 

This encapsulation is very effective in Xt. You should be able to get a long way toward com- 
pleting an application without even needing to know what the code inside a widget looks 
like, let alone the details that implement a particular widget. For that reason, in this book we 
don't show you what is inside a widget until Chapter 6, Inside a Widget. Even when you do 

Introduction to the X Toolkit and Motif 33 



creates a Shell widget that is designed to interact with the window manager and to be the 
parent for other widgets created in the application. 
The first argument to XtVaAppInitialize passes the address of an XtApp- 
Context. An XtAppContext is an opaque pointer to a large structure in which Xt 
will manage all the data associated with the application. The only use of the XtApp- 
Context returned from XtVaAppInitialize in a typical application is to pass it 
to XtAppMainLoop and possibly a few other functions. The true purpose for the Xt- 
AppContext being a public variable is complicated and is discussed later. 
The second argument (a string) is the class name of the application. It is the string that 
can be used in resource files to set resources for this application, and it is also the name of 
the app-defaults file, in which the application writer establishes default resource settings 
for the application. By convention, the class name is the same name as the application 
name (the string typed to invoke the application), except with the first letter capitalized, 
or if the application name begins with X, the first two letters capitalized. For the current 
application, the class name is XHello since the application name is xhello. 
The remaining arguments have special purposes that are not used in this application. We 
will introduce them briefly here but reserve complete treatment of them for 
Chapter 3, More Techniques for Using Widgets. The third and fourth arguments are a 
pointer to and length of an array of application-specific command-line arguments that 
you can define. The fifth and sixth arguments are the common argc and argv--which 
XtVaApplnitiali ze parses for a variety of standard X Toolkit options and the ones 
you defined in the previous arguments. The seventh argument is where you specify fall- 
back resource settings in case the app-defaults file is not installed properly. The final 
argument terminates a variable-length argument list which can be used to customize the 
Shell widget with resources: this application uses the default Shell widget and therefore 
provides no resource settings in the list. 
The Shell widget returned by the call to XtVaAppI nit i a 1 i z e is used as the parent of 
the first widget created in the application. 
The XtVaCreateManagedWidget call both creates the Label widget and tells the 
parent (the Shell widget) that the Label widget's geometry is to be managed. It is also 
possible to call XtVaCreateWidget and either XtManageChild or XtManage- 
Children separately, but this is usually done only if you want to create many children 
of a single widget, then put them all under parental management at once. 
XtVaCreateManagedWidget is used for creating any class of widget. The first 
argument is the instance name, which Xt uses to look up settings in the resource database. 
The second argument specifies the class of widget to create--this variable comes from 
the header file for that widget, and should always be found on the reference page for a 
widget The third argument is the parent, which in this case is the Shell widget returned 
by XtVaApplnitialize, but in a more complex example could be a composite 
widget deeper in a hierarchy of nested widgets. The fourth argument terminates a varargs 
list, unused in this example, that is for hardcoding widget resources. (More on varargs 
lists later.) 
Notice that XtVaCreateManagedWidget and XtVaApplnitialize each 
return a value of type Widget. This type is an opaque pointer that is used to refer to a 

Introduction to the X Toolkit and Motif 37 



2.3.2 Compiling the Application 

You can get the code for xhello.c and all the rest of the examples in this book via uucp or 
anonymous ftp, as described in the Preface. It is a good idea to compile and run each 
example as it is presented. 
The example programs come with Imakefiles that should make building them easy if you 
have the imake program (which should already be in/usr/binlXll on UNIX-based systems 
that have X11 Release 4 installed), and you need the configuration files, in/usrllib/Xll/con- 
fig on most UNIX-based systems. The source for imake and the configuration files are also in 
the XllR4 dislribution from MIT (see Appendix F, Sources of Additional Information, for 
how to get this disla-ibution). 
An Imakefile is a system-independent makefile that is used by imake to generate a Makefile. 
This is necessary because it is impossible to write a Makefile that will work on all systems. 
You invoke imake using the xmkmfprogram (also in/usr/bin/Xll and on the R4 distribution). 
Complete instructions for compiling the examples using imake are provided in a README 
file in the example source. Note that the examples are designed to work with Motif 1.1, and 
probably will not work with Motif 1.0. 
To compile any of the examples on a UNIX system without using imake, use the following 
command line: 
cc -0 -o filename filename.c -iXm -iXt -iXll 
If you want to do debugging, replace -O with -g in this command line. The order of the 
libraries is important. Xm relies on Xt, and both Xm and Xt rely on Xlib (the -IXll link flag 
specifies Xlib). 
Note that unlike the Athena widget set, Motif does not use the Xmu miscellaneous utilities 
library, or the Xext extension library, both provided by MIT. 

The App-defaults File 

As mentioned above, the resource mechanism allows widgets to be customized. Widget 
resources can be set from any one of several sources, including a user's resource file, the 
command line, or an application-specific defaults file. 
Each resource of a widget has a default value determined by the widget class that declared 
the resource. However, in many cases, the application wants a different default value, but 
still wants the user to be able to change the value of that resource. 
The Label widget is a case in point. Example 2-1 (xhello) sets the default string displayed in 
the Label widget, "hello," by naming the widget he22o in the call to XtVaCreate- 
ManagedWidget. It just so happens that the Label widget uses its widget name as the 
string to be displayed if no other string has been specified in the resource database. However, 
this trick doesn't exist for the other resources of Label or of other widgets. 

Introduction to the X Too&# and Motif 39 



Is the X Toolkit Too Complex? 
An editorial aside o_.--, ! : /...:t ,,J,, ;i ...................... 
Window systems may be simple to use, but they are very complex to program. The first 
tlu'ng that strikes the novice X programmer is how complicated everything is. Learning to 
program the X Window System, even with the help of the X Toolkit, is afar cry from learn- 
ing say, the C programming language, where the very first page of the tutorial presents a 
complete running program. The program itself is trivial, but this, the "hello worM" pro- 
gram, has become a tacit benchmark of programmability. The assumption is "'if you can't 
write "hello worM' simply, things are badly designed." 

In fact, "hello, worM" is a pathological example for X; it is a case where the stylized scaf- 
folding outweighs the functional code. You've just seen an X Toolkit equivalent to "hello 
worM," and it is nearly tlu'rty lines long. But it is node-independent, does device-indepen- 
dent graphics, and can be customized by the user to control what font to use, and what 
color to use for the border, background, and text. 

The "hello worM" example is indeed a good benchmark of language complexity, but it is 
not necessarily a good general benchmark for overall programming complexity. It is an 
especially poor measure for a system that encompasses a generalized distributed software 
environment, network communication, and device-independent graphics. Most people 
write complicated applications, not trivial programs like "'hello, worM," and it is the ease 
with which a complicated program can be written that is the true test of a language. 

For example, consider the difference in the number of lines of code between "hello worM" 
and a text editor. Kernighan & Ritchie's C Programming Language, where "hello worM" 
was first introduced, doesn't present an editor. However, Kernighan and Plaugher's Soft- 
ware Tools, an equally sacred reference from the same era, presents a text editor that con- 
tains well over one thousand lines. Furthermore, the editor is line-oriented, not screen- 
oriented. By comparison, because of the modular design of the Toolkit, and the develop- 
ment of widgets as reusable user-interface components, a programmer can construct a 
simple screen editor using the Motif Text widget in about 170 lines of code. This editor is 
user-configurable, device-independent, and based on a ready-made component that can 
easily be incorporated into any program needing to provide text-editing capabilities. 

This is not to invite absurd comparisons of incommensurate programming tools, but to 
emphasize that the complexity of X is the outgrowth of added functionality, not unneces- 
sary convolutions of straightforward algorithms. What really matters is what features are 
provided, how difficult is it to write the kind of application you want to write, and what 
performance can be achieved. 

--Mark Langley 

40 X Toolkit Intrinsics Programming Manual Motif Edition 



ble and almost ready for release, then it's time to determine which resources need to be hard- 
coded, and then to hardcode them. 

2.4 Connecting Widgets to Application Code 

The Toolkit is designed so that the code that implements the user interface and the code that 
implements application features can be kept separate. This is an advantage, because it allows 
either part to be modified without affecting the other. However, these two pieces of code 
need to be intimately connected, because the user interface must drive the application code. 
This section describes the two basic ways of making this connection using callbacks and 
actions. As mentioned earlier, the general idea of both techniques is that the application reg- 
isters functions to be called by Xt in response to occurrences within certain widgets. 
The two techniques differ in the way that the registered function is invoked. For callbacks, 
the trigger is an abstract occurrence defined by the widget, which may or may not be event 
related. When this happens, the routines on one of a widget's callback lists are invoked by 
the widget code, using a call to XtCallCallbacks or XtCallCallbackList. 
Actions, on the other hand, are invoked directly by Xt's translation mechanism, as the result 
of an event combination. 
An action is a function that performs one widget feature. A callback is a function that per- 
forms one application feature. This distinction should be kept in mind, but is not quite as 
clear as it sounds, since one widget feature is often the ability to call a function that imple- 
ments an application feature. In this case a callback is invoked by a widget from within an 
action routine. For example, the PushButton widget defines a callback resource called Xra- 
NactivateCallback and several action routines, one of which, Activate, simply 
calls the functions registered with the XmNactivateCallback resource. This combina- 
tion of the two mechanisms allows one to customize the abstract occurrence that triggers a 
callback. In other words, when these mechanisms are combined you can configure what user 
behavior will trigger the callback by using the translation manager which maps events into 
actions. 
The two mechanisms also differ in the way they are added to a widget. The application can 
add a callback routine to a widget using XtAddCallback or XtAddCallbacks only if 
the widget has declared a callback list as a resource. When a widget has a callback resource, 
it means that the widget writer foresaw that users of the widget would want to have applica- 
tion code called in response to a particular user behavior in that widget. Actions, on the other 
hand, can be added to a widget using XtAppAddActions without the widget's knowledge 
or consent. Usually actions are added when the feature to be added was not foreseen by the 
widget writer. 
A widget class may have more than one callback resource. The Motif ScrollBar widget, for 
example, has eight, in addition to those defined by its superclasses Primitive and Core! Each 
callback resource represents a very specific occurrence in the widget. This allows you to 
specify a different function to handle each of these different occurrences. One of these 
resources, XmNpagerncrerrtentCallback, is called when the user indicates that the 
information displayed should be paged down. XmNincrerrtentCallback is similar but it 

44 X Toolkit Intrinsics Programming Manual, Motif Edition 



Figure 2-11 shows the window that xgoodbye creates if you have installed the suggested app- 
defaults file (otherwise, it will display "goodbye"). It is suggested that you compile and run 
xgoodbye.c, testing its response to moving the pointer in and out of its window, and clicking 
the various pointer buttons on its window. 

....................... x  toodb  /e 
Go o db C_r u 1 

Worl d / 

Figure 2-11. The appearance of xgoodbye when the pointer is in the window 

This example is not as frivolous as it seems. Many applications use code identical to this to 
implement their "Quit" button. 

The code for xgoodbye.c is shown in Example 2-3. 

Examp 2-&xgoodbye.c: compcode 
/. 
* xgoodbye.c - simple program to put up a banner on the display 
* and callback an application function. 
*/ 

#include <stdio.h> 
/* 
* Include file required for all Motif programs 
*/ 
#include <Xm/Xm.h> /* Standard Motif definitions */ 

* Public include file for widgets we actually use in this file. 
*/ 
#include <Xm/PushB.h> /* Motif PushButton Widget */ 
/* 
* Quit button callback function 
*/ 
/* ARGSUSED */ 
void Quit(w, client data, call data) 
-- -- 
Widget w; 
XtPointer client_data, call_data; 
{ 
fprintf(stderr, "It was nice knowing you.\n"); 
exit(O); 

main(argc, argv) 
int argc; 
char **argv; 
{ 

46 X Toolkit Intrinsics Programming Manual Motif Edition 



Examp 2. xgoodbye.c: comp code ontinue 
XtAppContext app_context; 
Widget topLevel, goodbye; 
topLevel = XtVaAppInitialize( 

&app_context, 
"XGoodbye", 
NULL, 0, 
&argc, argv, 
NULL, 
NULL); 

/* Application context */ 
/* Application class */ 
/* command line option list */ 
/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

goodbye = XtVaCreateManagedWidget( 
"goodbye", /* arbitrary widget name */ 
xmPushButtonWidgetClass, /* widget class from PushB.h */ 
topLevel, /* parent widget*/ 
NULL); /* terminate varargs list */ 
XtAddCallback(goodbye, XmNactivateCallback, Quit, 
0 /* client data */); 
-- 
/* 
* Create windows for widgets and map them. 
*/ 
XtRealizeWidget(topLevel); 
/* 
* Loop for events. 
*/ 
XtAppMainLoop(app_context); 

And here is xgoodbye's app-defaults file: 

ExampM 2-4. XGoodbye: e app-deults file 
! Core resources 
*goodbye.width: 200 
*goodbye.height: I00 
*goodbye.alignment: XmALIGNMENT END 
-- 
' Label resources 
*goodbye.foreground: mediumblue 
*goodbye.fontList: *courier-bold*180*iso8859-1 
*goodbye.labelString: Click on me. 

The differences between xgoodbye and xhello all apply to adding a callback function. In this 
example we have some application code (the Quit function) that we register with Xt as a 
callback function for the widget called goodbye using the XtAddCallback call. 

The Quit function is defined before main, SO that we can use the function pointer Quit in 
the XtAddCallback call. It is also legal in C to declare Quit as a function pointer early 
in the application, but actually to define it further down in the source code. 

Introduction to the X Toolkit and Motif 47 



The following sections demonsu'ate how to set and get resources of an existing widget using 
the ArgList and varargs interfaces. The same form of arguments are used in many other func- 
tions that set resources, often while creating various types of widgets. Table 2-1 presents the 
parallel lists of Xt functions. The final arguments of all of these (many of which have not yet 
been described) are used in exactly the same manner as in the examples shown in Sections 
2.5.1.1 and 2.5.1.2. 

Table 2-1. Functions that Set Resources: ArgList and varargs Counterparts 

ArgList 

XtSetValues 
XtGetValues 
XtCreateWidget 
XtCreateManagedWidget 
XtAppCreateShell 
XtGetSubresources 
XtGetApplicationResources 
XtCreatePopupShell 
XtSetSubvalues 
XtGetSubvalues 
XtAppInitialize 

Varargs 

XtVaSetValues 
XtVaGetValues 
XtVaCreateWidget 
XtVaCreateManagedWidget 
XtVaAppCreateShell 
XtVaGetSubresources. 
XtVaGetApplicationResources 
XtVaCreatePopupShell 
XtVaSetSubvalues 
XtVaGetSubvalues 
XtVaAppInitialize 

2.5.1.1 

Setting Resources with the Varargs Interfaces 

The easiest way to set and get resources is to use the Xt functions xtvaSetValues and 
XtVaGetValues. Each of these functions takes a widget argument and a variable length 
list of resource name/value pairs, terminated by NULL. These interfaces are new to R4. 

Note that the resource to set is called XmNlabelString, and its value must be a special 
type called a compound string, represented by a structure of type xmSt ring. A single com- 
pound string can be multi-lingual, multiline, and multifont. A compound string contains a 
string, a character set, and a draw direction (left to right or right to left). The strings we 
specified in the app-defaults files for xhello and xgoodbye were automatically converted into 
compound strings by Xt. However, to set a string in the application code, we must do this 
conversion ourselves. This is done easily with the Motif function xmStringCreate- 
Simple (Motif provides numerous functions for manipulating compound strings.) 

Example 2-5 shows the code needed to change the string of a Label widget--this will work 
any time after the widget has been created, either before or after the widget is realized. 

50 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 2-6. Usg XtSetVaes  set a widget resoue 
Arg arg; 
static String new label = "Hi there." 
-- 
XmString compound; 

compound = XmStringCreateSimple(new label) ; 
-- 
XtSetArg(arg, XmNlabelString, compound); 
XtSetValues(w, &arg, i) ; 
XmStringFree (compound) ; 
The Arg type is defined as a structure containing the name and value pair that defines a 
resource: 
typedef struct { 
String name; 
XtArgVal value; 
} Arg, *ArgList; 
The definition of XtArgVal differs depending on architecture--its purpose is precisely to 
make code portable between architectures with different byte sizes. Its use in application 
code is demonstrated in Section 3.8.1. All resource values (in all varargs and ArgList calls) 
are limited to the size of XtArgVal, which is the largest of char *, caddr_t, long, 
int *, and proc *. This means that for larger pieces of data, a pointer must be used. For 
example, data of type float or double must be passed as pointers. The documentation 
for a widget class that declares a resource with a large value should document the fact that a 
pointer must be passed rather than the value itself. 
XtSetArg is a macro that makes it more convenient to set the two members of the Arg 
structure. If desired, you can also set the Arg structure members like any other C structure 
by using the. or -> syntax. 
Note that the first member of Arg is of type String, but should be set to one of the XmN 
resource name constants. 
XtSetValues is the call that actually changes the widget resource. You pass it the widget 
to be reconfigured, a list of Arg structures, and the length of the list. Example 2-6 sets only 
one resource, so the list length is 1. 
xtSetValues can set any number of resources of a single widget instance. Example 2-7 
shows the code necessary to set two resources. Compare this to Example 2-5 to see how 
much clearer the varargs interfaces are. 

Examp 2-Z Code fragment  set multip resoumes of a widget 
static String new label = "Hi there." 
-- 
XmString compound; 
Arg args[3]; 
int i; 

compound = XmStringCreateSimple(new label); 
-- 

52 X Toolkit Intrinsics Programming Manual, Motif Edition 



Table 2-2. Compound String Resources That Must Not be Freed After Querying 

Widget Class 

BulletinBoard 
FileSelecdonBox 

RowColumn 
Scale 
List 

Resource 

XmNdialogTitle 
XmNdirectory 
XmNnoMatchString 
XmNlabelString 
XmNtitleString 
XmNitems 
XmNselectedItems 

Example 2-9 showshow to quew a widgetresource using the ArgListintefface, XtGet- 
Values. 

Examp 2-9. Code fragment  get a widget msource using XtGetVaes 
define MAXLEN 256 

Widget hello; 
Arg arg; 
String p; /* NOTE - memory for array not allocated */ 
XmString compound; 

NULL) ; 

/* Label widget named hello created here. */ 
XtSetArg(arg, XmNlabelString, &compound); 
XtGetValues(hello, &arg, i); 

(void) XmStringGetLtoR(compound, XmSTRING DEFAULT CHARSET, &p); 
-- -- 

Note, however, that some resources are not designed to be queried. For example, translation 
tables and callbacks are compiled into an internal representation, so it is pointless to try to 
read them. 

2.5.2 

Core Resources 

The most basic widget class defined by Xt is Core. All widgets are subclasses of Core. 
Therefore, the resources of the Core class are available for all widgets. Table 2-3 shows the 
Core resources. Note that the resource name constants all begin with Xm. These constants 
are defined in the file <XmlXm.h>. In standard Xt, the resource name constants begin with 
Xt, and are defined in <Xt/StringDefs.h>. 

54 X Toolkit Intrinsics Programming Manual, Motif Edition 



If instead you use the x and y resources to try to set the position of the application: 
xgoodbye, x : 10 0 
xgoodbye, y : 10 0 
they are ignored also, for a similar reason. It is customary for the window manager to assert 
control over the position of the main application window (in this case the Shell widget 
goodbye), and take the value of these resources, whether set by the application or by the 
user, simply as "hints" to the desired behavior. There is no guarantee that the window 
manager will honor these hints. The application is generally free to move widgets within its 
own window, but not to move itself. The basic X philosophy is that the user (through the 
window manager), not the application, should be in control. (Kill the window manager, or 
run a window manager that honors application position hints, and the resource specifications 
shown just above will work.) 
Likewise, you will find that specifying: 
*goodbye .borderWidth : 10 
has no effect, while: 
*borderWidth : I0 
works. The reason for this behavior is that while the PushButton widget inherits the 
borderWidth resource from Core, it does nothing with its value. Only certain widget 
classes (Shells) use the borderWidth resource to set the border width of their window. 
Just because a resource is inherited by a widget does not mean that the widget's methods do 
anything to use its value. 
Another surprising fact appears if you set the foreground resource to the same color as 
the background. No text appears in the window, and it does not highlight itself when you 
move the mouse inside. However, if you click a button, you will find that the widget is still 
working. What is happening is that the background and foreground colors are now both 
white, and therefore there is no contrast with which to see the widget's drawing. The widget 
is not sophisticated enough to check that its two colors are not the same. (Adding this simple 
check would be easy, but it is much more difficult to tell whether two colors that are not the 
same contrast enough.) 
The cautionary point is that there may be unexpected interactions between resources in 
widget code. Like programs in general, widgets tend to do what you say, not what you mean. 
A well-designed widget will minimize ill effects, but given the amount of customization that 
is possible, it may take some time to uncover all the possible pitfalls. Unfortunately, the 
documentation for most existing widgets doesn't always do a good job of explaining how 
resources are used inside the widget. 

Introduction to the X Toolkit and Motif 59 



2.6 Advice on X Programming 

The X Window System is a very complex collection of software, not to try your patience, but 
to do things that no programming tools have done before. Not only does X provide tools to 
build a nice user interface, but it does so with network transparency, so that programs can run 
on any hardware and operating system and display on any other. 
Probably the best feature of all from the application developer's point of view is the 
portability of the source between hardware and operating systems. It is worth a lot of 
aggravation to be able to write just one version of a piece of software, and have it able to 
compile and run on anything from a PC-compatible to a Cray. 
The price you pay for these features is additional complexity. The key to programming X 
successfully is to keep things as simple as possible by keeping this complexity hidden. 
By choosing to use Xt and Motif, you have taken a first step to isolate your application from 
the details of the lower levels of X software. In general, use the highest-level tools available. 
Use Motif functions instead of Xt functions when equivalents are available, and Xt functions 
instead of Xlib functions. 
Also beware of configuring widgets too extensively. Every widget has many resources, and 
the number of possible permutations in even one widget makes it impossible fo OSF to test 
them exhaustively. At the same time, programmers tend to abuse this flexibility by overly 
configuring widgets. Often developers try to make Motif applications work in a particular 
way that MotiFs developers didn't intend or foresee. One way to avoid this problem is to 
make sure your intended interface conforms to the conventions specified in the OSFIMotif 
Style Guide. 
Although Motif will undoubtedly be improved to support even more varied interfaces, this 
will take time, and there will always be features that Motif will not support without 
contortions. If you can compromise a little on the details of how your interface should work, 
you will be better off. With Motif, you can get 90 percent of what you want in a very short 
time. Think twice before spending lots of time trying to get the last 10 percent. First think if 
there is some other user interface design that can fulfill your needs while being more 
consistent with Motif style. If you still insist on having that functionality, think carefully 
about the best way to implement it (and consult with someone who knows X intimately, 
because such a decision may require an understanding of Motif, Xt, and the lower levels of 
X). 
To be advised to compromise in this fashion may rub some programmers the wrong way. 
Most programmers program systems where they have total control over their environment. 
Many have the whole screen to play with, and worry about only one target system. In these 
environments, it is more practical to learn everything there is to know about the system, so 
that you can implement exactly what you want. Since X is a much larger piece of software 
than the operating system or toolbox of any one computer, it is less practical to obtain a 
complete understanding of every level of it. That's why it is better to use your creativity to 
design a good interface that can be implemented easily, using existing components in the 
ways they were designed to be used. 

60 X Toolkit Intrinsics Programming Manual, Motif Edition 



3 

More Techniques for Using Widgets 

This chapter describes how to use some of the more complex widgets found 
in applications, including composite widgets, constraint widgets, and popups. 
It also describes how to define application resources and command-line 
options, and how to hardcode the value of widget resources when you create 
a widget. 

In This Chapter: 

Using Composite Widgets .................................................................... 63 
Setting Resources for an Instance Hierarchy ................................... 66 
Geometry Management in Practice .................................................. 67 
Using Constraint Widgets .................................................................... 71 
The Standard Motif Instance Hierarchy ................................................ 74 
Motif Widget Creation Routines ........................................................ 75 
Building a Main Window ................................................................... 75 
Using Popups ...................................................................................... 78 
Creating a Basic Menu .................................................................... 79 
Creating a Basic Dialog Box ............................................................ 81 
Popup Window Hierarchy ................................................................. 85 
More About Callbacks .......................................................................... 86 
Passing Data to Callback Functions ................................................. 87 
The client_data Argument .............................................................. 87 
The call_data Argument ................................................................. 89 
Callback Lists .................................................................................. 90 
Application Resources ......................................................................... 91 
The Application Data Structure ........................................................ 92 
The Resource List ........................................................................... 92 
Getting the Resources ..................................................................... 96 
Command-line Options ........................................................................ 97 
Standard Command-line Options ..................................................... 98 



Defining Your Own Command-line Options ...................................... 99 
Preventing User Customization of Widget Resources ......................... 103 
Using the Varargs Interfaces .......................................................... 104 
Using the Argument List Interfaces ................................................ 106 
Another Way to Set Arguments .................................................... 107 
Merging Argument Lists ............................................................... 109 
More About Application Contexts ....................................................... 109 



Press Me 
_._._J.J 

Figure 3-1. xrowcolumn: appearance on the screen 

Example 3-1 shows the code that implements xrowcolumn. 

Example 3-1. xrowcolumn.c: complete code 
/, 
* xboxl.c - simple button box 
*/ 

* So that we can use fprintf: 
*/ 
#include <stdio.h> 

* Standard Motif include file: 
*/ 
#include <Xm/Xm.h> 

* Public include files for widgets used in this file. 
*/ 
#include <Xm/RowColumn.h> 
#include <Xm/PushB.h> 

* quit button callback function 
*/ 
/*ARGSUSED*/ 
void Quit(w, client_data, call_data) 
Widget w; 
XtPointer client_data, call_data; 
{ 
exit (0) ; 

* "Press me!" button callback function 
*/ 
/*ARGSUSED*/ 
void PressMe(w, client_data, call_data) 
Widget w; 
XtPointer client_data, call_data; 
{ 
fprintf(stderr, "Thankyou!\n"); 

64 X Toolkit Intrinsics Programming Manual, Motif Edition 



At the same time, if you are creating a lot of widgets, it pays to consider using gadgets 
instead of widgets. A gadget is a windowless widget, with somewhat reduced features. 
Motif provides gadget versions of many of its smaller, simpler widgets, such as PushButton. 
The gadget version of PushButton is PushButtonGadget. For the most part, gadgets are 
created and used just like widgets. Since a gadget has no window, it loads the server and the 
network less and can attain better performance. For example, one of the Motif demos, 
xmfonts, creates over 100 PushButtonGadgets as children of a single RowColumn widget. In 
that case, it definitely makes sense to use gadgets. Probably the most common use of gadgets 
in applications, though, is for the panes in menus. Therefore, we will reserve our major dis- 
cussion of gadgets until Chapter 13, Menus, Gadgets, and Cascaded Popups. 

3.1.1 

Setting Resources for an Instance Hierarchy 

You have already seen how an app-defaults file can set the string for a PushButton widget. 
However, xrowcolumn has an instance hierarchy that contains a RowColumn widget with 
two PushButton widgets as children. It is worth seeing how to set the PushButton widget 
labels in this new situation. (We will be returning often to the subject of setting resources, 
because it is so important to Toolkit programming. Each time, new ideas will be presented.) 

Example 3-2 shows an app-defaults file for xrowcolumn. 

Example 3-2. XRowColumn: app-defaults file 
*pressme. labelString : Press Me 
*quit. labelString : Quit 
*XmPushButton. fontList : variable 
*XmRowColumn. background : green 4 
When an application contains multiple widgets of the same class, resource specifications can 
either identify individual widget instances by name or can use wildcards or widget class 
names to reference more than one widget. The first two specifications in the example iden- 
tify the pressme and quit widgets by instance name. The third specification uses the 
class name PushButton to set the font of both PushButton widgets in the application. 
This line shows that resources of groups of widgets can be set with a single line. The fourth 
specification uses the class name RowColurtua to set the background of the RowColumn 
widget (but not the PushButton widgets) to the color green. Whenever you use a class name, 
it will match all widgets of that class in the application, even ones we add later in a later revi- 
sion of the application. 
By changing the period in the fourth specification to an asterisk, the specification will change 
the background color of not only all RowColumn widgets in the application, but also all their 
children, and their children, recursively. Remember from Chapter 2 that an asterisk matches 
zero or any number of intervening widget instance names or class names. In xrowcolumn, 
this setting will make the background of the RowColumn and PushButton widgets green. Try 
not to get careless with asterisks, though. They lead you to think you don't have to remember 
the instance hierarchy in your application, but this can backfire, because it is easy to set 
resources on more widgets than you realize. 

66 X Toolkit Intrinsics Programming Manual, Motif Edition 



the shell widget, to be resized, and this will be denied unless mwm allows the shell to resize 
itself. However, it is possible to set things like geometries in the application code, as will be 
demonstrated later in this chapter. 
Every widget's size and position is ultimately under the control of the window manager.* A 
RowColumn widget attempts to make itself just big enough to hold its children, using the 
resources provided by the application as a guide, but the window manager can override any- 
thing the widget or the application does. 
What happens when the user resizes an application is only part of the picture. The applica- 
tion itself may need to resize one of its widgets in order to display more widgets. Or the 
application may tell a widget to display more data and the widget will have to ask its parent 
to be resized. For example, what happens when the application changes the string in one of 
the PushButton widgets while the application is displayed? The PushBuuon widget attempts 
to resize itself to display the current string, by asking its parent for permission. 
Whether this request is granted depends on the position of the widget in the instance hier- 
archy, the resizing policy imposed by each composite widget in the hierarchy, and the win- 
dow manager. This is because each widget, from the PushButton widget on up, negotiates 
with its parent when the PushButton widget requests a new size. The PushButton widget 
tries to change size to accommodate the new string (larger or smaller), and the RowColumn 
widget must approve this change. Since the RowColumn widget is already the same size as 
the Shell widget, RowColumn can't get any larger without asking Shell. The Shell widget is 
responsible for negotiating with the window manager. 
The mwm window managers will allow applications to resize themselves only if the user has 
set the allowShellResize resource to True. (Some other window managers, such as 
twm, never allow it.) Otherwise, the RowColumn widget will reject the resize request unless 
the original change made the PushButton widget smaller. If the new size is rejected, the 
PushButton widget will still display the new string, but it may not show all of the string (if 
the new string is longer than the old one) or there may be extra space left over (if the old 
string was longer). 
Fortunately, all this negotiation is done by the widgets themselves. The application doesn't 
need to do anything. However, you should be aware that any widget resource change that 
results in a widget size change may not work unless there is enough room in the application 
for the change to be granted without resizing the top-level window. 
The RowColumn widget is Motif's most comprehensive and powerful geometry managing 
widget. It is widely used for managing groups of small widgets in many settings. (Some of 
these uses of RowColumn are under other names, such as CheckBox, PullDownMenu, and 
MenuBar.) However, it treats all its children the same, and therefore isn't appropriate for 
widgets of radically different geometries. RowColumn's decisions about where to place the 
widgets can be inappropriate. Figure 3-3 shows the results upon resizing of a RowColumn 
widget that is attempting to manage two ScrollBar widgets and a BitmapEdit widget.' 

*BulletinBoard creates an exception to this rule. Since BulletinBoard never resizes its children, the window manager 
controls which of these children are visible, but does not resize them. 
%The BitmapEdit widget is not part of the Motif widget set. It is used to build an application in Chapter 4, An Ex- 
ample Application, and written from scratch in Chapter 6, Inside a Widget, and Chapter 7, Basic Widget Methods. 

68 X Toolkit Intrinsics Programming Manual, Motif Edition 



Print Array 

Figure 3-3. Results upon resize of ScrollBar widgets inside a RowColumn widget 

Those two large triangles are actually ArrowButtons on the ends of a very wide but short 
ScrollBar! It might be possible to use the RowColumn resources to make this application 
look better, but it would be difficult to keep it good looking after resizing. 
Because no single geometry managing widget can satisfy all needs, there are several different 
types of composite widgets in most widget sets, each with different rules about how it places 
children. Many widget sets, including Motif, have a widget specifically designed to place 
scrollbars next to a main window. In Motif, this widget is called ScrolledWindow. 
Of course, applications are not limited to using only one composite widget. It is quite com- 
mon for the application's main window to be a large composite widget which contains sev- 
eral smaller composite widgets, each of which in turn contains certain groups of related 
widgets. You'll need to design the layout of widgets in your application, decide where in the 
instance hierarchy to place composite widgets, and experiment to find out which composite 

More Techniques for Using Widgets 69 



edge of Form with the XmNleftPosition or XmNleftOffset resources. The lat- 
ter is a fixed distance that won't change after resizing. 
2. Reladve to an edge of one of the other children. To do this, you set the XmleftAt- 
tachment tO XmATTACH_WIDGET, and set XmNleftWidget to the Widget ID of 
the other child you want this child to be next to. XmNleftWidget can only be set in 
the application code, not in resource files. 
3. To a percentage posidon within the Form widget (i.e., 50% would place the edge in the 
center of the Form widget, and upon resizing the edge would always be centered.) Set 
XmNleftAttachment tO XmATTACH POSITION, then set XmNleftPosition 
and XmNfractionBase so that XmNleftPosition / XmNfractionBase is the 
fracdon of the width of the Form where the edge should be located. 
4. To a percentage position established by the child's initial position within the Form 
widget. For example, if the application code initially positioned the child edge 20 pixels 
horizontally from the Form origin, and XmNfract'i onBase is set to 100 to represent 
the initial width of the Form, then the child edge will always be kept at 20% of the width 
of the Form. Set XmNleftAttachment to XmATTACH_SELF, then set XmNfrac- 
tionBase SO that the current XmNx position divided by XmNfractionBase is the 
fraction of the width of the Form where the edge should be located. The difference 
between XmATTACH_POSITION and XmATTACH_SELF is only that the former 
requires the setting of XmNleftPosition, while the latter takes the initial position 
directly from the child. 

Note that the XmNresizable resource is a constraint that controls whether a child is 
allowed to resize itself, or be resized by the application. It does not affect whether the Form 
widget will resize that widget--Form is always allowed to resize any of its children. 
The Form also has a number of normal resources (that are set on the Form, as opposed to con- 
straint resources that are set on its children) that control default distances and so on. One of 
these is XmNrubberPositioning, which governs how unattached edges of children 
behave. 
OSF has chosen to make some Form constraints not settable from the app-defaults file, so 
they must be set in the application code. Although this is where they should be set in a final 
commercial product, it makes debugging more difficult, since the code must be changed and 
recompiled every time a new combination of Form constraints is to be tried. Example 3-3 
shows the resource settings in xform.c that position the two PushButton widgets within the 
Form. This technique for setting resources in code is described in Section 2.5.1.1. 

Examp 3-3. xrm: constrat resource seings added 
} 
Widget quit, pressme; 
. 
. 
. 
quit = XtVaCreateManagedWidget("quit", /* widget name */ 
xmPushButtonWidgetClass, /* widget class */ 
form, /* parent widget*/ 
XmNleftAttachment, XmATTACH WIDGET, /* resource setting */ 

72 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 3- xrm: constrat resource seings added ontinue 
XmNleftWidget, pressme, /* resource setting */ 
NULL); /* terminate varargs list of resource settings */ 

) 
Notice that since these are constraints, these resources are being set on the quit child of 
Form, but the Form will actually use this information. It is actually an instruction for the 
Form widget about where to place the quit widget relative to the pressme widget. The 
effect of this resource setting is shown in Figure 3-5. Note that both widgets referenced in a 
constraint must be child widgets of the same constraint widget, in this case the Form widget. 
If they are not, Form will print a message at run time. 
If you run this program, you can compare its behavior on resize with the behavior of 
xrowcolumn, and you can experiment with different resource settings for the Form widget. 

* pressme.leftAttachment: XmATTACH_WlDGET 

Quit 

Press Me 

*pressme.leftWidget: quit 

Figure 3-5. Effect of the Form XmA TTACH_ WIDGET constraint resource 

Both the Form and RowColumn widgets are able to resize the PushButton widgets in addi- 
tion to or instead of moving them. In the Athena widget set there is a composite widget, Box, 
that moves but never resizes its children. Note that the difference between composite and 
constraint widgets is not their ability to resize children; it is that constraint widgets allow dif- 
ferent layout rules for each child. 

Without constraint settings, Form widgets pile up their children. This can also happen if you 
make an error in setting the constraints. Sometimes this can make it appear that one of the 
widgets has completely disappeared! 

More Techniques for Using Widgets 73 



3.3 The Standard Motif Instance Hierarchy 

Most Motif applications have a standard screen layout, which leads to a certain amount of 
boilerplate code in every application. This section describes that code. Figure 3-6 shows an 
example application, xmainwindow, which has this standard layout. Of course, in a real 
application the lower area would be more than an empty box. 

Figure 3-6. xmainwindow: an application with standard Motif screen layout 

Customarily, the first widget created in a Motif application (after the one created by Xt:Ap- 
pTnJ_t:J_a].J_ ze) is a MainWindow widget. A MainWindow is a geometry managing widget 
designed to manage a work area (often a custom window) with scrollbars, and optional 
menubar and Command widgets. In a drawing application, the drawing area would be the 
custom window, and MainWindow would automatically manage scrollbars that would allow 
the user to draw in an area larger than the application's total screen area. In our first example 
that includes a MainWindow, the work area will be simulated with a Frame widget, which is 
an empty box with a 3-D appearance. 
Most Motif applications also have a menubar across the top of the main window. Visually, 
the menubar contains labels which indicate the titles of the menus available. In widget terms, 
each of these labels is a CascadeButton, which is similar to a PushButton except that Cas- 
cadeButton is specifically designed to invoke a pulldown menu or dialog box instead of an 
application function. Two of the most common labels visible in a menubar are File and Help. 
The File button brings up a menu that includes the commands for reading and writing files, if 
any, and also the command to quit the application. According to the Motif style guide, the 

74 X Toolkit Intrinsics Programming Manual, Motif Edition 



File button has the position at the far left in the menubar, and the Help button has the far 
right.* The Help button brings up a dialog box which contains help text appropriate for the 
current situation. 

A Command widget is another horizontal band across the application, just below the work 
area. A Command widget contains two windows, one that allows you to type in commands, 
and the other that shows you the history of prior commands. The Command widget is 
optional in a MainWindow and is less common than the menubar. 

3.3.1 

Motif Widget Creation Routines 

All the previous examples have used XtVaCreateManagedWidget tO create widgets. 
As you may recall, you specify which type of widget you want by supplying an argument 
such as xmPushButtonWidgetClass. But Motif also provides its own functions for 
creating widgets. To create a PushButton, MotiFs function is XmCreatePushButton. 
Note, however, that Motif's function does not manage the widget, so you need to call 
XtManageChild separately. (If you forget, the widget won't be visible.) Also, as you 
will see later, it is harder to set widget resources with the Motif widget creation functions. In 
the cases where the two techniques are identical, our examples stick with the basic Xt rou- 
tine.t 
In some cases, however, the Motif widget creation routines have code beyond just calling the 
Xt widget creation routine. Some set resources in particular ways. For example, 
XmCreateMenuBar actually creates a RowColumn widget, but with some special 
resource settings. It is a lot more convenient to use XmCreateMenuBar than to use the Xt 
widget creation routine and set the resources yourself. 
As in the case of XmCreateMenuBar, the Motif widget creation routines often have 
names that are different from the widgets they create. There is no such thing as a McnuBar 
widget. Remember this when you look up a widget's resources in the Motif reference man- 
ual. If you are unsure of the widget class, look on the page for the Motif widget creation 
function first. 
Other Motif widget-creation functions actually create a combination of widgets. More will 
be said about this later. 

Building a Main Window 

With that introduction, we are ready to show you the code needed to implement a standard 
Motif MainWindow and its usual children. Example 3-4 shows a portion of xmainwindow.c, 
the code for implementing the application shown in Figure 3-6. 

*The menubar and the File menu am common features of window-based graphical applications using other widget 
sets and other window systems, including the Macintosh. 
#This is less verbose, less prone to error, and saves one function call. 

More Techniques for Using Widgets 75 



Examp 3- xmawindoc:coderimpmentingsndardMoscreenlayout 
/* 
* xmainwindow.c - main window with help and quit 
*/ 
/* Standard Motif include files: */ 
#include <Xm/Xm.h> 

/* 
* Public header files for widgets used in this file. 

./ 
#include <Xm/MainW.h> 
#include <Xm/RowColumn.h> 
#include <Xm/Frame.h> 
#include <Xm/PushB.h> 
#include <Xm/CascadeB.h> 
#include <Xm/MessageB.h> 

/* MainWindow */ 
/* for MenuBar (actually a RowColumn} */ 
/* Frame (simulated custom widget} */ 
/* PushButton (for menu buttons) */ 
/* CascadeButton (for menubar labels) */ 
/* MessageBox dialog (for help} */ 

/* callback functions defined here */ 
main(argc, argv} 
int argc; 
char **argv; 
XtAppContext app_context; 
Widget topLevel, mainWindow, menuBar, frame; 
Widget fileButton, fileMenu, quit, getHelp, helpBox; 
topLevel = XtVaAppInitialize( 

& app_cont ext, 
"XMainWindow", 
NULL, 0, 
&argc, argv, 
NULL, 
NULL) ; 
/* create main window */ 

/* Application context */ 
/* application class name */ 
/* command line option list */ 
/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

mainWindow = XtVaCreateManagedWidget( 
"mainWindow", /* widget name */ 
xmMainWindowWidgetClass, /* widget class */ 
topLevel, /* parent widget*/ 
NULL); /* terminate varargs list */ 

/* create menubar along top inside of main window */ 
menuBar = XmCreateMenuBar( 
mainWindow, /* parent widget*/ 
"menuBar", /* widget name */ 
NULL, /* no arguments needed */ 
0); /* no arguments needed */ 
XtManageChild(menuBar); 

frame = XtVaCreateManagedWidget( 
"frame", /* widget name */ 
xmFrameWidgetClass, /* widget class */ 
mainWindow, /* parent widget*/ 
NULL); /* terminate varargs list */ 

76 X Toolkit Intrinsics Programming Manual, Motif Edition 



A resource setting is necessary in order to make MainWindow display scrollbars and use 
them to control the custom window. Here is the portion of the XMainWindow app-defaults 
file that applies to the code shown so far: 

! Set initial size of application 
*XmMainWindow.width: 200 
! Frame will be bigger that application, thus requiring scrollbars 
*XmFrame.width: 300 
*XmFrame.height: 300 
! Make MainWindow display scrollbars and use them to 
! pan around in the frame. 
*XmMainWindow.scrollingPolicy: XmAUTOMATIC 

The remaining part of the boilerplate code in a standard Motif application is to build the File 
menu and Help button in the menubar, that you see in xraainwindow. This is described in the 
next section. 

3.4 Using Popups 

A popup is a widget that is displayed on the screen for short periods, instead of being perma- 
nently visible. 
The two most common kinds of popup widgets are menus and dialog boxes. Menus are 
familiar to most people, but dialog boxes are less so. A dialog box is a box on the screen that 
contains a message, or asks for user input, or both. Sometimes a dialog box provides a way 
to get input that is needed only occasionally and therefore doesn't deserve a place in the per- 
manently visible user interface. Fitting into this category is the Motif file selection box, 
which is commonly used as a dialog box. At other times, a dialog box requires immediate 
response by the user before the application can continue. For example, many applications 
that write files are capable of displaying a dialog box that says "Warning: file exists. Do you 
wish to overwrite?" 
A menu becomes visible when the user presses a mouse button while the pointer is in one of 
the CascadeButtons in the menubar. It becomes invisible again once the user has selected an 
item from the menu, released the button outside the menu, or moved into another Cascade- 
Button in the menubar. Dialog boxes usually become visible either because a button such as 
Help was clicked on by the user, or because the program needs occasional user input that is 
best supplied through a temporary window instead of as a permanently visible part of the 
application user interface. Dialog boxes become invisible when the user clicks on the OK or 
Confirm button in the dialog box, or provides the input that the dialog box is requesting. 
Popups are not a kind of widget, but rather a way of using widgets. Any widget can be used 
as a popup. However, some classes of widgets are more commonly used as popups, and 
Motif has simplified the interface by providing routines that not only create these widgets, 
but also prepare them for use as popups. For example, Motif provides xmCreatePopup- 
Menu for creating an empty popup menu. Internally, this routine creates a special parent 
widget called an OverrideShell, and then creates a RowColumn widget inside it, with special 
resource settings. It is then your job to create widgets (or gadgets) to appear in the menu. 

78 X Toolkit Intrinsics Programming Manual, Motif Edition 



A Motif menubar, as described in Section 3.3, usually contains a File menu and a Help button 
that brings up a dialog box. We'll discuss creating the File menu first, and then the Help dia- 
log box. 

3.4.1 

Creating a Basic Menu 

Motif provides three different types of menus: popup, pulldown, and option. Popup menus 
and pulldown menus are popups as we have defined them, but option menus are always visi- 
ble. RadioBox and CheckBox can also be thought of as kinds of menus. The menus that are 
invoked from the menubar are pulldown menus. Figure 3-7 shows xmainwindow with the 
File pulldown menu displayed. The techniques for creating all three types of menus are very 
similar, but we'll reserve discussion of the other types until Chapter 13, Menus, Gadgets, 
and Cascaded Popups. 

 .: 
Figure 3-7. xmainwindow with the File pulldown menu displayed 

Creating a pulldown menu is a four-step process: 
1. Create a CascadeButton as a child of the menubar. This will be the button in which the 
user will click in order to pull down the menu. 
2. Create an empty menu with XrnCreat:ePul.l.dornHenu as a child of the menubar. 
This actually creates a RowColumn with certain resource settings. 
3. Create PushButtons or PushButtonGadgets for each menu item, as children of the pull- 
down menu. 

4. Tell the CascadeButton that just created the ID of the menu, it should pop up. This can't 
be done until step 2 is done. 

More Techniques for Using Widgets 79 



In Motif, the RowColumn widget created by XmCreatePulldownMenu is called a menu 
pane, and the buuons contained by that menu are called menu items. 

This process sets up the popup widget, but does not put it on the screen. Somewhere in your 
code you need to call XtManageChild tO pop up the widget. This is typically done in the 
XmNactivateCallback callback routine of the CascadeButton. Motif takes care of 
popping down the menu at the appropriate times according to its conventions. 

Example 3-5 shows the code needed to add a File menu containing only a quit button to an 
existing menubar. 

Example 3-5. Adding a File menu to an existing menubar 
/* 
* quit button callback function 
*/ 
/ *ARGSUSED* / 
void Quit(w, client_data, call_data} 
Widget w; 
XtPointer client_data, call_data; 
{ 
exit (0 } ; 
} 

main(argo, argv) 
int argc; 
char **argv; 
{ 
Widget fileMenu, fileButton, quit; 

CREATE FILE MENU AND CHILDREN 

/* create the File button in the menubar */ 
fileButton = XtVaCreateManagedWidget( 
"fileButton",/* widget name */ 
xmCascadeButtonWidgetClass, /* widget class */ 
menuBar, /* parent widget*/ 
NULL); /* terminate varargs list */ 

/* create menu (really a Shell widget 
* and RowColumn widget combo) */ 
fileMenu = XmCreatePulldownMenu( 
menuBar, /* parent widget*/ 
"fileMenu", /* widget name */ 
NULL, /* no argument list needed */ 
0); /* no argument list needed */ 
/* Notice that fileMenu is intentionally NOT managed here */ 

/* create button in menu that exits application */ 
quit = XtVaCreateManagedWidget( 
"quit", /* widget name */ 
xmPushButtonWidgetClass, /* widget class */ 
fileMenu, /* parent widget*/ 
NULL); /* terminate varargs list */ 

80 X Toolkit Intrinsics Programming Manual, Motif Edition 



xmainwindow 

-- xmainwindow 

This is help text. 
But, it is only a few words. 
If you really need help,. 
Read the manual. 

Figure 3-8. xmainwindow with the Help dialog box displayed 
Example 3-6 shows the code required to add a Help button and dialog box to xmainwindow. 

82 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 3-7. XMainWindow: setting help text in the app-defaults file 
*helpBox.messageString: This is help text.\n\ 
If you really need help, \n\ 
I'm afraid you'll have to read the manual. 
! The following used if the window manager titles the dialog. 
*helpBox. dialogTit le : Help 
By ending lines with \ you can use a multi-line string as a resource value. 

Popup Window Hierarchy 

You may notice that dialog boxes can extend outside the application. This is because their 
Shell widgets are child windows of the root window, not the top-level window of the applica- 
tion, no matter which widget you supply as parent. By default in Xt, a child of the root is 
positioned at the top-left corner of the screen. However, Motif automatically positions most 
menus and dialog boxes in a suitable location in or over the application before popping them 
up. Dialog boxes or menus that are not triggered by a mouse button press, though, need to be 
positioned by the application. How to do this will be described in Chapter 13, Menus, Gad- 
gets, and Cascaded Popups. 

Figure 3-9 shows the widget instance hierarchy of xmainwindow, and its X window hier- 
archy. Note that the only difference between the two is the parentage of the dialog and menu 
widgets. 

Note that when you create a PulldownMenu, you are actually creating a Shell widget with the 
menu as its child. The same is true of MessageDialog. Each separate window hierarchy has 
a shell widget at the top. 
If you have a popup widget that might never be used, or whose characteristics are not known 
until just before it is popped up, you can create the popup shell and widget just before pop- 
ping it up, in the callback function or action that pops up the widget. This technique makes 
the startup time of the application marginally faster, but slows the pop up time the first time 
the popup is used. 
Popups, and menus in particular, will be described in much more detail in 
Chapter 13, Menus, Gadgets, and Cascaded Popups. 

More Techniques for Using Widgets 85 



Instance hierarchy 

rnainWindow-- MainWindow i 
I 
I I 
MenuBar-- I MenuBar / I Frame 
I 
I I 

--frame 

3.5 

Window hierarchy 

RootWindow i 
helpBox -j 

Figure 3-9. The widget instance and X window hierarchies are different only for popups 

More About Callbacks 

As you may recall, a callback is a function that your application wants called in response to a 
certain occurrence in a certain widget. The application simply declares the callback function 
and then calls XtAddCallback. While Chapter 2, Introduction to the X Toolkit and 
Motif, discussed the concept of callbacks and demonstrated the most common use, it did not 
completely describe all the useful tricks. You can pass application data to callback functions. 
You can arrange for more than one callback function to be called (in a particular order) when 
the callback is triggered, and add and remove functions from this list at will. You can declare 
callbacks statically using a callback list instead of calling XtAddCallback or XtAdd- 
Callbacks. 

86 X Too/k# Intrinsics Programming Manual, Motif Edition 



Most callback functions don't use the event field passed to the callback function either, but 
it is potentially useful, since it contains a lot of data about the user event that triggered the 
callback. If a button press or release triggered the callback, this event structure will be an 
XButtonEvent structure. This structure can be passed to XmMenuPosition to posi- 
tion a menu created with XmCreatePopupMenu, as will be described in 
Chapter 13, Menus, Gadgets, and Cascaded Popups. If the triggering event was a key press 
or release, an XKeyEvent would be passed. In some cases it may be useful to process this 
event to determine which key was pressed. Remember that due to ModUs keyboard inter- 
face, most callback functions can be invoked by either a keyboard or a mouse command. 
When this is the ease, your callback function must be written so that it can handle either type 
of event. 

Other widget sets do not use the call_data argument as heavily as Motif. For example, 
the Athena Widgets rarely use it at all. 

Callback Lists 

You may register any number of callback functions for a single widget callback resource. In 
other words, when a callback is triggered by a user event, all the functions in the current call- 
back list for that callback for that widget instance will be called, one at a time, in the speci- 
fied order. Multiple callback functions are not needed in many applications, but can be use- 
ful if applied creatively. 
Remember that most widgets also have more than one callback list, each triggered by a dif- 
ferent occurrence. What we are talking about here is that you can register a series of func- 
tions to be called in response to one occurrence. 

Let's take an example of how a callback list might be used. Perhaps you have the functions 
A, B, and C, and you need to be able to call them separately in response to events in three dif- 
ferent PushButton widgets, or to call all of them in order in response to events in a fourth 
PushButton widget. This fourth PushButton widget might have a callback list including the 
functions A, B, and C. While the fourth PushButton widget's code can also be implemented 
by creating a function D that calls A, B, and C and then registering D as the callback of the 
fourth PushButton widget, you can't pass a different piece of data into each routine, and you 
can't change the order of the functions called by D. You can do both easily if A, B, and C are 
specified in a callback list. The order in which the callback functions are called can be 
changed by removing them from the list (using XtRemoveCallback or XtRemove- 
Callbacks), and then adding them in a different order. You can also call the same func- 
tion more than once in a callback list. 

NOTE 

Never use XtRemoveAllCallbacks when using the Motif widget set. 
Motif adds its own callback functions to many of the widgets, and it depends on 
these functions to operate properly. 

90 X Toolkit Intrinsics Programming Manual, Motif Edition 



3.6.1 The Application Data Structure 

The structure type that contains all the application variables to be set through resources is 
commonly called AppData. Once this structure type is declared, memory can be allocated 
for a structure called app_data. Example 3-13 shows the code that defines the structure 
type and then allocates memory for the actual structure. 

Examp 3-1 xbitmap: geeing application resources 
typedef struct { 
Pixel copy_fg; 
Pixel copy_bg; 
int pixmap_width in cells; 
int pixmap_height in cells; 
int cell_size_in_pixels; 
Boolean debug; 
} AppData; 

AppData app_data; 

As usual in C, the members of the app._data structure will be referenced throughout the 
application code using the dot format. For example, the value of the debug field of 
app_data will be referenced with app_dat a. debug. 

The Resource List 

The resource list looks complicated, but it is easy to understand and even easier to write 
because it conforms to a consistent pattern. Each field in the application data structure has an 
entry in the resource list. Each resource entry in turn has seven fields, which describe the 
name of the resource, its type and default value, and various other information. 
The resource list controls Xt's value conversion facilities. Since user resources are always 
strings, and application data structure fields can be any type, a conversion may have to take 
place. Xt has built-in converters to convert from string to most common types needed by 
applications. These types are called representation types by Xt, and they are indicated by 
constants starting with XmR in Motif, or XtR in standard Xt. The representation type of a 
string (char *) is XmRString. A Motif compound string is XmRXmString. You con- 
trol the conversion simply by specifying a resource as a certain representation type in the 
resource list. 
It is possible to represent the same value in several different representation types. For 
example, a color may be represented as an ASCH color name such as "blue," as a structure 
containing Red, Green, and Blue values, or as a pixel value (an index into a colormap). Also 
note that a representation type is different from a C-Language type. It is also possible for 
two different representations of something to both use the same C-Language type. For 
example, two hypothetical representation types might be XtRInch and XtRMeter. Both 
represent distances and both would probably be integers or floating point numbers, but each 
would have a different value for the same distance. 

92 X Too&# Intrinsics Programming Manual Motif Edition 



Table 3-3. XrmOptionKind: Command-line Option Style Constants (continued) 

Constant 

XrmoptionStickyArg 

XrmoptionSepArg 

XrmoptionResArg 

XrmoptionSkipNArgs 

XrmoptionSkipArg 

XrmoptionSkipLine 

Meaning 

The value is the characters immediately following the option 
with no white space intervening. This is the style of argu- 
ments for some UNIX utilities such as uucico where -sven- 
ture means to call system venture. 

The next item after the white space after this flag is the value. 
For example, -fg blue would indicate that "blue" is the value 
for the resource specified by -fg. 

The resource name and its value are the next argument in 
a rgv after the white space after this flag. For example, the 
flag might be: 
-res "basecalc*background : white" ; 
then the resource name/value pair would be used as is. This 
form is rarely used because it is equivalent to -xrm, and 
because the C shell requires that special characters such as * 
be quoted. 

Ignore this option and the next N arguments in a rgv, where 
N is the value in the last field of this option table entry. 

Ignore this option and the next argument in a rgv. 

Ignore this option and the rest of argv. 

The options table is passed to XtAppInitiali ze as its third argument, and the number of 
options table entries as the fourth. The XtNumbe r macro is a convenient way to count the 
number of entries (this is only one of many contexts in which you'll see this macro used). 
Note that you cannot override the standard options by providing options with the same names 
in your own parsing table. If you try this, your options with the same names will simply not 
be set to the values specified on the command line. Instead, the standard options will be set 
to these values. This was a design decision in Xt, one of the few cases where a user-interface 
policy is enforced. Uniformity in this basic area was deemed more valuable than flexibility. 
Also note that there is no way to instruct Xt to interpret more than one argument format for 
the same option. For example, you cannot arrange for -size 3 and -size3 both to work. 
XtAppInitialize removes all the arguments it recognizes (including those in your 
options table) from argv and argc. If all goes well, only the application name will remain 
in argv, and argc will equal one. It is important to check whether there is more than one 
argument left after XtAppInitialize has returned. Command-line options that xt- 

102 X Toolkit Intrinsics Programming Manual Motif Edition 



Examp 3-1Z The R4 varas Wace  creating a widget (continue 
XmNlabelString, text, 
NULL); 

The standard varargs list entry is a resource name/value pair. The value must be already con- 
verted into the type required for that resource (documented on the widget's reference page). 
XtVaTypedArg (not Xm . . . ) is a special symbol used just before a resource name, 
which, when encountered, indicates that the next four arguments specify a resource that 
needs to be converted.* In Example 3-17, the value "red" needs to be converted into a pixel 
value, which is the index to the colormap register that contains the correct RGB values to dis- 
play on the screen. The argument XmNbackground is the resource to be set. Xm- 
RString is the type of the value to be converted. The final two arguments are the pointer 
to the value (or the pointer to the pointer to the value if not a string) and the size of the value 
pointed to in bytes. XtVaTypedArg can be used to convert any string that is valid in a 
resource file but is otherwise difficult to set in the source file. But don't use XtVaTyped- 
Arg unnecessarily, since it adds overhead. 
The varargs interfaces will also accept an arglist as one item in the list, using the symbol xt- 
VaNestedList as the resource name. XtVaNestedList allows you to create one 
argument list and pass it to a series of widget creation routines, instead of listing all the same 
resource settings in each widget creation routine. For more details on this, see 
Chapter 10, Resource Management and Type Conversion. 
There is some extra overhead involved in using the varargs interfaces because they massage 
the arguments into an argument list and call XtCreateWidget, XtCreateManaged- 
Widget, XtSetValues, or XtGetValues. However, the added convenience seems 
worth it. Furthermore, the XtVaTypedArg feature is not supported in the ArgList style of 
call (described in the next section). 
Unless you use the XtVaTypedArg feature, no diagnostic is printed when you specify a 
resource value incorrectly in the argument list. Therefore, make sure you specify the 
resource values correctly, and recognize this as a possible place to begin looking for bugs. 
(This is another reason to hardcode resources only when the application is almost ready for 
release. If you do it all at once in a methodical fashion, you are less likely to make mistakes 
than if you are always adding, subla'acting, and changing values in the argument lists.) 

NOTE 

If you use the varargs style of arguments, but forget to type the Va in the func- 
tion name, you can get various types of errors. If you specify resources in the 
call, you will get a core dump at run time, but you can detect the problem with 
lint, which will note the function as having a variable number of arguments. If 

*Note that XtVaTypedrg does not begin with Xm. It is a symbol defined by Xt. 

More Techniques for Using Widgets 105 



Example 3-19. Using an argument list in widget creation 
/* define quit_args */ 

main(argc, argv) 
int argc; 
char *argv[]; 
{ 
Widget quit, box; 

/* create box */ 

3.8.2.1 

quit = XtCreateManagedWidget( 
"quit", /* widget name */ 
xmPushButtonWidgetClass, /* widget class */ 
box, /* parent widget*/ 
quit_args, /* argument list*/ 
XtNumber(quit_args) /* arglist size */ 
); 

Note the use of the XtNumber macro to calculate how many arguments there are in the stat- 
ically initialized argument list. This macro eliminates the need to keep track of the number 
of resources you have set. 

Note also that the value field in the argument list must be in the correct representation type 
for that resource, which is often not a string. You may need to call XtConvertAndStore 
tO arrive at the right representation of the data to be placed in the argument list. For details 
on calling XtConvertAndStore, see Chapter 10, Resource Management and Type Con- 
version. An easier way to do this is to use the XtVaTypedArg feature supported by the 
varargs interfaces. 

As mentioned earlier, unless you invoke a converter, no diagnostic is printed when you spec- 
ify a resource value incorrectly in the argument list. Therefore, make sure you specify these 
correctly. 

Another Way to Set Arguments 

Instead of creating the argument list as a static array, you can allocate storage at run time and 
use the XtSetArg macro to set values into the storage. This is the coding style favored in 
Motif 1.0 applications. 

XtSetArg sets a single argument to a resource identifying a constant and a value. Example 
3-20 shows the code that would create an argument list with the same contents as the one 
created in Example 3-18 above. Some people prefer this technique because it places the 
argument list seUing closer to the XtCreateWidget call, making the code easier to read. 
(However, it is still more difficult to read than when using the varargs interfaces.) 

More Techniques for Using Widgets 107 



AppInitialize instead of XtInitialize and XtAppMainLoop, not XtMain- 
Loop. 
Of the routines you have seen so far in this book, only XtVaAppInitialize, XtApp- 
Initialize, XtAppMainLoop, and XtAppAddActions USe explicit application 
contexts. The complete list of routines that have equivalents is preSented in Section 14.6. 
Throughout this book we will continue to uSe the routines that uSe the explicit application 
context. 

110 X Toolkit Intrinsics Programming Manual, Motif Edition 



4 

An Example Application 

This chapter describes a complete application, in several iterations. First, it 
shows a simple version of the program, a bitmap editor, as it would be written 
assuming the existence of a BitmapEdit widget (which is actually developed 
in Chapter 6, Inside a Widget). Then, two refined versions are developed, 
each demonstrating additional Toolkit programming techniques. Finally, the 
same application is shown as it would be written if the bitmap editor were 
implemented in an application window rather than with the BitmapEdit widget. 

In This Chapter: 

xbitmapl : Bitmap Editor Using a BitmapEdit Widget ......................... 114 
XBitmapl App-defaults File ............................................................ 118 
xbitmap2: Adding Graphics to Display the Bitmap ............................. 119 
Exposure Strategy ......................................................................... 121 
Graphics from the Application ........................................................ 124 
Writing a Bitmap File ...................................................................... 127 
xbitmap3: Another Way to Create a Custom Window ........................ 129 
Actions .......................................................................................... 129 
The Actions Table ........................................................................ 131 
Format of an Action Function ....................................................... 132 
Translations ................................................................................... 133 
The Translation Table ................................................................... 133 
Hardcoding Translations .............................................................. 136 
Action Parameters ....................................................................... 137 
Adding Actions to Existing Widgets ................................................ 137 
xbitmap4: A Bitmap Editor Without a BitmapEdit Widget ................... 138 



4 
An Example Application 

Enough of these trivial programs! Now for an (almost) real application. This chapter 
describes the development of a bitmap editor. Although it is simple, it can be easily extended 
to be quite powerful without any new techniques. 

We will show several versions of xbitmap, beginning with a simple version that assumes the 
existence of a BitmapEdit widget (which will actually be developed in Chapter 6, Inside a 
Widget, and Chapter 7, Basic Widget Methods). Subsequent versions add two widgets that 
display the bitmap in small scale (one normal, one reverse video), and finally implement the 
same application without the use of the specialized BitmapEdit widget. 

These examples will demonstrate the techniques described in Chapter 2, Introduction to the 
X Toolkit and Motif, and Chapter 3, More Techniques for Using Widgets, as they would 
appear in a real application, and will bring up a number of new topics: 

The initial version introduces the bitmap editor application, and demonstrates the way the 
application can access the data within a widget using a public function defined by the 
widget class. 

The second version demonstrates two ways of adding the small-scale bitmaps, one using 
a standard widget and one drawing into a Core widget from the application. This allows 
us to introduce actions and translations, another way to link widgets with application 
code. 

The third version does not use the BitmapEdit widget, but instead implements its features 
by drawing into a Primitive widget. This demonstrates one way to prototype features and 
prepare to write your own widget. It also allows us to describe the code necessary to 
implement the bitmap editor so that you will already understand this code when you see it 
in the internal framework of a widget described in Chapter 6 and Chapter 7. 

Many applications have at least one custom window for which no existing widget will suf- 
fice. This chapter demonstrates that there are several ways to implement such a window, and 
describes the tradeoffs between the different options. Many features can be added from the 
application code by building on a DrawingArea widget, creating a Core or Primitive widget 
to draw into, or by creating a custom widget. By the end of Chapters 6 and 7, you will have 
seen how to implement this application entirely with existing widgets and application code, 
how to implement it using custom widgets, and how to implement a mixture of the two. 

An Example Application 113 



4.1 xbitmapl: Bitmap Editor Using a BitmapEdit Widget 

The screen appearance of xbitmapl is shown in Figure 4-1. As usual, it is a good idea to 
compile and run each example as it is discussed.* 

...... xbitmapl 

File 

Help 

Figure 4-1. xbitmap l : how it looks on the screen 

The BitmapEdit widget lets you set bits in the visible bitmap by clicking the first pointer but- 
ton or dragging the pointer with the first button held down, lets you erase bits using the sec- 
ond button, or lets you toggle bits using the third button. The File menu contains a Print but- 
ton which simply prints on the standard output an array of ones and zeroes representing the 
set and unset bits in the bitmap. (Code to read and write standard X11 bitmap files is added 
in a later version.) The File menu also contains a Quit button. 
xbitmapl is implemented by adding a small amount of code to xmainwindow, described in 
Chapter 3, More Techniques for Using Widgets. We replaced the Frame widget with a 
BitmapEdit widget, and added the Print button to the menu. Of course, a callback for the 
print button also has to be added. 
The code for xbitmapl is shown in Example 4-1. The only new technique shown in this 
example is the use of the public function BitmapEditGetArray defined by the Bitmap- 
Edit widget. BitmapEditGetArray gets a character army which represents the contents 

*How to get and compile the example source code is described in the Preface and Section 2.6.2.2. 

114 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 4-I. xb#map1: comp code (continue 
/*ARGSUSED*/ 
void ShowHelp(w, client_data, call_data) 
Widget w; 
XtPointer client data; 
XtPointer call_data; 
( 
Widget dialog = (Widget) client_data; 
XtManageChild(dialog); 
} 
/, 
* quit button callback function 
*/ 
/*ARGSUSED*/ 
void Quit(w, client_data, call_data) 
Widget w; 
XtPointer client_data, call_data; 
( 
exit (0) ; 
} 
main (argc, argv) 
int argc; 
char **argv; 
( 
XtAppContextapp_context; 
Widget topLevel, mainWindow, menuBar; 
Widget fileButton, fileMenu, quit, getHelp, helpBox; 
Widget temp; 
Widget bigBitmap, output; 
/* never call a Widget variable "exit"! */ 
extern exit(); 
static XrmOptionDescRec table[] = { 
{"-pw", "*pixmapWidthInCells", XrmoptionSepArg, NULL}, 
{ "-pixmapwidth", "*pixmapWidthInCells", XrmoptionSepArg, NULL }, 
{ "-ph", "*pixmapHeightInCells", XrmoptionSepArg, NULL }, 
{"-pixmapheight", "*pixmapHeightInCells", XrmoptionSepArg, NULL}, 
{"-cellsize", "*cellSizeInPixels", XrmoptionSepArg, NULL}, 

}; 

topLevel = XtVaAppInitialize( &app_context, "XBitmapl", 
table, XtNumber(table), &argc, argv, NULL, NULL); 

/* create main window */ 
mainWindow = XtVaCreateManagedWidget( "mainWindow", 
xmMainWindowWidgetClass, topLevel, NULL); 

/* create menu bar along top inside of main window */ 
menuBar = XmCreateMenuBar( mainWindow, "menuBar", 
NULL, 0); 
XtManageChild(menuBar); 

bigBitmap = XtVaCreateManagedWidget("bigBitmap", 
bitmapEditWidgetClass, mainWindow, 
NULL); 

/* Set MainWindow areas and add tab groups */ 

116 X Toolkit Intrinsics Programming Manual, Motif Edition 



 Examp 4-1. xbmap l : comp code (continue 
XmMainWindowSetAreas (mainWindow, menuBar, NULL, NULL, NULL, 
bigBitmap}; 
/* 
* CREATE FILE MENU AND CHILDREN 
*/ 
/* create button that will pop up the menu */ 
fileButton = XtVaCreateManagedWidget("fileButton", 
xmCascadeButtonWidgetClass, menuBar, NULL}; 
/* create menu (really Shell widget-RowColumn widget combo} */ 
fileMenu = XmCreatePulldownMenu( menuBar, 
"fileMenu", NULL, 0}; 
/* create the quit button up in the menu */ 
quit = XtVaCreateManagedWidget( "quit", 
xmPushButtonWidgetClass, fileMenu, NULL}; 
/* 
* Specify which menu fileButton will pop up. 
*/ 
XtVaSetValues(fileButton, 
XmNsubMenuId, fileMenu, 
NULL}; 
/* arrange for quit button to call function that exits. */ 
XtAddCallback(quit, XmNactivateCallback, Quit, 0}; 
/* 
* CREATE BUTTON TO OUTPUT BITMAP 
*/ 
/* create button that will pop up the menu */ 
output = XtVaCreateManagedWidget( "output", 
xmPushButtonGadgetClass, fileMenu, NULL); 
XtAddCallback(output, XmNactivateCallback, PrintOut, bigBitmap}; 
/* 
* CREATE HELP BUTTON AND BOX 
*/ 
/* create button that will bring up help popup */ 
getHelp = XtVaCreateManagedWidget( "getHelp", 
xmCascadeButtonWidgetClass, menuBar, NULL); 
/* tell menuBar which is the help button 
* (will be specially positioned. */ 
XtVaSetValues(menuBar, 
XmNmenuHelpWidget, getHelp, 
NULL}; 
/* create popup that will contain help */ 
helpBox = XmCreateMessageDialog( getHelp, 
"helpBox", NULL, 0}; 
temp = XmMessageBoxGetChild (helpBox, XmDIALOG_CANCEL_BUTTON}; 
XtUnmanageChild (temp}; 
temp = XmMessageBoxGetChild (helpBox, XmDIALOG_HELP_BUTTON); 
.. XtUnmanageChild (temp); 

An Example Application 117 



Figure 4-2. xbitmap2: true-scale normal and reverse bitmaps added 

Another way to display the small pixmaps is to use a DrawingArea widget, which is an empty 
widget that provides callbacks in which you can place drawing code. DrawingArea is useful 
for building simple custom windows that don't have complicated graphics or user input. This 
technique is implemented in xbitmap2. 
The third possibility is to draw nto a Core or Primitive widget. This would use code very 
similar to that in xbitmap2, but would link the application code with the widget using actions 
and translations instead of with callbacks. We will be demonstrating this technique in 
xbitmap3 as an introduction to translations and actions. 

120 X Toolkit Intrinsics Programming Manual, Motif Edition 



4.2.1 Exposure Strategy 

The redrawing technique used in xbitmap2 works as follows. Two pixmaps (off-screen draw- 
able areas) are created to record the current state of each bitmap. Whenever a cell is toggled, 
a pixel in each pixmap is changed by drawing into each pixmap. Then each entire pixmap is 
copied into the corresponding widget. The same routine that copies from pixmap to widget is 
used whenever the widgets become exposed. Figure 4-3 illustrates this technique. 

Application draws to 
pxmap only... 

...then copies 
pixrnap to 
widget window 

Figure 4-3. Application draws into Pixmap and copies it to widget window 

In the actual code, two single-plane pixmaps are created during application startup, the same 
size as the bitmap displayed in the BitmapEdit widget. Each of the two bitmap display areas 
is implemented with a DrawingArea widget. DrawingArea provides a callback resource 
called XmNexposeCallback. The application calls XtAddCallback to register a 
function with each of the two widgets for the XmNexposeCallback resource. This func- 
tion, called RedrawSmallPicture, copies from the pixmaps into the widget's window. 
This function takes care of redrawing the widgets whenever exposure occurs, and it also can 
be called whenever a cell is toggled. The BitmapEdit widget has an XtNtoggle- 
Callback resource. The function registered for this widget and resource draws into the 
two pixmaps, and then calls RedrawSmallPicture to copy the updated pixmap infor- 
mation to the window (alternately, it could draw directly into window instead of copying 
from the pixmap). 
Three new routines are needed: RedrawSmallPicture, SetUpThings, and Cell- 
Toggled. These three routines are primarily composed of Xlib calls that set up for and per- 
form graphics. The RedrawSmallPicture routine copies a pixmap into a widget, Set- 
UpThings creates the pixmaps and the GCs (introduced in the next subsection, 4.2.2) 
needed to draw into these pixmaps, and CellToggled is a callback function registered 
with the BitmapEdit widget that updates the pixmaps whenever a cell is toggled. Code is 
also added to main to create the two DrawingArea widgets and register RedrawSmall- 
Picture with them. We'll show these routines one at a time. Example 4-3 shows the 
improvements to the main routine. 

An Example Application 121 



.... !: Example 4-3. xbitmap2: implementing small pixmaps with DrawingArea widgets (continued) 
framel = XtVaCreateManagedWidget ( "frameNormal', 
xmFrameWidgetClas s, smallPixmapBox, 
NULL} ; 
/* create DrawingArea for small pixmap widget - must set size. */ 
..: bitmap_stuff, showNormalBitmap - XtVaCreateManagedWidget ( 
"showNormalBitmap", xmDrawingAreaWidgetClass, framel, 
XmNwidth, bitmap_stuff, pixmap_width_in_cell s, 
XmNheight, bitmap_stuff, pixmap_height_in_cel i s, 
NULL) ; 
/* create Frame so small pixmap widget appears in box */ 
frame2 = XtVaCreateManagedWidget ( "frameReverse', 
xmFrameWidgetClass, smallPixmapBox, 
NULL) ; 
/* create DrawingArea for small pixmap widget - must set size. */ 
bitmap_stuff, showReverseBitmap = XtVaCreateManagedWidget ( 
"showReverseBitmap", xmDrawingAreaWidgetClass, frame2, 
XmNwidth, bitmap_stuff.pixmap_width in cells, 
XmNheight, bitmap_stuff, pixmap_height_in_cell s, 
NULL) ; 
/* register RedrawSmallPicture as the redrawing function */ 
XtAddCallback (bitmap_stuff. showNormalBitmap, XmNexposeCallback, 
RedrawSmallPicture, 0) ; 
XtAddCallback (bitmap_stuff. showReverseBitmap, XmNexposeCallback, 
RedrawSmallPicture, 0) ; 
/* Register CellToggled to be called whenever a cell is toggled. */ 
XtAddCallback(bigBitmap, XtNtoggleCallback, CellToggled, 0); 
XtReali zeWidget (topLevel) ; 
XtAppMainLoop (app_context) ; 
} 
Thc main routinc rcgistcrs RedrawSmallPicture as thc XmNexposeCallback 
function for each DrawingArea widget. It also registers CellToggled as the Xt- 
NtoggleCallback for the BinapEdit widget, to be called whenever a bitmap cell is 
toggled. 
SetUpThings uses Xlib calls to create the pixmap that will be used as an off-screen copy 
of what will be displayed in the DrawingArea widgets. SetUpThings also creates GCs 
that will be used to draw into these pixmaps. CellToggled does the drawing, and 
RedrawSmallPicture performs the copying. These routines are shown in the next sec- 
tion, which describes how graphics work in Xt programs. 

An Example Application 123 



Fortunately, as long as your widget or application requires only a small number of colors, and 
you do not particularly care whether the colors you get are exactly the colors you requested, 
Xt provides a simplified interface. It hides the actual Xlib calls involved in the Resource 
Manager's converter routines. As described in Chapter 3, More Techniques for Using 
Widgets, if you specify application resources for colors in a resource list, Xt will automati- 
cally convert color names specified as resource settings into pixel values. If you need to do 
more advanced color handling, then you will need to make Xlib calls yourself. For a descrip- 
tion of Xlib's color handling, see Chapter 7, Color, in Volume One, Xlib Programming Man- 
ual. 
xbitmapl works either in color or monochrome, since the widgets it creates can have their 
color set by resources. All of xbitmap2 except the small pixmaps we have been implement- 
ing also support color. To support color in the small pixmaps takes more work. We would 
need to add application resources to get the pixel values that will be set into the GCs used 
when drawing, as described in Section 3.6. 
Example 4-5 shows the CellToggled routine. As you may recall, this routine is a call- 
back function registered with the BitmapEdit widget, to be called whenever a cell is toggled. 

Example 4-5. xbitmap2: the CellToggled routine 
/* ARGSUSED */ 
static void 
CellToggled (w, client_data, call_data) 
Widget w; 
XtPointer client data; /* unused */ 
XtPointer call data; /* will be cast to cur info */ 
{ 
/* cast pointer to needed type: */ 
BitmapEditPointInfo *cur info = (BitmapEditPointInfo *) call data; 
/* 
* Note, BitmapEditPointInfo is defined in BitmapEdit.h 
*/ 
XDrawPoint (XtDisplay (w) , bitmap_stuff, normal_bitmap, 
((cur_info->mode == DRAWN) ? bitmap_stuff.draw_gc : 
bitmap_stuff.undraw_gc) , cur_info->newx, cur_info->newy) ; 
XDrawPoint (XtDisplay (w) , bitmap_stuff, reverse_bitmap, 
((cur_info->mode == DRAWN) ? bitmap_stuff.undraw_gc : 
bitmap_stuff.draw_gc), cur_info->newx, cur_info->newy); 
RedrawSma 1 IP i ctu re (bit map_stu f f. showNo rma iBit map, 
cur_info->newx, cur_info->newy) ; 
RedrawSmallPicture (bitmap_stuff. showReverseBitmap, 
cur_info->newx, cur_info->newy) ; 
} 
Note Hint BinapEdit passes a sucture called BitmapEditPoint Info into the callback 
function as an argument. This structure is defined in the public include file, BitmapEdit.h, 
and it provides the information necessary to keep the small bitmaps displaying the same pat- 
tern as BitmapEdit. The fields of BitmapEditPointTnfo are the mode (whether drawn 
or undrawn) and the coordinates of the point toggled. The CellToggled routine draws 
points into the pixmaps according to the information passed in, and then calls Redraw- 
SmallPicture to copy the pixmaps into each Core widget. 

126 X Toolkit Intrinsics Programming Manual Motif Edition 



The first line of CellToggled casts the generic pointer info into the structure type 
defined by BitmapEdit, BitmapEditPointInfo. Under most compilers this can also be 
done (perhaps more dearly) by declaring the info argument as type BitmapEditPoint- 
Info in the first place. However, ANSI C compilers require a cast. 

The RedrawSmallPicture routine is shown in Example 4-6. 

Example 4-6. xbitmap2: the RedrawSmallPicture routine 
/*ARGSUSED* / 
static void 
RedrawSmallPicture(w, client_data, call_data) 
Widget w; 
XtPointer client_data; 
XtPointer call_data; 
{ 
Pixmap pixmap; 
if (w == bitmap_stuff, showNormalBitmap) 
pixmap = bitmap_stuff.normal_bitmap; 
else 
pixmap = bitmap_stuff, reverse_bitmap; 
if (DefaultDepthOfScreen (XtScreen (w)) == 1) 
XCopyArea (XtDisplay (w} , pixmap, XtWindow (w) , 
DefaultGCOfScreen (XtScreen (w} } , 0, 0, 
bitmap_stuff.pixmap_width in cells, 
bitmap_stuff.pixmap_height in cells, 
0, 0); 
else 
XCopyPlane (XtDisplay (w) , pixmap, XtWindow (w) , 
DefaultGCOfScreen (XtScreen (w)) , 0, 0, 
bitmap_stu f f. pixmap_widt h_in_ce i i s, 
bitmap_stuff.pixmap_height in cells, 
0, 0, I); 
} 
RedrawSmallPicture is called from CellToggled, and also by XI in response to 
Expose events because we registered it as a callback for the DrawingArea widgets. The 
use of one of two Xlib routines, depending on the depth of the screen, is an optimization. 
XCopyArea is faster, but can be used for this job only on monochrome displays, because 
the pixmaps used here are one plane deep on all displays and must be translated into multiple 
planes with XCopyPlane on color displays. 
See Volume One, Xlib Programming Manual, for details. 

Writing a Bitmap File 

Once we have pixmaps in our application that contain the current bitmap, it is a trivial matter 
to change the printout callback function to write a bitmap file instead of just printing an 
array of ones and zeroes to the standard output. This is easy because there is an Xlib func- 
tion, XWriteBitmapFile, that writes the contents of a single-plane pixmap into a file. 
Example 4-7 shows the code that gets a filename from the command line and then writes the 
bitmap file. 

An Example Application 127 



4.3 xbitmap3: Another Way to Create a Custom Window 

The small bitmaps added in the last section provided a simple example of making a custom 
window by creating a DrawingArea widget and drawing into it from the application. 
DrawingArea also provides a callback for keyboard and pointer (mouse) input, so that you 
can implement simple user response from the application. However, you will quickly find 
that to implement a more complicated custom window you need a lot more control than 
DrawingArea gives you. 

The two other ways to implement a custom window are to add features to an empty widget 
such as Core or Primitive using actions and translations, or to write your own widget. Until 
you have experience working with widget code, it's easier to prototype the custom window 
for your application by adding to a Primitive widget from the application code. Once this 
code is working, and you have read Chapter 6, Inside a Widget, and Chapter 7, Basic 
Widget Methods, you can easily move the code into a widget when you want to package it or 
take advantage of any of the features of Xt that are inaccessible from the application. The 
code for the BitmapEdit widget was originally written as an application (in xbitmap3), and 
later moved into a widget. 

In the next section we describe xbitmap3, which works just like xbitmapl without using the 
BitmapEdit widget. 

4.3.1 Actions 

So far in the book we have used callbacks to link widgets with application code. When you 
are implementing a custom window, callbacks are useless because they are defined by each 
widget class, and none of the existing widget classes has the callbacks or features that you 
need. 
Therefore, you need to use a different technique for linking application code with widget 
code: the combination of actions and translations. You can use actions to add features to a 
Primitive or Core widget. (Actions are also used inside widget code to implement widget 
features.) 
In xbitmap3 we will make the RedrawSmallPicture function into an action function 
instead of a callback function (this means just giving it different arguments). Then we need 
to arrange for Xt to call RedrawSmallPicture whenever one of the Primitive widgets 
becomes exposed. The general procedure for arranging this is the same as in xbitmap2--you 
register the function during the setup phase of the application, and then Xt will call it in 
response to Expose events. Registering an action, though, is quite different from register- 
ing a callback. 
To register the action, you first declare an actions table, which maps action name strings to 
action function pointers. Then you must register the actions table with Xt by calling Xt- 
AppAddActions. Finally you create a translation table and store it in the app-defaults file 
or hardcode it in the application. A translation table is a widget resource which contains a 
mapping between events or event sequences and action names. Figure 4-4 shows a 
translation table and an action table, and shows how each is used in the process of mapping 

An Example Application 129 



4.3.1.2 

context, and therefore usable by any widget instance of any class in the application. Which 
widgets they are actually used with is defined by the translation table, as described below. 
The names of widget class actions and application actions do not conflict. For example, if an 
application were to define an action called Move, and some widget class in Motif already has 
an action by that name, the two actions would not conflict with each other. 
When you map the action to events in a particular widget (using a translation table), the same 
is true, with a slight caveat. If you write an action called Move, and the widget you install it 
on already has a Move action, your version will be ignored. This implies that you are trying 
to replace a widget action with your own, and this is not allowed. You have to write a 
subclass of the widget to replace a widget action. 

Format of an Action Function 

An action function is just a pointer to a function with four arguments: a widget, an event, a 
string containing any arguments specified for the action in the translation table (described in 
Section 4.3.2.3), and the number of arguments contained in the string. Example 4-9 shows 
the action version of RedrawSmallPicture. 

Example 4-9. An XtActionProc with widget and event arguments 
/* ARGSUSED */ 
static void 
RedrawSmallPicture(w, event, params, num_params) 
Widget w; 
XExposeEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
Pixmap pixmap; 
if (w == bitmap_stuff, showNormalBitmap) 
pixmap = bitmap_stuff.normal_bitmap; 
else 
pixmap = bitmap_stuff, reverse_bitmap; 
if (DefaultDepthOfScreen (XtScreen (w)) == I) 
XCopyArea (XtDisplay (w) , pixmap, XtWindow (w) , 
DefaultGCOfScreen (XtScreen (w)) , event->x, event->y, 
event->width, event->height, event->x, event->y) ; 
else 
XCopyPlane (XtDisplay (w) , pixmap, XtWindow (w) , 
DefaultGCOfScreen (XtScreen (w)) , event->x, event->y, 
event->width, event->height, event->x, event->y, I) ; 
} 
Compare this version of RedrawSmallPicture to the callback version in Example 4-8. 
Action functions are directly passed the event structure that describes the event that triggered 
the action, in this case an XExposeEvent structure. This structure contains the position 
and dimensions of the area that was exposed. This version of RedrawSmallPicture 
copies only the necessary parts of the pixmap to refresh the areas that are exposed. 

132 X Toolkit intrinsics Programming Manual, Motif Edition 



The callback version shown in Example 4-8 copies the entire pixmap to the widget regardless 
of which part of the widget was exposed. This is slightly inefficient but the difference is not 
noticeable when the pixmap is small. Under Motif, but not Athena, callback functions are 
passed the event structure as part of a larger structure, which is passed as the ca22 data 
-- 
argument (for example XmAnyCa].].backSt:ruct:). Therefore, you have access to the 
event structure from within both callbacks and actions. 
However, be aware that if you are allowing user configuration of the translation table (which 
is discussed below), an action may be called with different kinds of events. You should at 
least check the event type in the action routine and print an appropriate message if the user 
has arranged to call the action with the wrong type of event. We'll show how to do this in 
Chapter 8, Events, Translations, and Accelerators. 
Note that for true ANSI C portability, all four arguments to the action function must be 
declared, even though many compilers allow you to leave off trailing arguments that are not 
referenced in the function. If some of the arguments are not used, you should be sure to 
include the lint comment/* ARGSrJSED */. 
One difference between action functions and callback functions is that, unlike callbacks, 
there is no argument provided for passing in application data. You can only pass application 
data into an action function through global variables. 

Translations 

Once you have an action table registered, those actions are ready to be used by any widget in 
the application. But which widgets will they be used in, and which will trigger them? 
Translations determine these things. 
You need to set a translation table resource, XmNt:rans].at:i.ons, on any widget you want 
to be able to call an application action. In the case ofxbitmap3, we want redrawSrna].].- 
Pict:ure to be called when lxpose events occur in the widgets that are displaying the 
small pixmaps. This means that we need to set the XmNt:ranalat:iona resource on those 
two widgets, and the value of the resource should be a translation that maps an Expose 
event into a RedrawSmallPicture call. 

4.3.2.1 

The Translation Table 

Every widget that contains actions also has a default translation table that maps event 
combinations into those actions. The application can override, augment, or replace this table 
to make a widget call application-registered actions in addition to the widget's own actions. 
Registering actions with XtAppAddActions makes them eligible for inclusion in 
translation tables. 

Each line of a translation table maps a sequence of events to a sequence of actions. The 
entire translation table is simply a string consisting of one or more event specifications in 
angle brackets, with optional modifiers, followed by a colon and a function name string 
defined in an action table. Multiple translations can be specified as part of the same string. 

An Example Application 133 



cult is that your code may interact with the widget's code in unpleasant ways. When the 
changes are major, it makes more sense to create a new widget subclass that shares some 
characteristics and code with its superclass. As we will see, that is exactly how PushButton 
is implemented, as a subclass of Label. The Primitive and DrawingArea widgets, on the oth- 
er hand, have no input or output semantics at all, and therefore it is simpler to add actions to 
them without conflict. 

4.4 xbitmap4: A Bitmap Editor Without a BitmapEdit Widget 

The xbitmap4 implements an application almost identical to xbitmapl, but without using the 
BitmapEdit widget. The custom bitmap editing window is done in a Primitive widget, with 
all the code in the application. This is an example of a custom window that could not be eas- 
ily built using DrawingArea. This application is a culmination of everything you have seen 
so far. It is also a preview of what you will see in the next chapter. The same code in 
xbitmap4 that is used to implement the bitmap editor will be moved into widget code in 
Chapters 6 and 7. 
This example takes advantage of application resources to set the configurable parameters of 
the bitmap code. The code that sets up the application resources is described in Section 3.6. 
When moving the code into a widget framework, the same resource list will be used verba- 
tim. The example also provides command-line options to set the important parameters of the 
bitmap code. The code for processing these options is described in Section 3.7. The code is 
the same whether used for setting application resources or widget resources, except no call 
equivalent to XtGetApplicationResources is necessary in a widget. 
The exposure strategy used for the bitmap editor is the same as for the small bitmaps in the 
previous section. The application creates a large pixmap of depth one that stores the current 
image of the bitmap being edited. Whenever the screen needs updating, the applicable part 
of the pixmap is copied to the Core widget in the Redraw_picture routine. Because this 
pixmap is much bigger than the ones in the last section, it is an important optimization that 
only the required parts of the pixmap are copied. (This is not the only possible exposure 
strategy. This particular strategy has very low network load, but uses a relatively large 
amount of server memory. For this reason it is not ideal for PC servers.) 
The SetUpThlngs routine creates the pixmap, draws a grid into it that will persist for the 
life of the application, and creates three GCs. One GC is for copying from the pixmap to the 
window, and two are for drawing and undrawing cells in the pixmap. The btn_event rou- 
tine draws and undraws cells in the pixmap according to pointer clicks and drags, and calls 
Redraw_pi ct u re to update the Core widget display. 
Redraw_picture is called both from the application and from Xt. This is a common 
trick used to reduce the duplication of drawing code. Since Redraw_picture is an ac- 
tion, it has an event argument that is used by Xt to pass in the Expose event describing the 
area exposed. This application also uses this argument by constructing a fake event to pass in 
information about which part of the widget to draw. 

138 X Toolkit Intrinsics Programming Manual, Motif Edition 



The application adds actions and sets the XmNt ranslations resource of the Core widget 
so that Xt calls the application routine Redraw_picture whenever Expose events ar- 
rive, and calls btn event when ButtonPress or MotionNotify events arrive. 

Example 4-15 shows the complete code for xbitmap4. You have seen all the techniques here 
in various examples before. You should work through the code and make sure you under- 
stand the purpose of each section. However, don't worry about the details of the Xlib calls, 
since they are specific to this application. 

i!!!!ii:  Example 4-15. xbitmap4: implementing the bitmap editor from the application 
::!:3:.-!: 
i:::::::.:: * xbitmap4, c 
............. 
.............. 
!::i::::,..i #include <Xm/Xm.h> 
..........: 
::::::::-.::: 
iiiiiii!ili #include <Xm/PanedW. h> 
iiiii !!i #include <Xm/RowColumn .h> 
...... ..... 
%ii #include <Xm/PushB. h> 
::::..-i-:;::. 
ii I /* we use XmPrimitive, but no header file needed (in Xm.h) */ 
i-.-i.:i,; #include <stdio.h> 
i:ii:?:i /* The following could be placed in an "xbitmap.h" file. */ 
i!i#i #define XtNdebug "debug" 
ii " #define XtCDebug "Debug" 
.:- 
#define XtNpixmapWidthInCells "pixmapWidthInCells" 
#define XtCPixmapWidthInCells "PixmapWidthInCells" 
#define XtNpixmapHeightInCells "pixmapHeightInCells" 
iii  #define XtCPixmapHeightInCells "PixmapHeightInCells" 
#define XtNcellSizeInPixels "cellSizeInPixels" 
#define XtCCellSizeInPixels "CellSizeInPixels" 
.z.: #define DRAWN 1 
::::: 
i!iiii!i!il #define UNDRAWN 0 
:::iiiiiii .... #define DRAW 1 
iiii':-i;.-i #define UNDRAW 0 
iiii::i!ii #define MAXr.INES 1000 
-" #define MINBITMAPWIDTH 2 
,.:..: :: #define MAXBITMAPWIDTH 1000 
:: .-'..-.-i #define MINBITMAPHEIGHT 2 
:::-:::: 
:  #define MAXBITMAPHEIGHT 1000 
:;ii!iii::i #define MINCELLSIZE 4 
:-;.-::ii::".- .... #define MAXCELLSIZE 100 
ii!!ii-.ili #define SCROLLBARWIDTH 15 
-."i  /. 
-:-:- * Data structure for private data. 
}!i!ili!ii : (This avoids lots of global variables.) 
!:.iii ! typedef struct { 
iiiiii Pixmap big_picture; 
!iiiiiiii GC draw_gc, undraw_gc; /* for drawing into the 
-.2:-'.- * big_picture, 1-bit deep */ 
..-.1-. GC copy_gc; /* for copying from pixmap 
-'..>:!i * into window, screen depth */ 
Widget bitmap; /* this is the drawing surface */ 

An Example Application 139 



Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 
char *cell; /* this is the array for printing output 
* and keeping track of cells drawn */ 
int cur_x, cur_y; 
Dimension pixmap_width_in_pixels, pixmap_height_in_pixels; 
] PrivateAppData; 
/* data structure for application resources */ 
typedef struct { 
Pixel copy_fg; 
Pixel copy_bg; 
int pixmap_width in cells; 
int pixmap_height in cells; 
int cell_size_in_pixel s; 
Boolean debug; 
} AppData; 
AppData app_data; 
PrivateAppData private_app_data; 
/* resource list */ 
static XtResource resources [] = { 
{ 
XmNforeground, 
XmCForeground, 
XmRP ixel, 
sizeof (Pixel} , 
XtOffsetOf (AppData, copy_fg} , 
XmRSt ring, 
XtDefaultForeground 
}, 
{ 
XmNbackground, 
XmCBackground, 
XmRPixel, 
sizeof (Pixel} , 
XtOffsetOf (AppData, copy_bg} , 
XmRSt ring, 
XtDefaultBackground 
}, 
{ 
XtNpixmapWidt hInCe 11 s, 
XtCPixmapWidthInCel i s, 
XmRInt, 
sizeof (int} , 
XtOffsetOf(AppData, pixmap_width in cells}, 
XmRImmediate, 
(XtPointer} 32, 
}, 
{ 
XtNpixmapHeight InCell s, 
XtCP ixmapHeight InCell s, 
XmRInt, 
sizeof (int} , 
XtOffsetOf(AppData, pixmap_height in cells}, 
XmRImmediate, 
(XtPointer} 32, 
}, 

140 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 
{ XtNcellSizelnPixels, 

.::.:..<::. 

}, 

}, 

XtCCellSizeInPixels, 
XmRInt, 
sizeof (int) , 
XtOffsetOf (AppData, cell_size in pixels) , 
XmRImmediate, 
(XtPointer} 30, 

XtNdebug, 
XtCDebug, 
XmRBoolean, 
sizeof(Boolean), 
XtOffsetOf(AppData, debug), 
XmRImmediate, 
(XtPointer) False, 

}; 

/* Command-line options table */ 
static XrmOptionDescRec options[] = { 
{"-pw", "*pixmapWidthInCells", XrmoptionSepArg, NULL}, 
{"-pixmapwidth", "*pixmapWidthInCells", XrmoptionSepArg, NULL}, 
{"-ph", "*pixmapHeightInCells", XrmoptionSepArg, NULL}, 
{"-pixmapheight", "*pixmapHeightInCells", XrmoptionSepArg, NULL}, 
{"-cellsize", "*cellSizeInPixels", XrmoptionSepArg, NULL}, 
{"-fg", "*foreground", XrmoptionSepArg, NULL}, 
{"-foreground", "*foreground", XrmoptionSepArg, NULL}, 
{"-debug", " *debug", XrmoptionNoArg, "True"}, 

}; 

/* callback function to print cell array to stdout */ 
/* ARGSUSED */ 
static void 
PrintOut(w, event, params, num_params} 
Widget w; 
XEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
/. 
* The absense of the small pixmaps in this version makes it 
* more difficult to call XWriteBitmapFile. Therefore, we will 
* stick with the printed output for this version. 
*/ 
int x, y; 
putchar('\n'}; 
for (y = 0; y < app_data.pixmap_height_in_cells; y++} { 
for (x = 0; x < app_data.pixmap_width in cells; x++} 
putchar(private_app_data.cell[x + y * 
app_data.pixmap_width_in_cells] ? '1' : '0'); 
putchar('\n'}; 
} 
putchar('\n'}; 

An Example Application 141 



Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 
static void RedrawPicture () , DrawCell (), UndrawCell (), ToggleCell () , 
DrawPixmaps () ; 
static void Syntax(argc, argv) 
int argc; 
char * argv[]; 
{ 
int i; 
static int errs = False; 
/* first argument is program name - skip that */ 
for (i -- I; i < argc; i++) { 
if (!errs++) /* do first time through */ 
fprintf (stderr, "xbitmap4 : command line\ 
option not understood: \n") ; 
fprintf(stderr, "option: %s\n", argv[i]); 
} 
fprintf(stderr, "xbitmap understands all standard Xt\ 
command line options. \n") ; 
fprintf(stderr, "Additional options are as follows:\n"); 
fprintf (stderr, "Option Valid Range\n") ; 
fprintf (stderr, "-pw MINBITMAPWIDTH to\ 
MAXBITMAPWIDTH\n" ) ; 
fprintf (stderr, "-pixmapwidth 
MAXBITMAPWIDTH\n" ) ; 
fprintf (stderr, "-ph 
MAXBITMAPHEIGHT\n" ) ; 
fprintf (stderr, "-pixmapheight 
MAXBITMAPHEIGHT\n" ) ; 
fprintf (stderr, "-cellsize 
MAXCELLS I ZE \n" ) ; 
fprintf (stderr, "-fg 
fprintf (stderr, "-foreground 
fprintf (stderr, "-debug 

main (argc, argv) 
int argc; 
char *argv[]; 
{ 

MINBITMAPWIDTH to\ 
MINBITMAPHEIGHT to\ 
MINBITMAPHEIGHT to\ 
MINCELLSIZE to\ 
color name\n"); 
color name\n"); 
no value necessary\n"); 

XtAppContext app_context; 
Widget topLevel, vpane, buttonbox, quit, output; 
extern exit(); 
/* translation table for bitmap core widget */ 

String trans = 
"<Expose>: RedrawPicture() 
<BtnlDown>: DrawCell() 
<Btn2Down>: UndrawCell() 
<Btn3Down>: ToggleCell() 
<BtnlMotion>: DrawCell() 
<Btn2Motion>: UndrawCell() 
<Btn3Motion>: ToggleCell()"; 

\n\ 
\n\ 
\n\ 
\n\ 
\n\ 
\n\ 

static XtActionsRec window actions[] 
{"RedrawPicture", RedrawPicture}, 
{"DrawCell", DrawCell}, 

142 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 4-1 xbmap4: impmenting e bmap editor from e application ontinue 
{"UndrawCell", UndrawCell}, 
{"ToggleCell", ToggleCe11}, 
}; 
topLevel = XtVaAppInitialize( 
&app_context, /* Application context */ 
"XBitmap4", 
options, XtNumber(options}, 
&argc, argv, /* command line args */ 
NULL, /* for missing app-defaults file */ 
NULL}; /* terminate varargs list */ 
/* XtInitialize leaves program name in args */ 
if (argc > I} 
Syntax(argc, argv}; 
XtGetApplicationResources(topLevel, 
&app_data, 
resources, 
XtNumber(resources}, 
NULL, 
0); 
/* 
* We must check the application resource values here. 
* Otherwise, user could supply out of range values and crash 
* program. Conversion routines do this automatically, so 
* colors are already checked. 
*/ 
if ((app_data.pixmap_width in cells > MAXBITMAPWIDTH) 
(app_data.pixmap_width in cells < MINBITMAPWIDTH) 
(app_data.pixmap_height in cells > MAXBITMAPWIDTH) 
(app_data.pixmap_height in cells < MINBITMAPWIDTH)) { 
fprintf(stderr, "xbitmap: error in resource settings:\ 
dimension must be between %d and %d cells\n", 
MINBITMAPWIDTH, MAXBITMAPWIDTH}; 
exit(l}; 
} 
if ((app_data.cell_size_in_pixels < MINCELLSIZE} 
(app_data.cell_size in pixels > MAXCELLSIZE)) { 
fprintf(stderr, "xbitmap: error in resource settings:\ 
cell size must be between %d and %d pixels\n", 
MINCELLSIZE, MAXCELLSIZE}; 
exit(l}; 
} 
/* begin application code */ 
set_up_things(topLevel}; 
private_app_data.cell = XtCalloc(app_data.pixmap_width in cells * 
app_data.pixmap_height in cells, sizeof(char}}; 
if (app_data.debug} 
fprintf(stderr, "xbitmap: pixmap dimensions are %d by %d\n", 
app_data.pixmap_width_in_cells, 
app_data.pixmap_height in cells}; 
vpane = XtVaCreateManagedWidget("vpane", xmPanedWindowWidgetClass, _ 
topLevel, XmNwidth, - 

An Example Application 143 



!:;ii Examp 4-1 xb#map4: impmenting e b#map editor from e applation ontinue 
. 
private_app_data.pixmap_width_in_pixels, NULL); 
buttonbox = XtVaCreateManagedWidget("buttonbox", 
-: xmRowColumnWidgetClass, vpane, NULL); 
: output = XtVaCreateManagedWidget("output", xmPushButtonWidgetClass, 
buttonbox, NULL); 
XtAddCallback(output, XmNactivateCallback, PrintOut, NULL); 
quit = XtVaCreateManagedWidget("quit", xmPushButtonWidgetClass, 
buttonbox, NULL); 
XtAddCallback(quit, XmNactivateCallback, exit, NULL); 
/* note: no header file needed to create xmPrimitive */ 
private_app_data.bitmap = XtVaCreateManagedWidget("bitmap", 
xmPrimitiveWidgetClass, vpane, 
XmNtranslations, XtParseTranslationTable(trans}, 
XmNwidth, private_app_data.pixmap_width_in_pixels, 
XmNheight, private_app_data.pixmap_height_in_pixels, 
NULL); 
XtAppAddActions(app_context, window_actions, 
XtNumber(window_actions}}; 
XtRealizeWidget(topLevel}; 
XtAppMainLoop (app_context) ; 
} 
set_up_things (w} 
Widget w; 
{ 
XGCValues values; 
int x, y; 
XSegment segment[MAXLINES]; 
int n_horiz_segments, n_vert_segments; 
private_app_data.pixmap_width in pixels = 
app_data.pixmap_width in cells * 
app_dat a. cel l_s i ze_in_pixels; 
private_app_dat a. pi xmap_he ight_in_pixel s = 
app_data.pixmap_height in cells * 
app_data.cell_size in pixels; 
private_app_data.big_picture = XCreatePixmap(XtDisplay(w}, 
RootWindowOfScreen(XtScreen(w}}, 
private_app_data.pixmap_width_in_pixels, 
private_app_data.pixmap_height_in_pixels, 1}; 
values.foreground = 1; 
values.background = 0; 
values.dashes = 1; 
i .... values.dash offset = 0; 
-- 
values.line_style = LineOnOffDash; 
private_app_data.draw_gc = XCreateGC(XtDisplay(w}, 
private_app_data.big_picture, GCForeground I GCBackground 
I GCDashOffset I GCDashList I GCLineStyle, &values); 

values.foreground = 0; 

144 X Toolkit Intrinsics Programming Manual, Motif Edition 



iiiiii!ii Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 
:::::::::::::::::::::: values, background - 1; 
i private_app_data, undraw_gc - XCreateGC (XtDisplay (w), 
private_app_data.big_picture, GCForeground I GCBackground 
I GCDashOffset I GCDashList I GCLineStyle, &values); 
....... 
iiiiiii:iiii values, foreground - app_data, copy_fg; 
ii:;i:;i values, background - app_data, copy_bg; 
.... iiii private_app_data, copy_gc - XCreateGC (XtDisplay (w), 
.. RootWindowOfScreen (XtScreen (w)), 
.-.-:':'i:!: 
i!;iili GCForeground I GCBackground, &values); 
...... 
...:.:.:.:.:.: 
!iiiiiiii XFillRectangle (XtDisplay (w), private app data .big_picture, 
"i:i:i:i:i:i:i -- 
::!?:ili!i private_app_data.undraw_gc, 0, 0, 
i:iliiiiiii private app data. pixmap width in_pixels, 
i::i::i::i:::-:...:.-i pri vat elapp_--dat a. pixmaplheight--_in_pixe 1 s ) ; 
ii:iil /* draw permanent grid into pixmap */ 
" .::::iii 
:.::!i::i.:.-"i!! n_horiz_segments -app_data.pixmap_height in cells + 1; 
:: n_vert_segments - app_data.pixmap_width in cells + 1; 
for (x = 0; x < n_horiz_segments; x += 1) { 
segment [x] .x1 = 0; 
segment [x] . x2 = private_app_data, pixmap_width_in_pixel s; 
segment [x] .yl = app_data.cell_size in pixels * x; 
segment[x] .y2 = app_data.cell_size in pixels * x; 
} 
/* drawn only once into pixmap */ 
XDrawSegments (XtDisplay (w), private_app_data, big_picture, 
private_app_data, draw_gc, segment, n_horiz_segment s) ; 
 for (y = 0; y < n vert segments- y += 1) { 
::::::::iii -- -- " 
::::::::: ....... segment[y] .x1 =y * app_data.cell_size in pixels; 
ii!! segment [y] .x2 = y * app_data.cell_size in pixels; 
segment [y] .yl = 0; 
segment [y ] . y2 = private_app_data, pixmap_height_in_pixels ; 
} 
/* drawn only once into pixmap */ 
XDrawSegments (XtDisplay (w), private_app_data.big_picture, 
private_app_data.draw_gc, segment, n_vert_segments) ; 
} 
/* ARGSUSED */ 
static void 
RedrawPicture(w, event, params, num_params) 
Widget w; 
-i .... XExposeEvent *event; 
:i!!ii String *params; 
iiii Cardinal *num_params; 
register int x, y; 
i!ii i unsigned int width, height; 
.=. 
.... if (event} { /* drawing because of expose or button press */ 
x = event->x; 
y = event->y; 
width = event->width; 
. 
i height = event->height; 
) 

An Example Application 145 



Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 
else { /* drawing because of scrolling */ 
x = 0; 
y= 0; 
width = 10000; /* always the whole window! */ 
height = 10000; 
if (DefaultDepthOfScreen (XtScreen (w} } == i} 
XCopyArea (XtDisplay (w}, private_app_data.big_picture, 
XtWindow(w}, private_app_data.copy_gc, x + 
private_app_data.cur_x, y + private_app_data, cur_y, 
width, height, x, y}; 
else 
XCopyPlane (XtDisplay (w} , private_app_data, big_picture, 
XtWindow (w} , private_app_data.copy_gc, x + 
private_app_data, cur_x, y + private_app_data, cur_y, 
width, height, x, y, 1}; 

} 
/* ARGSUSED */ 
static void 

DrawCell(w, event, params, num_params) 
Widget w; 
XButtonEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
DrawPixmaps (private_app_data.draw_gc, DRAW, w, event} ; 
} 

/* ARGSUSED */ 
static void 
UndrawCell(w, event, params, num_params) 
Widget w; 
XButtonEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
DrawPixmaps (private_app_data.undraw_gc, UNDRAW, w, event) ; 
} 

/* ARGSUSED */ 
static void 
ToggleCell(w, event, params, num_params) 
Widget w; 
XButtonEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
static int oldx = -i, oldy = -i; 
GC gc; 
int mode; 
int newx = (private_app_data.cur_x + event->x) / 
app_data.cell_size_in_pixels; 
int newy = (private_app_data.cur_y + event->y} / 
app_data.cell_size_in_pixels; 
if ((mode = private_app_data.cell[newx + newy * 

146 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 4-15. xbitmap4: implementing the bitmap editor from the application (continued) 

app_data.pixmap_width in cells]) -- DRAWN) 
gc - private_app_data.undraw_gc; 
mode - UNDRAW; 
} 
else { 
gc - private_app_data.draw_gc; 
mode - DRAW; 
} 
if (oldx !-newx II oldy != newy} { 
oldx - newx; 
oldy - newy; 
DrawPixmaps(gc, mode, w, event}; 
} 

/* Private Function */ 
static void 
DrawPixmaps(gc, mode, w, event} 
GC gc; 
int mode; 
Widget w; 
XButtonEvent *event; 
{ 

int newx - (private_app_data.cur_x + event->x} / 
app_data.cell_size_in_pixels; 
int newy = (private_app_data.cur_y + event->y} / 
app_data.cell_size_in_pixels; 
XExposeEvent fake event; 
/* if already done, return */ 
if (private_app_data.cell[newx + newy * 
app_data.pixmap_width in cells] == mode} 
return; 
XFillRectangle(XtDisplay(w}, private_app_data.big_picture, gc, 
app_data.cell_size_in_pixels*newx + 2, 
app_data.cell_size_in_pixels*newy + 2, 
(unsigned int} app_data.cell_size in ixels - 3, 
(unsigned int} app_data.cell_size in pixels - 3); 
private_app_data.cell[newx + newy * 
app_data.pixmap_width in cells] = mode; 
fake_event.x = app_data.cell_size in pixels * newx - 
private_app_data.cur_x; 
fake_event.y - app_data.cell_size in ixels * newy - 
private_app_data.cur_y; 
fake_event.width - app_data.cell_size_in_pixels; 
fake_event.height - app_data.cell_size in pixels; 
RedrawPicture(private_app_data.bitmap, &fake_event}; 

Of particular interest in the code for xbitmap4 is the Syntax function. Notice that it prints 
out the options that were not understood, in addition to printing out a list of valid options. 

An Example Application 14 7 



5 

More About Motif 

This chapter describes each widget in the Motif set that has not yet been 
introduced, and describes the features that Motif adds to the model provided 
by the Xt Intrinsics. 

In This Chapter: 

The Remaining Motif Widgets and Gadgets ....................................... 151 
Geometry Managing Widgets ......................................................... 157 
Dialog Widgets .............................................................................. 159 
Widget Creation Functions ................................................................. 160 
Compound Strings and Font Lists ...................................................... 162 
Simple Compound Strings ............................................................. 162 
Character Sets and Font Lists ........................................................ 164 
Strings with Multiple Fonts ............................................................. 166 
Manipulating Compound Strings .................................................... 168 
Converting Compound Strings to Text ............................................ 169 
Rendering Compound Strings ........................................................ 169 
Pixmap and Image Caching Functions ............................................... 169 
Dynamic Resource Defaulting ............................................................ 171 
Resolution Independence .................................................................. 172 
Keyboard Traversal and Focus ........................................................... 173 
Motif Virtual Keyboard Bindings ......................................................... 174 
The Motif User Interface Language .................................................... 175 



5 
More About Motif 

This book is primarily about how to program with the Xt Intrinsics, and has used the Motif 
widgets to demonstrate those techniques. It has so far not described many of the Motif widg- 
ets, and hasn't touched the surface of the topic of how to combine them to best advantage. 
Complete coverage of these topics is left to the forthcoming Volume Six, X Motif Program- 
ming Manual. However, this chapter will acquaint you with the default appearance and gen- 
eral purpose of the Motif widgets we have not yet used. With this information, you should 
gain a general idea of the range of widgets you have to choose from. 

Motif also provides many features that are roughly at the same level as those provided by Xt, 
but that go beyond those provided by Xt. Part of Motif, therefore, is a kind of extension of 
Xt. This chapter will provide sufficient introduction so that you know the purpose and capa- 
bilities of each of these features. This will enable you to determine whether these features 
will be useful in your application, and warrant further investigation. Again, more complete 
coverage of these features, with examples, will be left to Volume Six, X Motif Programming 
Manual. 

5.1 

The Remaining Motif Widgets and Gadgets 

Let's begin with the primitive widgets that you haven't yet seen in examples in this book. 
These are widgets that do not manage child widgets. Although we have not explicitly 
created ArrowButton and ScrollBar widgets, you have seen them as part of MainWindow and 
ScrolledWindow. ArrowButton is the widget used at the ends of ScrollBars. ScrollBars, in 
turn, are created automatically by MainWindow and ScrolledWindow. 

Command widgets are for keeping track of typed commands. The upper window shows the 
history of past commands typed, and the lower window shows the command currently being 
typed. Figure 5-1 shows a Command widget. 

More About Motif 151 



Filter 
I tmnt/adrian/X/Xt/progslmotif/ch03l* 

Directories 

"ogs/motit/ch03/. 

rogs/motif/ch03/.. 

Files 
Ex3-6 
Ex3-6.c 
Ex3-6.o 
Ex3-7 
Ex3-7.c 
Ex3-7.o 
Imakefile 
Makefile 

Selection 
I tmnt/adrian/X/Xt/progs/motif/ch03/ 

Filter I Cancel I 

Help 

Figure 5-2. A FileSelectionBox widget 

A SelectionBox allows the user to choose from a list of alternatives. It provides a scrolled 
list, and a text area. The user can select from the list using the pointer, or type the name from 
the list. 

More About Motif 153 



Directories 
Arrow Button  
Bulletin Board 
Command 
Drawing Area il 
Drawn Button 
File Selection Box 
Form 
Frame 
: 

Selection 

Figure 5-3. A SelectionBox widget 

Text is a text editor in a single widget. It can edit single line or multiline text. By default it 
uses Emacs-style editing commands. TextField is a single line text editor with provision for 
verification that the user supplied acceptable data. The Text and TextField widgets provide a 
multitude of functions for accessing and manipulating their contents from the application. 
The XmCreateScrolledText function is used for creating a Text widget with Scroll- 
Bars. Figure 5-4 shows a Text and a TextField widget. 

Figure 5-4. A Text and TextField widgets 

The Separator widget is used to visually separate distinct areas within larger components. It 
just draws a line between widgets. Separators can be used to separate items in popup menus, 
action areas within dialog boxes, or simply adjacent geometry managing widgets. Usually 

154 X Toolkit Intrinsics Programming Manual, Motif Edition 



you should use a SeparatorGadget instead. Figure 5-5 shows a menu containing elements 
separated with Separator widgets. 

New 
Open 
Save 

Generate Source Code 
Create Message [OFF] 
Print Resources 
Quit 

Figure 5-5. A menu containing buttons separated by Separator widgets 

A ToggleButton sets a boolean value. ToggleButton is designed to be added in groups to a 
RadioBox or a CheckBox. See Figure 5-6. Both RadioBox and CheckBox are implemented 
using a RowColumn widget. The resources that distinguish these two types of user interface 
elements are automatically set when you use the XmCreateRadioBox or XmCreate- 
SimpleCheckBox convenience functions. Each ToggleButton in a RadioBox has a dia- 
mond-shaped indicator, and only one ToggleButton at a time can be chosen. In a CheckBox, 
each ToggleButton has a. square indicator and any number of the ToggleButtons can be 
selected at the same time. 

More About Motif 155 



modeless 
application modal 
system modal 

Fi'. auto unmanage 
I-.. default position 
... 

Figure 5-6. ToggleButton widgets used in a RadioBox and a CheckBox 

DrawnButton is a widget that works like PushButton but that is empty except for a button 
shadow. It provides callbacks for exposure and resize, so that you can provide your own 
drawing code. DrawnButton is not often used, since PushButton allows you to supply either 
text or a pixmap as its label. DrawnButton can be used to implement an animated button 
(where the contents change frequently), or to draw text that is beyond the capabilities of 
PushButton. Since DrawnButton has no distinctive appearance, it is not shown. 
Scale is really a slider widget, which can be used for input or output. Scale is shown in Fig- 
ure 5-7. 

18 

Figure 5-7. A Scale widget 

Six types of simple widgets are also available as gadgets: PushButtonGadget, LabelGadget, 
ArrowButtonGadget, CascadeButtonGadget, SeparatorGadget, and ToggleButtonGadget. 

156 X Toolkit Intrinsics Programming Manual, Motif Edition 



January 
February 
March 

April 

May 
June 
July 
August 

Figure 5-8. A List widget containing PushButtonGadgets 

The ScrolledWindow widget is used to implement a "window" into a data object (such as text 
or graphics). If the data being viewed is larger than the ScrolledWindow, scrollbars are atta- 
ched to enable the user to view portions of the window interactively. ScrolledWindow is 
capable of automatically creating and operating its own ScrollBar widget children. You have 
to provide ScrolledWindow with a work area to manage. 
The MainWindow widget acts as the standard layout manager for the main application's win- 
dow. It is designed specifically to contain a MenuBar, an optional command window, a work 
region, and scrollbars. This widget is an extension of the ScrolledWindow widget. You have 
to provide MainWindow with a work area and menu bar to manage. 
The Frame widget manages one child within a visible border that the Frame draws. It is most 
often used to provide a 3-D border for RowColumn and Form widgets, which otherwise have 
no 3-D look. 
The PanedWindow widget manages its children in a vertically tiled format only. Its width 
fluctuates with the widest widget in its list of managed children. The widget provides a sash 
to allow the user to adjust the height of each pane. 
The Form widget has an elaborate means of linking the edges of its children to itself and to 
one another. Different layout criteria can be specified for each child. Form widgets are good 
managers to use as children of DialogShells that you build yourself. Like RowColum widg- 
ets, Forms have no border, allowing them to be placed next to other geometry managing 
widgets without giving the appearance that their items are grouped separately. A Frame 
widget is used to give Forms visible boundaries. 

158 X Toolkit Intrinsics Programming Manual, Motif Edition 



5.1.2 Dialog Widgets 

DialogShell and MenuShell perform the window manager interaction as parent widgets of 
dialog widgets and menus respectively. DialogS hell is created alone only when you are 
creating a custom dialog box that is not based on BulletinBoard or Form (since XmCreate- 
BulletinBoardDialog and XmCreateFormDialog exist). MenuShell is used 
when you are creating a menu that is not one of the standard types created by XmCreate- 
PulldownMenu, XmCreatePopupMenu, XmCreateOptionMenu, etc. 
A simple Help dialog box was demonslated in Section 3.4.2. This was a MessageBox 
created as a dialog using XmCreateMessageDialog. A MessageBox widget can be 
configured to display a symbol that represents the kind of information being displayed. Motif 
defines six symbols for this purpose, and provides a widget creation function that creates a 
MessageBox as a dialog for each symbol. They are XmCreateErrorDialog, Xm- 
CreateInformationDialog, XmCreateMes s ageDialog, XmCreate- 
QuestionDialog, XmCreateWorkingDialog, and xmCreatewa rning- 
Dialog. Figure 5-9 shows these five types of dialogs. 

no active widget selected 

OK I HelPl Cancell 

Restart Mwm? 

OK I Cancel I 

Error Question 

Information I Warning Working 

I I 

Figure 5-9. Dialog boxes with the five standard symbols 

As noted in Chapter 3, More Techniques for Using Widgets, there is no standard dialog for 
help information. However, the InformationDialog seems most appropriate, once its Cancel 
button and possibly its Help button are unmanaged. 

More About Motif 159 



5.2 Widget Creation Functions 

You have already seen a few of the functions Motif provides for creating widgets. For 
example, in Chapter 3 we used XmCreatePulldownMenu, XmCreateMenuBar, and 
XmCreateMessageDialog in xmainwindow. As you may recall, these are very similar 
to Xt's widget creation functions except that in the Motif routines: 

The widget parent argument comes before the widget instance name argument (the 
reverse of the Xt functions). 

No widget class pointer is necessary (it is implied by the function name). 

A separate XtblanageChild call is required to display the widgeL 

There are many more of these functions. Some of them create single widgets, some create 
single widgets with certain special resource settings, and some create combinations of widg- 
ets. 
For users of other widget sets such as Athena, the use of the IDs returned by Motif widget 
creation functions can be a bit confusing. The functions that create combinations of widgets 
don't always return the top level widget of the combination. For example, XmCreate- 
MessageD:i.alog returns the ID of the MessageBox widget, not the ID of the DialogShell 
that XmCreateMessageDialog creates as its parent. This allows you to easily set the 
resources of the MessageBox. When you want to pop up the dialog, you call XtManage- 
Child with the ID of the MessageBox, not its DialogShell parent. (Users of the Athena 
widget set popup widgets by calling xtpopup on the Shell widget.) 
Here is a complete list of the xmCreate* functions, and a brief description of what the 
object created is intended for. 

Table 5-1. XmCreate Functions 

Function 

XmCreateArrowButton 
XmCreateArrowButtonGadget 
XmCreateBulletinBoard 
XmCreateBulletinBoardDialog 

XmCreateCascadeButton 
XmCreateCascadeButtonGadget 
XmCreateCommand 
XmCreateDialogShell 
XmCreateDrawingArea 
XmCreateDrawnButton 
XmCreateErrorDialog 
XmCreateFileSelectionBox 
XmCreateFileSelectionDialog 
XmCreateForm 

Description 

Create an ArrowButton widgeL 
Create an ArrowButtonGadget. 
Create a BulletinBoard widget 
Create BulletinBoard widget with DialogShell par- 
ent. 
Create a CascadeButton widget 
Create a CascadeButtonGadget. 
Create a Command widget. 
Create a DialogShell widget 
Create a DrawingArea widget 
Create a DrawnButton widget 
Create a MessageBox with error symbol. 
Create a FileSelectionBox widget 
Create a FileSelectionBox with a DialogShell parent. 
Create a Form widget 

160 X Toolkit Intrinsics Programming Manual, Motif Edition 



Table 5-1. XmCreate Functions (continued) 

Funcdon 

XmCreateFormDialog 
XmCreateFrame 
XmCreateInformationDialog 
XmCreateLabel 
XmCreateLabelGadget 
XmCreateList 
XmCreateMainWindow 
XmCreateMenuBar 

XmCreateMenuShell 
XmCreateMessageBox 
XmCreateMessageDialog 
XmCreateOptionMenu 

XmCreatePanedWindow 
XmCreatePopupMenu 

XmCreatePromptDialog 

XmCreatePulldownMenu 

XmCreatePushButton 
XmCreatePushButtonGadget 
XmCreateQuestionDialog 
XmCreateRadioBox 

XmCreateRowColumn 
XmCreateScale 
XmCreateScrollBar 
XmCreateScrolledList 

XmCreateScrolledText 
XmCreateScrolledWindow 
XmCreateSelectionBox 
XmCreateSelectionDialog 

XmCreateSeparator 
XmCreateSeparatorGadget 
XmCreateSimpleCheckBox 

XmCreateSimpleMenuBar 

Description 

Create a Form widget with DialogS hell parent. 
Create a Frame widget. 
Create a MessageBox with information symbol. 
Create a Label widget. 
Create a LabelGadget. 
Create a List widget. 
Create a MainWindow widget. 

Create a RowColumn widget with resource settings 
for being a menubar. 
Create a MenuShell widget. 
Create a MessageBox widget. 
Create a MessageBox with a DialogShell parent. 
Create a RowColumn widget with resource settings 
for being an option menu. 
Create a PanedWindow widget. 
Create a RowColumn widget with resource settings 
for being a popup menu. 
Create a SelectionBox widget with a DialogShell 
parent. 
Create a RowColumn widget with resource settings 
for being a pulldown menu. 
Create a PushButton widget. 
Create a PushButtonGadget. 
Create a MessageBox with question symbol. 
Create a RowColumn widget with resource settings 
to be a radio box. 
Create a RowColumn widget. 
Create a Scale widget. 
Create a ScrollBar widget. 
Create a ScrolledWindow widget containing a List 
widget. 
Create a Text widget. 
Create a ScrolledWindow widget. 
Create a SelectionBox widget. 
Create a SelectionBox widget with a DialogS hell 
parent. 
Create a Separator widget. 
Create a SeparatorGadget. 
Create a RowColumn widget with resource settings 
to function as a CheckBox, and children. 
Create a RowColumn widget with resource settings 
to function as a MenuBar, and children. 

More About Motif 161 



Table 5-1. XmCreate Functions (continued) 

Function 

XmCreateSimpleOptionMenu 

XmCreateSimplePopupMenu 

XmCreateSimplePulldownMenu 

XmCreateSimpleRadioBox 

XmCreateText 

Description 

Create a RowColumn widget with resource settings 
to function as a OptionMenu, and children. 
Create a RowColumn with resource settings to func- 
tion as a popupMenu, and children. 
Create a RowColumn widget with resource settings 
to function as a PulldownMenu, and children. 
Create a RowColumn widget with resource settings 
to function as a RadioBox, and children. 
Create a Text widget. 

XmCreateTextField 
XmCreateToggleButton 
XmCreateToggleButtonGadget 
XmCreateWarningDialog 
XmCreateWorkArea 

XmCreateWorkingDialog 

Create a TextField widget. 
Create a ToggleButton widget. 
Create a ToggleButtonGadget. 
Create a MessageBox with warning symbol. 
Create a RowColumn widget with resources to func- 
tion as a WorkArea. 
Create a MessageBox with working symbol. 

5.3 Compound Strings and Font Lists 

Compound strings are designed to address two issues frequently encountered by application 
designers: the use of foreign character sets to display text in other languages, and the use of 
multiple fonts when rendering text. 
Many character sets used by foreign languages are too large for the characters to be repre- 
sented by the char type, as English can be. Compound strings solve this problem by repre- 
senting characters as 16 bit values ("words") rather than the classic 8 bit values ("chars"). 
Also, since some languages such as Hebrew and Arabic are read from right-to-left, compound 
strings also store directional information for rendering purposes. 
A compound string is made of three elements: a character set, a direction and text. Com- 
pound strings that incorporate multiple fonts are achieved by concatenating separate com- 
pound strings with different character sets together to produce a single string. 

5.3.1 

Simple Compound Strings 

Almost all of the Motif widgets require a compound string when specifying text. Labels, 
PushButtons, Lists--all require their text to be given in compound string format, whether or 
not you require the additional flexibility compound strings provide.* Therefore, the most 

*Currently, the Text widget does not require compound strings, but it will in future releases of Motif. 

162 X Toolkit Intrinsics Programming Manual, Motif Edition 



common use for compound strings in English-language applications is simply to convert 
standard C-style null-terminated text strings for use in a widgeL 
First of all, strings specified in resource files need not be converted, since Motif will automat- 
ically do the conversion. 
To do the conversion for strings specified directly in the application code, we use the function 
XmSt ringCreateSimple (). 
XmString 
XmStringCreateSimple (text) 
char *text; 
The text parameter is a common C cha r string. The value returned is of type xmSt ring 
which is an opaque type to the programmer. 
As its name implies, xmStringCreateSimple () does nothing special. The function 
converts a C string into a compound string using the default font and direction. You cannot 
specify a font, a string direction, or have multiple lines. Common usage might be as follows: 
XmString str= XmStringCreateSimple ("Push Me") ; 
widget = XtVaCreateManagedWidget ("widget_name", 
xmPushButtonGadgetClas s, parent, 
XmNlabelString, str, 
NULL) ; 
XmStringFree (str) ; 
XmStringCreateSimple (), along with the other functions tt create compound 
strings, allocates memory to store the strings created. Widgets whose resources take com- 
pound strings as values always allocate their own space and store copies of the compound 
string values you give them, so you must free your copy of the string after having set it in the 
widget resource. Compound strings are freed using xmSt ringFree (). 
This three-step process is typical of the type of interaction you will have with compound 
strings. You create a string, set it in a widget, then free the string (unless you want to use it in 
another widget). However, this process involves quite a bit of overhead; memory is allocated 
by the string creation function, then again by the internals of the widget for its own storage, 
and then your copy of the string must be deallocated (freeing memory is also an expensive 
operation). 
This process can be simplified by using the XtVaTypedArg feature in Xt. This symbol is 
used in variable argument list specifications for functions like XtVaCreateManaged- 
Widget or XtVaSetValues. It allows you to specify resources in any type--most likely 
a more convenient one--and have Xt do the conversion for you. In the case of compound 
strings, this method can be used convert between C strings and compound strings without 
having to do it yourself. The following code fragment has the same effect as the example 
shown above without the overhead of the three-step process. 
widget = XtVaCreateManagedWidget ("widget_name", 
xmPushButtonWidgetClass, parent, 
XtVaTypedArg, 
XmNlabelString, XmRString, "Push Me", sizeof(char *) , 
NULL) ; 

More About Motif 163 



Example 5-1. multi_font: code to use multiple fonts in a compound string (continued) 
text = XmStringConcat (trap, s3) ; 
XtVaCreateManagedWidget ( "widget_name" , 
xmLabelWidgetClass, toplevel, 
XmNlabelSt ring, text, 
NULL) ; 
XmStringFree (sl) ; 
XmStringFree (s2) ; 
XmStringFree (s3) ; 
XmStringFree (trap) ; 
XmStringFree (text) ; 
XtRealizeWidget (toplevel) ; 
XtAppMainLoop (app) ; 

The output of this code fragment is shown in Figure 5-10. 

multi-font 
......... 

Figure 5-10. multi_font: how it looks on the screen 

The XmNfontList resource is initialized to have three character set and font name pairs. 
Each string is created using xmSt:ringCreat:e ( ) with the appropriate text and character 
set specified. Then, the strings are concatenated together using xmSt ringConcat ( ), two 
at a time, until we have a single compound string that contains all the texts and includes all 
the character set changes. 
It is possible to specify compound text strings (such as the XrnNlabelString resource of 
the Label widget) in resource files as normal strings. This is possible because Motif takes 
care of the conversion to compound strings. However, when you want font changes within a 
string, you need to create compound strings or segments explicitly within the application as 
illustrated in Example 5-1. 

More About Motif 167 



5.3.4 Manipulating Compound Strings 

Most C programmers are used to dealing with functions such as st rcpy ( ), st rcmp (), 
and st rcat ( ), to copy, compare and modify strings. However, these functions are ineffec- 
tive with compound strings since compound strings are not based on a byte-per-character for- 
mat and they have other types of information embedded within them (character sets, direc- 
tions and separators). In order to accomplish some of these common tasks, you can either 
convert the compound string back into C strings or use the functions Motif provides to 
manipulate compound strings directly. Your choice depends largely on the complexity of the 
compound strings you have and the complexity of the manipulations you need to do. 
We've already seen how xmStringConcat () is used to concatenate compound strings. 
The following utility functions are also provided: 
Boolean 
XmStringByteCompare (strl, str2) 
XmString strl, str2; 
Boolean 
XmStringCompare (strl, str2) ; 
XmString strl, str2; 
XmSt ring 
XmStringConcat (strl, str2) 
XmString strl, str2; 
XmSt ring 
XmStringNConcat (strl, str2, n) 
XmString strl, str2; 
int n; 
XmString 
XmSt ringCopy ( st r) 
XmSt ring str; 
XmString 
XmStringNCopy (str, n) 
XmSt ring str; 
int n; 
int 
XmStringHasSubstring (string, substring) 
XmString string, substring; 
int 
XmSt ringLength (st r) 
XmSt ring str; 
The XraStringNConcat () and XmStringNCopy() functions differ from their 
"N-less" brethren in that they concatenate or copy, respectively, only n characters from the 
specified string. Otherwise, the purpose of these functions is readily apparent from their 
names. Note however that since a compound string includes various tags, direction indica- 
tors and segment separators, XmStringr.ength () cannot be used to get the length of the 
text represented by the compound string (i.e., it's not the same as strlen ( ) ). 

168 X Toolkit Intrinsics Programming Manual, Motif Edition 



The only thing slightly confusing about XmGetPixmap is that you specify your filename 
(including path) in the iraage-narae argument 
X also defines a client-side representation of a window area, called an image. An image is 
usually generated by grabbing a portion of an existing window or pixmap using XGet- 
Tmage. An image is a structure that contains all the data from a window area, using the 
server's natural data format. The structure also includes fields that describe the combination 
of byte-order, bit-order, and image format used by the server. Unlike many other Xlib struc- 
tures, the image structure is publicmits fields are documented msince it is stored on the cli- 
ent side. Because of the many permutations of server formats that are possible, Xlib provides 
generalized functions for manipulating image data, though they are rather slow because they 
always convert the data into the client's natural format before processing it An image can be 
dumped into a window or pixmap using xPut xmage. 
Motif uses images to allow pixmaps to be specified in resource files, and to allow multiple 
instances of a widget to share one pixmap stored in the server. For example, you know that 
the MessageBox widget has several variations, with different symbols for information, warn- 
ing, error, question, and working. Each of these symbols is created by MessageBox using 
XmTnstallXmage. (This happens before any instances of the widget class are created, in 
the class_initialize method, which will be described later.) To install each image, 
first an image structure is created and filled with data in standard X11 bitmap file format. 
Then this structure is passed to XmInstallImage. Also passed is the string name for this 
image, which will be used to used to refer to the image in resource files. For example, the 
question symbol is called de f a u 1 t_xm_que s t i o n. 
When an instance of MessageBox is created using a call such as xmCreateQuestion- 
Dialog, the XmNdialogType resource is automatically set to XmDIALOG_QUESTION. 
In a switch statement, MessageBox maps this symbol into the corresponding image name, 
"default_xm_question." MessageBox calls XmGetPixmap to get the pixmap specified by 
this image name. If the pixmap already exists because another QuestionDialog has already 
been created, then this pixmap is set into the XmNsymbolPixmap resource. If the pixmap 
does not yet exist, it is created, cached for later use by widgets of this type, and set into Xm- 
NsymbolPixmap. (You can also bypass this entire facility from the application by creat- 
ing your own pixmap and setting XmNsymbolPixmap directly.) 
Motif keeps reference counts in order to free these cached pixmaps when they are no longer 
needed. Therefore, MessageBox calls XmDestroyPixmap when the XmNsymbol- 
Pixmap is set directly, when the dialog type is changed, or when the widget itself is des- 
troyed. XmDestroyPixmap just decrements the reference count to a pixmap--the pix- 
map is deslroyed only if no other widgets are using it. 
Motif defines a group of images that are pre-installed in the image cache. Each of these is 
converted into pixmaps when they are first used to set a widget resource, using the current 
foreground and background colors for that first widget. Table 5-2 lists and describes these 
pixmaps. 

170 X Toolkit Intrinsics Programming Manual, Motif Edition 



fled widget's XmNnavigationType resource. There are various other settings for this 
resource that you can use if you set the resource directly instead of using these functions. 
You can also move the focus by clicking the pointer in a widget that can accept the focus (has 
XmNtraversalOn set to True). Within Motif applications, you can choose between a 
click-to-type model, which supports keyboard traversal, and a pointer-following model, 
which does not support keyboard traversal. The default is the click-to-type model. You can 
change this by setting the XmNkeyboardFocusPolicy resource of a Shell widget, but 
this is not recommended. Note that this resource sets the keyboard focus model within this 
one application; this is completely separate from the model you choose for mwm, although 
the two choices available in each case are the same. 
List, ScrollBar, multiline Text widgets, and Option menus must be sole members of a tab 
group, because they use the arrow keys for other purposes. 
Because keyboard traversal depends on Motif moving the keyboard focus around, applica- 
tions should not set the keyboard focus explicitly. In other words, you should never call Xt- 
SetKeyboardFocus or XSetlnputFocus. Instead you can call XmProcess- 
Traversal. 
Even Motif menus can be operated using the keyboard. A menu can be mapped by a 
mnemonic such as AIt-F typed anywhere in the application. Once mapped, the menu can be 
traversed with the arrow keys, and an item selected with the Return key. Alternately, if the 
strings in the menu have mnemonics defined, they will have letters underlined, and the user 
can type these letters to select the item. Finally, menu items can be selected without the 
menu being mapped by using accelerator keys, which are described in Chapter 8, Events, 
Translations, and Accelerators. 

5.8 Motif Virtual Keyboard Bindings 

The main alphabetic area of keyboards on different systems is very uniform, but the modifier 
keys such as Control, Alt, Meta, Hyper, and Super, and the function keys, are not uniform. 
The X keyboard model hides many of the differences between the different keyboards that 
are available on different systems. Each X server contains a mapping between the keycodes 
for each physical key, and keysyms, which are symbolic constants each of which represents a 
standardized meaning of a key combination. For example, there are separate keysyms XK_A 
and XK a which represent the "a" key with and without the Shift key pressed. See Volume 
One, Xlib Programming Manual, for an extensive discussion of this model. 

Motif adds another level of mapping to this system. Translation tables for Motif widgets ref- 
erence keysyms not defined by the Xlib standard. For example, a line in the translation table 
of every Motif widget reads as follows: 

static char defaultTranslation[] = 

<Key>osfHelp: Help () "; 
The string osfHelp is in the position normally occupied by a keysym, but in this case it is a 
Motif virtual keysym. Motif then internally maps this string into a real keysym. 

174 X Too&# Intrinsics Programming Manual, Motif Edition 



Example 5-2. The .c file for a simple UIL application (continued) 
Widget widget; 
XtPointer client_data; 
XtPointer call_data; 

.............. 
........... -. 
....... 
....... 
:::::::::::::: 
-::::::.:::::. 
iiiiii!iiiii!i int argc; 
iiiiiiiiili:i char **argv; 
::::::::::': 

...... 
.............. 
-:::::-::::::: 

XmAnyCallbackStruct *data = (XmAnyCallbackStruct *) call_data; 
char *tag = (char *) client_data; 

printf ("button selected\n"} ; 

XtAppContext app_context; 
Widget topLevel, appMain; 
/* 
* Initialize the MRM 
*/ 
MrmInitialize (); 

topLevel = XtVaAppInitialize( 

/* 

&app_context, 
"XUilDemo", 
NULL, 0, 
&argc, argv, 
NULL, 
NULL); 

/* Application context */ 
/* application class name */ 
/* command line option list */ 
/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

* Define the Mrm.hierarchy (only 1 file) 
*/ 

if (MrmOpenHierarchy (I, /* number of files */ 
vec, /* files */ 
NULL, 
&s_MrmHierarchy} /* ptr to returned id */ 
!= MrmSUCCESS} { 
printf ("Mrm can't open hierarchy\n"}; 

Register our callback routines so that the resource 
manager can resolve them at widget-creation time. 

if (MrmRegisterNames (regvec, regnum) 
!= MrmSUCCESS} 
printf("Mrm can't register names\n"}; 
/* 
* Call MRM to fetch and create the pushbutton and its container 
*/ 
if (MrmFetchWidget (s_MrmHierarchy, 
"helloworld main", 
topLevel, 
&appMain, 
&class) != MrmSUCCESS) 

176 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 5-2. The .c file for a simple UIL application (continued) 
printf ("Mrm can't fetch interface\n") ; 
/* Manage the main window of the hierarchy created by Mrm. */ 
XtManageChild (appMain) ; 

XtReali zeWidget (topLevel) ; 
XtAppMainLoop (app_context) ; 

This .c file stays essentially the same for a much more complicated application, with the 
exception of added callback functions and added event handlers for popping up popup widg- 
ets. The description of the hierarchy of widgets lies in one or more .uil modules. Example 
5-3 shows the .uil module for the application whose C code is shown above. 

Examp 5-3. The.uflfile rasimp Uapplication 
module helloworld 
version = 'vl.O' 
names i case sensitive 
procedure 
button_selected(); 
object 
helloworld main : XmRowColumn { 
controls { 
XmLabel our_label; 
XmPushButton our_button; 
}; 
}; 
object 
our button : xmPushButton { 
arguments { 
XmNlabelString = compound_string (" Hello" , separate=true) 
& "World!'; 
}; 
callbacks { 
XmNactivateCallback = procedure button selected(); 
}; 
}; 
object 
our label : XmLabel { 
arguments { 
XmNlabelString = 

}; 

compound_string('Press button once',separate=true) & 
compound_string('to change label;',separate=true) & 
"twice to exit.'; 

end module; 

More About Motif 177 



6 

Inside a Widget 

This chapter describes the code inside a basic widget. Much of this code is 
common to all widgets. You can think of it as a framework that Xt uses to 
implement a widget's features. After reading this chapter, you should under- 
stand the procedure for creating your own widget around this framework. 

In This Chapter: 

Widget Source File Organization ........................................................ 184 
The Private Header FilemBitmapEdiP.h ............................................ 185 
Parts and Records ......................................................................... 185 
Class Part and Class Record ......................................................... 186 
Instance Part and Instance Record ................................................ 187 
The Widget Implementation FilemBitmapEdit.c ................................. 189 
Obligatory Include Files .................................................................. 190 
Defining the Resource List ............................................................. 191 
The Translation Table and Actions Table ........................................ 194 
Declaring Methods ......................................................................... 196 
Initializing the Class Record ........................................................... 197 
The Core Class Part .................................................................... 197 
Initializing the Core Methods ........................................................ 200 
Description of Core Methods .......................................................... 202 
Packaging the Class Record for Application Use ............................ 204 
A Sample Method .......................................................................... 204 
The Public Header FileBitmapEdit.h ............................................... 207 
The Process of Widget Writing ........................................................... 209 
Summary of Conventions ................................................................... 211 



6 
Inside a Widget 

This chapter reveals the framework of code common to all widgets. As an example, it 
describes the code for the BitmapEdit widget that was used in versions of the xbitmap appli- 
cations early in Chapter 4, An Example Application. Later examples in that chapter 
described how to implement the bitmap editor without a BitmapEdit widget. Therefore, you 
have already seen the code that is specific to this widget, and can concentrate on the frame- 
work and how to place widget-specific code within this framework. 
Some applications use only the standard user interface elements defined in the widget set. If 
you are writing an application like this, you have no need to write your own widgets, and no 
real need to understand the internals of widgets. However, many applications have at least 
one custom window which has features not supported by any existing widget. To implement 
such features, you can add to a Core or Primitive widget from your application code or you 
can write your own widget. 
Placing specialized user-interface code into a widget has several advantages. For one, the 
widget becomes a self-contained module that can be modified and documented separately 
and used in other programs. Second, the code will take advantage of Xt's automatic dis- 
patching of events to widgets, and several other features that you can't use from the applica- 
tion. Finally, it is a general premise of Xt that application code should be separated as much 
as possible from user-interface code. 
It is important to remember that widget classes are never written from scratch. People 
always start from template files that contain the framework for a widget without the specific 
code, or even better, if possible, from an existing widget that has some similar characteristics. 
Therefore, you'll never have to type in the framework you're about to see. You'll only have 
to learn where to insert your code into it. The beauty of the widget framework is that the 
code within it is very modular--each module has a specific place and purpose. Once you 
understand the framework, you can locate these modules in existing code and use them as 
examples. Chapter 7, Basic Widget Methods, shows you how to write the most important 
modules within the framework. 
By and large, a widget whose superclass is Core can operate under any widget set without 
modification. However, both the Motif widget set and the OPEN LOOK widget set have 
Primitive classes beneath Core that add some basic features common to all widgets in each 
seL In the case of Motif, by subclassing from Primitive you get support for keyboard traver- 
sal with highlighting, resolution independence, shadows, Motif's automatic color selection, 
and a Help key callback. These features are basic to Motif's user-interface conventions, and 

Inside a Widget 183 



Class hierarchy 

I Core i 
I 

Figure 6-1. The class hierarchy of the BitmapEdit widget (with other classes shown doed) 

class and instance structures of a subclass of Composite such as Box begin with the fields 
from Core, continue with fields from Composite, and end with the fields defined by Box. 
Composite and Constraint are subclasses of Core that have additional methods that allow 
them to manage children; they are described in Chapter 12, Geometry Management. This 
chapter concentrates on the features of the Core widget. 
Xt requires that you implement each class's new fields as a separate structure called a part:, 
and then combine this part: structure with each superclass's part: structure in the complete 
structure called a Rec, or record. In real code, these structures are called 
widgetnameClasspart: and widgetnameClassRec for the class structure, and simply 
widgetnamepart: and widgetnameRec for the instance structure. 
The reason for this "structure within a structure" design is primarily to reduce the changes in 
the code of subclasses that would be required if changes were made to the superclass's struc- 
tures. As we will see later, only the portion of the .c file that initializes the class structure 
will need changing if a superclass class structure is changed. A second benefit of this design 
is that it reduces the amount of typing required to implement a new class. 

Class Part and Class Record 

Let's make these ideas concrete by showing the class structure for BitmapEdit. The complete 
class structure is called Bit:mapEdit:ClassRec, and the partial structure is called 
Bit:raapEdit:ClassPart:. Their definitions from BitmapEdiP.h are shown in Example 
6-1. 

Example 6-1. BitmapEdiP.h: the class part and class record 
/* 
* BitmapEditP.h - Private definitions for BitmapEdit widget 
*/ 

/* protect against multiple including of this file */ 
#ifndef _ORABitmapEditP_h 
#define _ORABitmapEditP_h 

186 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 6-1. BitmapEdiP.h: the class part and class record (continued) 

/* 
* Include private header file of superclass. 
* In this case, however, Primitive's header file is 
* thrown into XmP.h. 
*/ 
#include <Xm/XmP. h> 
/* 
* Include public header file for this widget. 
*/ 
#include "BitmapEdit. h" 
/* New fields for the BitmapEdit widget class record */ 
typedef struct { 
int make_compiler_happy; /* need dummy field */ 
} BitmapEditClassPart; 
/* Full class record declaration */ 
typedef struct _BitmapEditClassRec { 
CoreClassPart core class; 
XmPrimitiveClas sPart primitive_class; 
BitmapEditClassPart bitmapEdit_cla s s; 
} BitmapEditClassRec; 
Like most widget classes, BitmapEdit provides no new fields in the class part, but it needs 
one dummy member to make the C compiler happy. A class defines new class part fields to 
allow a subclass to choose to inherit a function or to replace it. Most classes don't define 
fields here because they don't plzn to have subclasses. This fine point is described in Section 
12.4.5. 
The CorePart and CoreClassPart structures are defined in Core's private header file 
<X]]/CoreP.h>, which is included by <Xm/XmP.h>. XmPrinLtivePart and xm- 
PrimitiveClassPart are also defined in <Xm/XmP.h>. In general, you need to 
include the private header file of the superclass at the top of your private header file. The 
header files begin with an i fnde f statement that allows the preprocessor to make sure that 
no header file is included twice. 
If the class structure contains a pointer to an extension structure, you can add to the class 
structure in later releases of your widget and maintain binary compatibility with subclasses. 
This feature is used in the basic Intrinsics classes Composite and Consuaint, but is unlikely 
to be useful to you. However, when you do define an extension structure, you do so in the 
private header file. Extension structures are discussed in Section 14.13. 

Instance Part and Instance Record 

The instance record is built exactly like the class structure: by defining new fields in a part 
structure, and then by combining the instance parts of all superclasses in the instance record. 
Bit:mapV.dit:Part: defines BitmapEdit's new widget instance fields, and the entire widget 
instance record is Bit:mapEditRec. These structures are defined in BitmapEdiP.h (along 

Inside a W'KJget 187 



with the class structures just shown) and are shown in Example 6-2. We've included several 
likely instance variables, but none of those shown is an essential part of the widget structure. 

Examp 6-2. BitmapEdiP.h: e sncepaandsncerecord 
/* New fields for the BitmapEdit widget record */ 
typedef struct { 
/* resources */ 
Pixel foreground; 
XtCallbackList callback;/* application installed callback fns */ 
Dimension pixmap_width in cells; 
Dimension pixmap_height in cells; 
int cell_size_in_pixels; 
int cur_x, cur_y; /* pstn of visible corner in big pixmap */ 
char *cell; /* for keeping track of array of bits */ 
Boolean showAll; /* whether bitmap should display 
entire bitmap */ 
/* private state */ 
Dimension pixmap_width_in_pixels; 
Dimension pixmap_height_in_pixels; 
Pixmap big_picture; 
GC draw_gc; /* for drawing into pixmap */ 
GC undraw_gc; /* for undrawing into pixmap */ 
GC copy_gc; /* for copying pixmap into window */ 
} BitmapEditPart; 

* Full instance record declaration 
*/ 
typedef struct _BitmapEditRec { 
CorePart core; 
XmPrimitivePart primitive; 
BitmapEditPart bitmapEdit; 
} BitmapEditRec; 

#endif 

/* _ORABitmapEditP_h */ 

Unlike the class part, which generally defines no new fields, the instance part of a widget 
almost always defines new instance variables. These variables control all the configurable 
elements of the widget, and they hold the widget's state. 

Some of these instance variables are resources because they are listed in the resource list in 
the BitmapEdit.c file. (This resource list has exactly the same format as the resource list you 
saw in the application code in Section 3.6.2). These variables are known as public instance 
variables (because they are readable and writable from the application). By convention, the 
public instance variables are placed first in the instance part structure, and comments indicate 
which fields are public. When the application instantiates the widget, Xt sets the public fields 
based on the resource databases, the command line (the -xrm form), and the argument list 
passed to XtVaCreateManagedWidget. [ter on, the application may change these 
fields using xtvaSetValues. 

The private instance structure fields (not listed in the widget's resource list) are either 
derived from resource values or they hold some aspect of the widget's state (such as whether 
it is highlighted). As in Example 6-2, graphics contexts (GCs) are always found here as pri- 
vate fields if the widget draws any graphics. Graphics contexts are needed for doing draw- 
ing, and are derived from public instance structure fields such as colors and fonts, because it 

188 X Toolkit Intrinsics Programming Manual Motif Edition 



Structure of widget .c File 

Header Files 
Resource List 

Action Function Declarations 

Actions Table 

Default Translation Table 

Method Function Declarations 

Class Record Initialization 

Method Function Definitions 

Action Function Definitions 

I 
I 
I 
I 

#include <Xll/...> 

static XtResource resources = { }; 

static void Action(); 

static XtActionsRec actions[]={}; 

static char defaultTranslations[]=""; 

static void Initialize(), Redisplay(); 

NewWidgetClassRec newWidgetClassRec={}; 
{ 
/*CoreClassPart,etc.*/ 
} 

static void Initialize() 
{ 
. 

static void Action() 
{ 

Figure 6-2. Order of code in widget .c file 

Defining the Resource List 

A widget inherits the resources defined by its superclasses, and it can also add its own 
resources by defining a resource list and setting it into the class structure. A widget resource 
list is identical to an application resource list, which you saw added to xbitmap in Chapter 4. 
The only difference is that a widget need not call XtGetApplicationResources. 

In creating an application resource list, we created a structure called app_data whose 
fields were to be set through resources. In widget code, the instance pan structure is used just 

Inside a Widget 191 



like app_data, except that the private instance structure fields will not appear in the 
resource list. Each member of the instance structure that is to be a resource must have an 
entry in the resource list. 

Example 6-5 shows a resource list for the public instance variables defined previously in 
Example 6-2. 

Example 6-5. BitmapEdit's resource list 
#define offset (field) XtOffsetOf (BitmapEditRec, field) 
static XtResource resources[] = { 
{ 
XtNtoggleCallback, 
XtCToggleCallback, 
XtRCallback, 
sizeof (XtPointer) , 
offset (bitmapEdit. callback), 
XtRCallback, 
NULL 
}, 
{ 
XtNcellSizeInPixels, 
XtCCellSizeInPixels, 
XtRInt, sizeof(int}, 
offset (bitmapEdit. cell_size in pixels) , 
XtRImmediate, 
(XtPointer) DEFAULT CELL SIZE 
}, 
{ 
XtNpixmapWidthInCell s, 
XtCPixmapWidthInCell s, 
XtRDimension, 
sizeof (Dimension) , 
offset (bitmapEdit.pixmap_width in cells), 
XtRImmediate, 
(XtPointer) DEFAULT PIXMAP WIDTH 
}, 
{ 
XtNpixmapHeight I nCel i s, 
XtCPixmapHeight InCell s, 
XtRDimension, 
sizeof (Dimension) , 
offset (bitmapEdit.pixmap_height in cells) , 
XtRImmediate, 
(XtPointer) DEFAULT PIXMAP HEIGHT 
}, 
{ 
XtNcurX, 
XtCCurX, 
XtRI nt, 
sizeof (int} , 
offset (bitmapEdit. cur_x) , 
XtRImmediate, 
(XtPointer) 0 
}, 
{ 
XtNcurY, 

192 X Toolkit intrinsics Programming Manual Motif Edition 



Example 6-5. BitmapEdit's resource list (continued) 

Xt CCu rY, 
XtRInt, 
sizeof (int}, 
offset (bitmapEdit. cur_y}, 
XtRSt ring, 
(XtPointer) NULL 
}, 
{ 
XtNcel iArray, 
XtCCel iArray, 
XtRString, 
sizeof (String}, 
offset (bitmapEdit. cell}, 
XtRImmediate, 
(XtPointer} 0 
}, 
{ 
XtNshowEntireBitmap, 
XtCShowEntireBitmap, 
XtRBoolean, 
sizeof (Boolean} , 
offset (bitmapEdit. showAll }, 
XtRImmediate, 
(XtPointer) True 
}, 

}; 

The details of each field in a resource list entry is presented in Chapter 10, Resource Man- 
agement and Type Conversion. 
As mentioned earlier, a widget class inherits all the resources defined in the resource lists of 
its superclasses. If a resource is given the same name as a superclass resource, it overrides 
the superclass resource. One reason to create a new resource with the same name as a super- 
class resource is to give it a new, subclass-specific default value. The Primitive widget does 
this to replace Xt's default value for XmNbackground and XmNbackgroundPixmap. 
Another reason is to provide further processing on a resource value. For example, Primitive 
redefines the XmNx and XmNy resources so that it can add code to calculate these values 
using the current unit type (to implement resolution independence). 
When defining a resource list, use constants defined in <Xm/Xm.h> whenever possible. How- 
ever, any constant unique to this widget class can be defined in the public include file, as is 
described in the next section. 
Table 6-1 summarizes the conventions for the constants used in the resource list. 

Inside a Widget 193 



conflicts with other widget classes. Example 6-9 shows the method declarations from 
BitmapEdit. 

Examp  BitmapEdit.c: nctionpe declarations 
/* Declaration of methods */ 
static void Initialize(); 
static void Redisplay(); 
static void Destroy(); 
static void Resize(); 
static Boolean SetValues(); 
static XtGeometryResult QueryGeometry(); 
/* these Core methods not needed by BitmapEdit: 
* 
* static void ClassInitialize(); 
* static void Realize(); 
*/ 
/* the following are functions private to BitmapEdit */ 
static void DrawPixmaps(), DoCell(), ChangeCellSize(); 
/* the following are actions of BitmapEdit */ 
static void DrawCell(), UndrawCell(), ToggleCell(); 

Initializing the Class Record 

We've already shown you how to create the resource list, the translation table, and the 
actions table, and set into the class structure. A major part of the work is done. Now we just 
need to insert the method names we declared earlier into the class record, and set a few of the 
miscellaneous data fields 

As we saw in the discussion of the private header file, the BitmapEdit class record includes 
class parts for BitmapEdit itself and for each superclass of BitmapEdit, in this case Primitive 
and Core. To initialize the class record, each class part has to be initialized field by field. 
Fortunately this is easy because the majority of the fields are always initialized to the same 
values. 

6.3.5.1 

The Core Class Part 

Since all widget classes are subclasses of Core, all need to initialize the Core class part. 
Example 6-10 shows the core part initialized as needed by the BitmapEdit widget. The 
actual name of each field is shown in the comment at left. Each field will be discussed after 
the example. 

Examp 6-10. BitmapEdit. itiaationofCoreclassrecord 
BitmapEditClassRec bitmapEditClassRec = { 
{ /* core class fields */ 
/* superclass / (WidgetClass) &coreClassRec, 
/* class name */ "BitmapEdit", 
/* widget_size */ sizeof(BitmapEditRec), 

Inside a Widget 197 



Backing Store Provides hints about when a window's contents should be preserved by the 
server even when the window is obscured or unmapped. This is useful for 
widgets that are very time-consuming to redraw. Not all servers are cap- 
able of maintaining a backing store. Check the value returned from the 
Xlib DoesBackingStore macro to determine whether this feature is 
supported on a particular screen on your server. 
Saving Under Provides hints about whether or not the screen area beneath a window 
should be saved while a window such as a popup menu is in place, to save 
obscured windows from having to redraw themselves when the popup is 
removed. Not all servers can save under windows. You can find out 
whether this feature is supported on a particular screen with the Xlib 
Does SaveUnders macro. 
Colormap Determines which virtual colormap should be used for this window. If 
your widget requires a lot of specific colors--for example, to draw a shad- 
ed image, it may need to create its own virtual colormap. In that case, it 
would set this attribute to the ID of the created colormap. For more infor- 
mation, see Chapter 7, Color, in Volume One, Xlib Programming Manual. 
Cursor Determines which cursor should be displayed when the pointer is in this 
window. You must create this cursor before setting this attribute. This can 
be done with a standard type converter, as described in Chapter 14, Mis- 
cellaneous Toolkit Programming Techniques. 
It may clarify the picture to describe the features that window attributes do not affect. Set- 
ring the window attributes does not determine a window's parent, depth, or visual. These are 
all set when a window is created, and are permanent. The window attributes are also not 
used for setting the size, position, or border width of a widget. These are set using xtSet- 
Values. Window attributes do not determine how graphics requests are interpreted; this is 
the job of the graphics context (GC). 
Note that some of the window attributes are not listed here because they should not be set di- 
rectly by widgets, in the realize method or anywhere else. These include the 
event mask, which controls which events are sent to this widget. Xt itself sets this win- 
dow attribute based on the translation table. Another is override redirect, which is 
-- 
handled by the Shell widget. 
You could write a realize method that set your desired attributes and then called Xt- 
CreateWindow. But this is slightly wasteful, since Core already has a reali ze method 
that creates a window and you can take advantage of it. This is the second inheritance 
scheme used for self-contained fields. You define your own realize method just as if you 
were going to write it from scratch, but then you call the superclass's realize method di- 
rectly, as shown in Example 6-13. 

Examp 6-13. heriting by voking e supemss meod from a widget meod 
::: #define superclass (&coreClassRec) 
. .i static void Realize(w, valueMask, attributes) 
-  Widget w; 
-!!!i XtValueMask *valueMask; 

206 X Toolkit Intrinsics Programming Manual, Motif Edition 



6.6 Summary of Conventions 

The naming conventions for the various structure declarations in the widget source files can 
be confusing. Table 6-3 summarizes these conventions, using the BitmapEdit widget as an 
example, and describes where each type is used. This table is just to help you read the code. 
If you create a new class starting from an existing class, and globally change the names as 
described above, all of the definitions and references listed here will already be done for you. 

Table 6-3. Summary of Xt Structure Name Conventions 

Sucture Name 

BitmapEditClassPart 

BitmapEditClassRec 

bitmapEditClassRec 

BitmapEditPart 

BitmapEditRec 

_BitmapEditRec 

_BitmapEditClassRec 

BitmapEditWidget 

BitmapEditWidgetClass 

bitmapEditWidgetClass 

Descripdon 

Partial class structure typedef (usually dummy field only) used for de- 
firting BitmapEditClassRec in P.h file. 
Complete class structure typedef, declared extern in P.h file, used 
for initializing class structure in .c file. 
Name of complete class structure allocated in .c file, declared ex- 
tern in P.h file, allocated in .c file, used as superclass in class 
record initialization of subclasses of this widget (.c file). 
Partial instance structure typedef, used for defining BitmapEdit- 
Rec in P.h file. 

Complete instance structure typedef, also used to initialize widg- 
et size field of class record in .c file. 
Type of BitmapEditRec, used for defining BitmapEdit- 
Widget pointer in .h file. 
Type of BitmapEditClassRec, used for defining Bitmap- 
EditWidgetClass pointer in .h file. 
Pointer to BitmapEditRec (complete instance structure), used to 
reference instance structure fields in .c file (passed as argument to 
methods). 
Pointer to _BitmapEditClassRec, used to cast bitmapEdit- 
Clas sRec for superclass in class record initialization of subclasses 
of this widget (.c file). 
Of Dq WidgetClass, address of bitmapEditClassRec, 
used in XCreateWidget calls to identify class to be created. 

Inside a Widget 211 



7 

Basic Widget Methods 

This chapter describes the initialize, expose, set_values, resize, 
query_geometry, and destroy methods. It explains when Xt calls each 
method, and describes in detail what should be in each of these methods. 
Among other things, these methods prepare for and do the drawing of graph- 
ics that appear in a widget. This chapter describes what the Toolkit adds to 
the graphics model provided by Xlib, but does not describe in detail how to 
draw using Xlib; this topic is described in Chapters 5, 6, and 7 of Volume 1, 
Xlib Programming Manual This Chapter also describes how to write action 
routines that work in the widget framework. 

In This Chapter: 

The X Graphics Model Inside Widgets ............................................... 216 
The initialize Method .......................................................................... 216 
Creating GCs ................................................................................. 219 
The expose Method ........................................................................... 221 
The set_values Method ...................................................................... 225 
The resize Method ............................................................................. 227 
The query_geometry Method ............................................................. 230 
The destroy Method ........................................................................... 233 
Actions in the Widget Framework ....................................................... 234 



iiiiiiiii Examp  1. The itialize meod 
......... 
.... 
iiiii! ;! /* ARGSUSED */ 
;iiii!iii.. static void 
i:iiiil ! .... Inltlalize(treq, tnew, args, num_args) 
iiiiiiiii- Widget treq, tnew; 
ilill !;; ArgList args; 
# .... Cardinal *num_args; 
i { BitmapEditWidget new = (BitmapEditWidget) tnew; 
new->bitmapEdit.cur_x = 0; 
new->bitmapEdit.cur_y = 0; 
/* 
* Check instance values set by resources that may be invalid. 
*/ 
if ((new->bitmapEdit.pixmap_width in cells < i) I I 
(new->bitmapEdit.pixmap_height_in_cells < i)) { 
XtWarning("BitmapEdit: pixmapWidth and/or pixmapHeight\ 
is too small (using i0 x i0)."); 
new->bitmapEdit.pixmap_width in cells = i0; 
new->bitmapEdit.pixmap_height_in_cells = i0; 
) 
if (new->bitmapEdit.cell_size_in_pixels < 5) { 
XtWarning("BitmapEdit: cellSize is too small (using 5)."); 
new->bitmapEdit.cell_size_in_pixels = 5; 
) 
if ((new->bitmapEdit.cur x < 0) II 
-- 
(new->bitmapEdit.cur_y < 0)) { 
XtWarning("BitmapEdit: cur_x and cur_y must be\ 
non-negative (using 0, 0)."); 
new->bitmapEdit.cur x = 0; 
new->bitmaPEdit.cur_y = 0; 
) 
/* 
* Allocate memory to store array of cells in bitmap, if not 
* already done by application. 
*/ 
if (new->bitmapEdit.cell == NULL) 
new->bitmapEdit.cell = 
XtCalloc(new->bitmapEdit.pixmap_width in cells 
* new->bitmapEdit.pixmap_height in cells, 
sizeof(char)); 
else 
new->primitive.user_data = True; /* user supplied cell array */ 
/* Calculate useful values */ 
new->bitmapEdit.pixmap_width in pixels = 
new->bitmapEdit.pixmap_width in cells 
* new->bitmapEdit.cell size in pixels; 
new->bitmapEdit.pixmap_height in pixels = 
new->bitmapEdit.pixmap_height_in_cells 
* new->bitmapEdit.cell size in pixels; 
/* 
* Motif Primitive sets width and height to provide enough room 
* for the highlight and shadow around a widget. (This means 

Basic Widget Methods 217 



As you should recall from Chapter 6, Inside a Widget, all the variables set in initial- 
ize are declared in the BitmapEditPart instance structure in the private header file. 
Note that most of the arguments of initialize are rarely used. When initialize is 
called, the request argument is an instance structure containing the same values as new. 
But as new is changed, request provides a sometimes useful record of the resource set- 
tings originally made by the user. The args and num__args arguments contain the 
resource settings provided in the call to XtVaCreateManagedWidget. These are some- 
times useful in distinguishing between settings made by the application (args) from settings 
made by the user (which already appear in new and request). As of R4, the code in the 
initialize hook method, described in Chapter 10, Resource Management and Type 
Conversion, can optionally be placed in the initiali ze method. 

7.2.1 

Creating GCs 

In any widget that does drawing, some of the private instance variables will hold the IDs of 
GCs created in the initialize method. These variables will be read when the GCs are 
needed in the expose method, and will be reset if necessary in the set values method. 
-- 
Example 7-1 called separate routines, GetDrawGC, GetUndrawGC, and GetCopyGC to 
create the GCs. Example 7-2 shows these routines. 
A program prepares for creating a GC by setting the desired characteristics of the GC into 
members of a large structure called XGCValues (defined by Xlib), and specifying which 
members of XGCValues it has provided by setting a bitmask. This bitmask is made by 
ORing the GC mask symbols defined in <Xll/X.h>. Each bitmask symbol represents a mem- 
ber of the XGCValues structure. Every GC field has a default value, so only those values 
that dfer from the default need to be set. The default GC values are discussed in Volume 
One, Xlib Programming Manual. 
Widget code normally creates a GC with the XtGetGC call, not the Xlib analogue 
XCreateGC. XtGetGC keeps track of requests to get GCs by all the widgets in an appli- 
cation, and creates new server GCs only when a widget requests a GC with different values. 
In other words, after the first widget creates a GC with XtGetGC, any subsequent widget 
that calls XtGetGC to create a GC with the same values will get the same GC, not a new 
one. Using this client-side caching also reduces the number of requests to the server. 
Xlib provides XChangeGC to change the values in an existing GC. Xt provides no analo- 
gue. Because of the sharing of GCs allocated with XtGetGC, you must treat them as read- 
only. If you don't, you may confuse or break other widgets. In cases where your widget cre- 
ates a GC that needs changing in such a way that it is impractical to create a new GC each 
time, it may be appropriate to use the Xlib call XCreateGC instead of the Xt call XtGet- 
GC. 
BitmapEdit must use XCreateGC for two of its three GCs bccause these GCs are for draw- 
ing into pixmaps of depth 1, while XtGetGC always creates GCs for drawing into windows 
or pixmaps of the default depth of the screen. In other words, XtGetGC would work on a 
monochrome screen, but not on color. However, this is an unusual situation. Most widgets 
can use XtGetGC exclusively. 

Basic Widget Methods 219 



of Primitive.* The background pixel value is derived from a resource of the Core widget. 
(Core defines a background resource but no foreground.) On the other hand, the 
line_style member of XGCValues is set to LineOnOffDash regardless of resource 
settings. In general, you hardcode the GC components that you don't want to be user cus- 
tomizable. (All these instance variables are defined in the yourwidgetPart structure 
defined in yourwidgetP.h.) 
Certain GC parameters are traditionally handled as resources rather than being hardcoded. 
Colors and fonts are the most basic examples. In the X Window System you can't use a color 
until you allocate a pixel value for it, and you can't use a font until you load it The code that 
processes resources called by XtAppTnitialize automatically allocates and loads the 
colors and fonts specified as resources, and sets the instance variables to the right representa- 
tion type as specified in the resource table. Therefore, it is actually easier to provide user 
customizability than to convert values to the representation types required to hardcode them. 
How the resource conversion process works is described in more detail in 
Chapter 10, Resource Management and Type Conversion. To decide which GC settings you 
need for your application, see Chapter 5, The Graphics Context, in Volume One, Xlib Pro- 
gramming Manual. 

7.3 

The expose Method 

The expose method is responsible for initially drawing into a widget's window and for 
redrawing the window every time a part of the window becomes exposed. This redrawing is 
necessary because the X server does not maintain the contents of windows when they are 
obscured. When a window becomes visible again, it must be redrawn. 

The expose method usually needs to modify its drawing based on the geometry of the win- 
dow and other instance variables set in other methods. For example, the Label widget will 
left-justify, center, or fight-justify its text according to the XmNalignment resource, and 
the actual position to draw the text depends on the widget's current size. The Label widget 
has an instance structure field called alignment, which is set initially in the initial- 
i ze method, and is read in Label's expose method. 

Another factor to consider when writing the expose method is that many widgets also draw 
from action routines, in response to user events. For example, BitmapEdit toggles bitmap 
cells in action routines. The expose method must be capable of redrawing the current state 
of the widget at any time. This means that action routines usually set instance variables 
when they draw so that the expose method can read these instance variables and draw the 
fight thing. 

Most widgets keep track of what they draw in some form of arrays or display lists. When 
they need to redraw, they simply replay the saved drawing commands in the original order to 
redraw the window. For example, BitmapEdit keeps track of the state of each bitmap cell in 

*To work with the Athena widget set, BitmapEdit would have to define its own X t N fo reg r ou nd resource. 

Basic Widget Methods 221 



a character array. It could easily traverse this array and redraw each cell that is set in the 
array. 

However, BitmapEdit does not use this strategy. In order to improve its scrolling perfor- 
mance, the expose method copies an off-screen pixmap into the window whenever 
redisplay is required. The actions draw into this off-screen pixmap (in addition to updating 
the character array), and then call the expose method directly to have the correct portion of 
the pixmap copied to the window. 

The expose method is passed an event that contains the bounding box of the area exposed. 
To achieve maximum performance it copies only this area from the pixmap to the window. 
The BitmapEdit actions take advantage of this, too. They manufacture an artificial event 
containing the bounding box of the cell to be toggled, and pass it when they call expose. 
This causes the expose method to copy that one cell that was just updated to the window. 

Example 7-3 shows the expose method from the BitmapEdit widget. 

Examp 3. The expose meod 
/* ARGSUSED */ 
static void 
Redisplay(w, event) 
Widget cw; 
XExposeEvent *event; 
BitmapEditWidget cw = (BitmapEditWidget) w; 
register int x, y; 
unsigned int width, height; 
if (!XtIsRealized(cw)) 
return; 
if (event) { /* called from btn-event */ 
x = event->x; 
y = event->y; 
width = event->width; 
height = event->height; 
) 
else {/* called because of expose */ 
x = 0; 
y = 0; 
width = cw->bitmapEdit.pixmap_width_in_pixels; 
height = cw->bitmapEdit.pixmap_height in pixels; 
} 
if (DefaultDepthOfScreen(XtScreen(cw)) == i) 
XCopyArea(XtDisplay(cw), cw->bitmapEdit.big_picture, 
XtWindow(cw), cw->bitmapEdit.copy_gc, x + 
cw->bitmapEdit.cur_x, y + cw->bitmapEdit.cur_y, 
width, height, x, y); 
else 
XCopyPlane(XtDisplay(cw), cw->bitmapEdit.big_picture, 
XtWindow(cw), cw->bitmapEdit.copy_gc, x + 
cw->bitmapEdit.cur_x, y + cw->bitmapEdit.cur_y, 
width, height, x, y, i); 

222 X Toolkit Intrinsics Programming Manual, Motif Edition 



widget 2 
expose A 

bounding rectangle 
in merged expose 
event 

region 

expose B 

window 3 
(overlapping window) 

Figure 7-1. compress_exposure: 2 rectangles if XtExposeNoCompress; bounding box and re- 
gion if XtExposeCompressSeries or XtExposeCompressMultiple 

current bitmap into it. When needed in the expose method, this pixmap just has to be 
copied into the window. This approach was chosen for its simplicity. When scrollbars are 
added, the widget is able to pan around in the large bitmap quickly and efficiently. Note that 
one of two Xlib routines is called based on the depth of the screen. This is because XCopy- 
Area is slightly more efficient than xCopyPlane and should be used when running on a 
monochrome screen. 
Note that instance variables are used for the arguments of the Xlib routines in Example 7-3. 
Don't worry about exactly what each Xlib routine does or the meaning of each argument. 
See the reference page for each routine in Volume Two, Xlib Reference Manual, when you 
need to call them in your code. 
See Chapters 5, 6, and 7 in Volume One, Xlib Programming Manual, for more information 
on the GC, drawing graphics, and color, respectively. 

224 X Toolkit Intrinsics Programming Manual, Motif Edition 



7.4 The set values Method 

When the application calls XtVaSetValues (or XtVaSetValues) tO change widget 
resources during run time, Xt calls the set values method. The set values method 
is where a widget responds to changes in its public instance variables. It should validate the 
values of the public variables, and recalculate any private variables that depend on public 
variables that have changed. 

Example 7-4 shows the set_values method for BitmapEdiL 

Examp 4. The set vaes meod 
/* ARGSUSED */ 
static Boolean 
SetValues(current, request, new, args, num_args) 
Widget current, request, new; 
ArgList args; 
Cardinal *num_args; 
{ 
BitmapEditWidget curcw = (BitmapEditWidget) current; 
BitmapEditWidget newcw = (BitmapEditWidget) new; 
Boolean do_redisplay = False; 
if (curcw->primitive.foreground != newcw->primitive.foreground) 
XtReleaseGC(curcw, curcw->bitmapEdit.copy_gc); 
GetCopyGC(newcw); 
do redisplay = True; 
-- 
) 
if ((curcw->bitmapEdit.cur x != newcw->bitmapEdit.cur x) 
(curcw->bitmapEdit?cur_y != newcw->bitmapEdit?cur_y)) 
do redispla = True; 
-- 
if (curcw->bitmapEdit.cell_size_in_pixels != 
newcw->bitmapEdit.cell_size_in_pixels) { 
ChangeCellSize(curcw, newcw->bitmapEdit.cell_size_in_pixels); 
do_redisplay = True; 
) 
if (curcw->bitmapEdit.pixmap_width in cells != 
-- -- 
newcw->bitmapEdit.pixmap_width in cells) { 
newcw->bitmapEdit.pixmap_width_in_elYs = 
curcw->bitmapEdit.pixmap_width_in_cells; 
XtWarning("BitmapEdit: pixmap_width in cells cannot\ 
be set by XtSetValues.\n"); 
} 
if (curcw->bitmapEdit.pixmap_height_in_cells != 
newcw->bitmapEdit.pixmap_height in cells) { 
newcw->bitmapEdit.pixmap_height_in_cells = 
curcw->bitmapEdit.pixmap_height_in_cells; 
XtWarning("BitmapEdit: pixmap_height_in_cells cannot\ 
be set by XtSetValues.\n"); 
) 
return do redisplay; 
-- 

Basic Widget Methods 225 



The resi ze method is passed only one argument, the widget instance structure pointer (of 
type Widget). This structure contains the new position, size, and border width of the 
widget's window. The method changes any instance pan fields that depend on the size or 
position of the widget. When the resize method returns, Xt calls the expose method, 
regardless of whether or not the contents need redrawing. (It is a basic characteristic of the X 
server that it generates Expose events when a window is resized.) 
A Label widget whose text is centered would reset the starting position of its text in the 
resize method. 
In some widgets, it takes some thought to determine the correct response to resizing. Take 
BitmapEdit, for example. BitmapEdit can be configured to show only a portion of the bit- 
map, so that scrollbars can pan around in the complete bitmap. When the application is 
resized, should BitmapEdit show more cells or increase the cell size? Up to the point where 
the entire bitmap is shown, it is easier to increase the number of cells shown. When Bitmap- 
Edit is resized larger than necessary to show the entire bitmap, it should probably increase 
the cell size. We will use this strategy in the resize method of the BitmapEdit widget, 
which is shown in Example 7-5.* 

Examp 5. B#mapEdit: e rese meod 
/* ARGSUSED */ 
static void 
Resize(w) 
Widget w; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
/* resize does nothing unless new 
* size is bigger than entire pixmap */ 
if ((cw->core.width > cw->bitmapEdit.pixmap_width_in_pixels) && 
(cw->core.height > 
cw->bitmapEdit.pixmap_height_in_pixels)) { 
/* Calculate the maximum cell size that will 
* allow the entire bitmap to be displayed. */ 
Dimension w_temp_cell_size in pixels, 
h_temp_cell_size_in_pixels; 
Dimension new_cell_size_in_pixels; 
w_temp_cell_size_in_pixels = cw->core.width / 
cw->bitmapEdit.pixmap_width_in_cells; 
h_temp_cell_size_in_pixels = cw->core.height / 
cw->bitmapEdit.pixmap_height_in_cells; 
if (w_temp_cell_size in pixels < h_temp_cell_size_in_pixels) 
new_cell_size_in_pixels = w__temp_cell_size_in_pixels; 
else 
new_cell_size_in_pixels = h_temp_cell_size_in_pixels; 
/* if size change mandates a new pixmap, make one */ 
if (new cell size_in_pixels 
-- -- 
'= cw->bitmapEdit.cell size in pixels) 
-- 
*This si strategy ds have one problem; it never duces e cell si. This is not a serious problem cause 
BitmapEdit has a source at controls e cell si. The appcafi at uses tiffs widget could provide a user ter- 
hce r setting e ce si ff e appcafion writer was concerned about is problem. 

228 X Toolkit Intrinsics Programming Manual, Motif Editbn 



Example 7-5. BitmapEdit: the resize method (continued) 

ChangeCellSize(cw, new_cell_size_in_pixels); 
static void 
ChangeCellSize(w, new cell size) 
-- -- 
Widget w; 
int new cell size; 
-- -- 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int x, y; 
cw->bitmapEdit.cell_size in pixels = new cell size; 
-- _ 
/* recalculate variables based on cell size */ 
cw->bitmapEdit.pixmap_width_in_pixels = 
cw->bitmapEdit.pixmap_width_in_cells * 
cw->bitmapEdit.cell_size_in_pixels; 
cw->bitmapEdit.pixmap_height_in_pixels = 
cw->bitmapEdit.pixmap_height in cells * 
cw->bitmapEdit.cell_size_in_ixis; 
/* destroy old and create new pixmap of correct size */ 
XFreePixmap(XtDisplay(cw), cw->bitmapEdit.big_picture); 
CreateBigPixmap(cw); 
/* draw lines into new pixmap */ 
DrawIntoBigPixmap(cw); 
/* draw current cell array into pixmap */ 
for (x = O; x < cw->bitmapEdit.pixmap_width_in_cells; x++) { 
for (y = O; y < cw->bitmapEdit.pixmap_height in cells; y++) { 
if (cw->bitmapEdit.cell[x + (y * 
cw->bitmapEdit.pixmap_width_in_cells)] == DRAWN) 
DoCell(cw, x, y, cw->bitmapEdit.draw_gc); 
else 
DoCell(cw, x, y, cw->bitmapEdit.undraw_gc); 

} 
} 
} 

static void 

DoCell(w, x, y, gc) 
Widget w; 
int x, y; 
GC gc; 
BitmapEditWidget cw = (BitmapEditWidget) w; 
/* otherwise, draw or undraw */ 
XFillRectangle(XtDisplay(cw), cw->bitmapEdit.big_picture, gc, 
cw->bitmapEdit.cell_size_in_pixels * x + 2, 
cw->bitmapEdit.cell_size_in_pixels * y + 2, 
(unsigned int)cw->bitmapEdit.cell_size_in_pixels - 3, 
(unsigned int)cw->bitmapEdit.cell size in pixels - 3); 

Basic Widget Methods 229 



Examp  Z B#mapEdit: He que_geomet meod ontinue 
answer->width = (cw->bitmapEdit.pixmap_width in pixels > 
DEFAULTWIDTH) ? DEFAULTWIDTH : 
cw->bitmapEdit.pixmap_width_in_pixels; 
answer->height = (cw->bitmapEdit.pixmap_height_in_pixels > 
DEFAULTHEIGHT) ? DEFAULTHEIGHT : 
cw->bitmapEdit.pixmap_height in pixels; 
if ( ((proposed->request_mode & (CWWidth I CWHeight)) 
== (CWWidth  CWHeight)) && 
proposed->width == answer->width && 
proposed->height == answer->height) 
return XtGeometryYes; 
else if (answer->width == cw->core.width && 
answer->height == cw->core.height) 
return XtGeometryNo; 
else 
return XtGeometryAlmost; 

7.7 The destroy Method 

When a widget is desla'oyed by the application, its destroy methods are invoked in sub- 
class to superclass order. Therefore, the destroy method for any given class needs to free 
only the memory allocated by itself; it need not worry about memory allocated by super- 
classes. 

Any server resources created by Xt (such as GCs requested through XtGetGC) should be 
freed in the destroy method. In addition, if you called any Xlib routines, such as 
XCreateGC, that allocate server- or client-side resources, be sure to free them here. 
BitmapEdit creates pixmaps for use in the drawing process, so it must free them. It must also 
free the GCs it allocated. 

If this is not done, then the server resources allocated for the widget will not be freed until 
the application exits. This is not a fatal problem. It matters only in applications that desoy 
widgets and then continue running for a while before they exit, which is unusual. Example 
7-8 shows the destroy method code from the BitmapEdit widget. It frees the pixmaps 
created in the initialize method shown in Example 7-1. 

Examp 8. The destroy meod 
static void 
Destroy(w) 
Widget w; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
if (cw->bitmapEdit.big_picture) 
XFreePixmap(XtDisplay(cw), cw->bitmapEdit.big_picture); 
if (cw->bitmapEdit.draw_gc) 
XFreeGC(XtDisplay(cw), cw->bitmapEdit.draw_gc); 

Basic Widget Methods 233 



Example 7-8. The destroy method (continued) 
if (cw->bitmapEdit. undraw_gc) 
XFreeGC (XtDisplay (cw), cw->bitmapEdit .undraw_gc) ; 
if (cw->bitmapEdit. copy_gc) 
XtReleaseGC (cw, cw->bitmapEdit, copy_gc) ; 
/* Free memory allocated with Calloc. This was done 
* only if application didn't supply cell array. 
*/ 
if (!cw->primitive.user data) 
-- 
XtFree (cw->bitmapEdit. cell) ; 
) 
If your widget allocated memory for any of its instance variables (or other global variables) 
using the Toolkit routines XtMalloc or XtCalloc (which operate just like the C library 
but add error checking), then it should free that memory here with XtFree. Many widgets, 
including BitmapEdit, allow the application to supply the working memory, or the widgets 
can allocate it themselves. BitmapEdit maintains a flag (user_allocated) to indicate 
who originally allocated the memory. 
If your widget called XtAddEventHandler or XtAddTimeOut, then you should call 
XtRernoveEventHandler and XtRernoveTirneOut, respectively (these routines are 
described in Chapter 9, More Input Techniques). 

7.8 Actions in the Widget Framework 

Although actions, stricdy speaking, are not methods, writing them is part of the process of 
writing a simple widget. Fortunately, you have already seen action routines added from the 
application. Action routines look and work the same in the widget framework as in the appli- 
cation, except that they use instance structure fields as data instead of the application data 
structure fields. Example 7-9 shows the actions of BitmapEdit. 

Examp 9. BitmapEdit: action routines 
/*ARGUSED*/ 
static void 
DrawCell(w, event) 
Widget w; 
XEvent *event; 
String *params; 
Cardinal *num_params; 
BitmapEditWidget cw = (BitmapEditWidget) w; 
DrawPixmaps(cw->bitmapEdit.draw_gc, DRAW, cw, event); 
) 
/*ARGUSED*/ 
static void 
UndrawCell(w, event) 
Widget w; 
XEvent *event; 
String *params; 

234 X Too&# Intrinsics Programming Manual, Motif Edition 



Examp 9. BitmapEdit: action routines (continue 
Cardinal *num_params; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
DrawPixmaps(cw->bitmapEdit.undraw_gc, UNDRAW, cw, event); 
/*ARGUSED*/ 
static void 
ToggleCell(w, event) 
Widget w; 
XEvent *event; 
String *params; 
Cardinal *num_params; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
static int oldx = -i, oldy = -i; 
GC gc; 
int mode; 
int newx, newy; 
/* This is strictly correct, but doesn't 
* seem to be necessary */ 
if (event->type == ButtonPress) { 
newx = (cw->bitmapEdit.cur x + ((XButtonEvent *)event)->x) / 
-- 
cw->bitmapEdit.cell_size_in_pixels; 
newy = (cw->bitmapEdit.cur_y + ((XButtonEvent *)event)->y) / 
cw->bitmapEdit.cell_size_in_pixels; 
} 
else { 
newx = (cw->bitmapEdit.cur x + ((XMotionEvent *)event)->x) / 
-- 
cw->bitmapEdit.cell_size_in_pixels; 
newy = (cw->bitmapEdit.cur_y + ((XMotionEvent *)event)->y) / 
cw->bitmapEdit.cell_size_in_pixels; 
} 

if ((mode = cw->bitmapEdit.cell[newx + newy * 
cw->bitmapEdit.pixmap_width_in_cells]) == DRAWN) { 
gc = cw->bitmapEdit.undraw_gc; 
mode = UNDRAW; 
} 
else { 
gc = cw->bitmapEdit.draw_gc; 
mode = DRAW; 
} 

if (oldx != newx II oldy != newy) { 
oldx = newx; 
oldy = newy; 
DrawPixmaps(gc, mode, cw, event); 
} 

static void 
DrawPixmaps(gc, mode, w, event) 
GC gc; 
int mode; 
Widget w; 

Basic Widget Methods 235 



8 

Events, Translations, 
and Accelerators 

This chapter describes the complete syntax of translation tables, and 
describes a mechanism called accelerators for mapping events in one widget 
to actions in another. Motif mnemonics, which are keyboard shortcuts for 
invoking menu items in visible menus, are also discussed. 

In This Chapter: 

Translation Table Syntax .................................................................... 240 
The Directive ................................................................................. 241 
Selecting the Events to Translate ................................................... 241 
Details in Keyboard Events ............................................................ 244 
Details in Other Event Types .......................................................... 245 
Modifiers ........................................................................................ 247 
Physical Keys Used as Modifiers ................................................. 248 
Default Interpretation of the Modifier List ...................................... 250 
Prohibiting a Modifier ................................................................... 250 
Requiring an Exact Match ............................................................ 251 
Paying Attention to the Case of Keysyms .................................... 251 
Event Sequences .......................................................................... 252 
Special Considerations Involving Motion Events ........................... 253 
Modifiers and Event Sequences ................................................... 253 
Using Modifiers to Specify Button Event Sequences .................... 254 
Key Event Sequences ................................................................. 254 
Interactions Between Translations .................................................. 254 
Translations in Multiple Resource Files ........................................ 255 
Order of Translations ................................................................... 255 
Event Sequences Sharing Initial Events ....................................... 256 
Event Sequences Sharing Noninitial Events ................................. 256 



Accelerators and Mnemonics ............................................................. 257 
Xt Accelerators .............................................................................. 257 
Event Propagation ......................................................................... 259 
Installing Accelerators in Multiple Widgets ...................................... 261 
Defining the Accelerator Table in the Code ..................................... 262 
Motif Accelerators and Mnemonics ................................................ 263 
Mnemonics .................................................................................. 263 
The display_accelerators Method ................................................... 264 



8 
Events, Translations, 
and Accelerators 

Events drive the application. They send a great variety of information from the server to the 
client and from the user to the application. More knowledge of events is necessary both to 
use existing widgets successfully in large applications and to write widgets. 
Events are sufficiently cenu'al to X that we've devoted two chapters in this book to them. 
This chapter provides a closer look at translations and actions; Chapter 9, More Input Tech- 
niques, looks at lower-level event handlers, as well as at other sources of input. Appendix 
C, Event Reference, in Volume Five, X Toolkit Intrinsics Reference Manual, will also be 
useful when you need details about any of the event types. 
The basic concept and use of translations and actions has already been described. But trans- 
lation tables have a complicated syntax which can be used to do much more than the simple 
mappings you have seen up until now. Translation tables can detect user-interface idioms 
such as double- and triple-button clicks or key combinations such as Shift-Meta-M. This 
chapter focuses on the more advanced features of translation tables. 
Next, we discuss a variation of translations called accelerators. Accelerators bind events 
that occur in one widget to actions in another. This is a flexible feature with many uses. One 
common use is to supply a keyboard interface to a normally pointer-driven application. By 
adding accelerators to the top-level window of the application, a keyboard event typed with 
the pointer anywhere in the application can be translated into an action in the correct widget. 
The name "accelerator" comes from the fact that many advanced users find it faster to use 
keyboard shortcuts instead of menus. 
As mentioned in Chapter 3, More Techniques for Using Widgets, it is a very good idea to 
specify translation tables (and accelerator tables, too) in the app-defaults file instead of hard- 
coding them in the application, especially while an application is under development. This 
lets you develop the translations and accelerators without recompiling the application every 
time you want to make a change. 

Events, Translations, and Accelerators 239 



8.1 Translation Table Syntax 

If you are reading this book in sequence, you've already seen translations used many times. 
However, we haven't given a formal description of their syntax or a complete listing of the 
events you can translate. 
A translation table consists of an optional directive, which specifies how the table should be 
merged with any other existing translation tables, followed by a series of production rules, of 
the form: 
Imodifier_list] <event> [, <event> ... ] I (count) ] [detail] : action( I arguments] ) [ action... ] 
where brackets ([ ]) indicate optional elements, an ellipsis (...) indicates repetition, and 
italics indicate substitution of an actual modifier, event, detail, or action name. 
At a minimum, a translation must specify at least one event, specified by a predefined event 
name or abbreviation enclosed in angle brackets; a colon separator; and at least one action. 
However, a sequence of events can be specified; likewise, more than one action can be 
invoked as a result. The scope of event matching can be limited by one or more optional 
modifiers, and, in the case of some events, by a "detail" field that specifies additional infor- 
mation about the event. (For example, for key events the detail field specifies which key has 
been pressed.) Repeated occurrences of the same event (e.g., a double-click) can be specified 
by a count value in parentheses. A colon and optional white space separates the translation 
and the action. 
The examples below are all valid translations: 
<Enter> : dolt () 
<BtnlDown>, <BtnlUp> : doit () 
<BtnlUp> (2) : doit () 
Buttonl<Btn2Down>, <Btn2Up> : doit () 
invoke doitO on a click o/Button 2 while Button I is held down 
Shift<BtnDown> : doit () 
invoke doitO on a click of any button while the shift key is held down 
<Key>y : dolt ( ) invoke doitO when the y key ispressed 
A translation table is a single string, even when composed of multiple translations. If a trans- 
lation table consists of more than one translation, the actual newlines are escaped with a 
backslash (except for the last one), and character newlines are inserted with the \n escape 
sequence, as you've seen demonstrated in examples throughout this book. 
The following sections provide additional detail on each of the elements of an event transla- 
tion. We'll talk first about the directive, followed by event specifiers, details, modifiers, and 
counts. We'll also provide some pointers on the proper sequence of translations, and discuss 
what happens when translations overlap. 

invoke doit 0 on an EnterWindow event 
invoke doitO on a click o/Button 1 
invoke doitO on a double-click of Button I 

240 X Toolkit Intrinsics Programming Manual, Motif Edition 



complete reference to each event type is provided in Appendix C, Event Reference, in Vol- 
ume Five, X Toolkit Intrinsics Reference Manual. 

Table 8-1. Event Type Abbreviations in Translation Tables 

Event Type 

ButtonPress 

ButtonRelease 

KeyPress 

KeyRelease 
MotionNotify 

EnterNotify 

LeaveNotify 

FocusIn 
FocusOut 
KeymapNotify 
Expose 
GraphicsExpose 
NoExpose 
ColormapNotify 
PropertyNotify 
VisibilityNotify 
ResizeRequest 

Abbreviations 

BtnDown 
BtnlDown 
Btn2Down 
Btn3Down 
Btn4Down 
Btn5Down 
BtnUp 
BtnlUp 
Btn2Up 
Btn3Up 
Btn4Up 
Btn5Up 
Key 
KeyDown 
Ctrl 
Meta 
Shift 
KeyUp 
Motion 
PtrMoved 
MouseMoved 
BtnMotion 
BtnlMotion 
Btn2Motion 
Btn3Motion 
Btn4Motion 
Btn5Motion 
Enter 
EnterWindow 
Leave 
LeaveWindow 
FocusIn 
FocusOut 
Keymap 
Expose 
GrExp 
NoExp 
Clrmap 
Prop 
Visible 
ResReq 

Description 

Any pointer button pressed 
Pointer button 1 pressed 
Pointer button 2 pressed 
Pointer button 3 pressed 
Pointer button 4 pressed 
Pointer button 5 pressed 
Any pointer button released 
Pointer button 1 released 
Pointer button 2 released 
Pointer button 3 released 
Pointer button 4 released 
Pointer button 5 released 
Key pressed 
Key pressed 
KeyPress with Clxl modifier 
KeyPress with Meta modifier 
KeyPress with Shift modifier 
Key released 
Pointer moved 
Pointer moved 
Pointer moved 
Pointer moved with any button held down 
Pointer moved with button 1 held down 
Pointer moved with button 2 held down 
Pointer moved with button 3 held down 
Pointer moved with button 4 held down 
Pointer moved with button 5 held down 
Pointer entered window 
Pointer entered window 
Pointer left window 
Pointer left window 
This window is now keyboard focus 
This window lost keyboard focus 
Keyboard mappings changed 
Part of window needs redrawing 
Source of copy unavailable 
Source of copy available 
Window's colormap changed 
Property value changed 
Window has been obscured 
Redirect resize request to window manager 

242 X Toolkit Intrinsics Programming Manual, Motif Edition 



died; Xt gets the current keyboard mapping from the server, v i s ibilityNot i f y events 
are handled automatically if the visible interest field in the Core structure is set to 
True (see Section 9.4.1). 
With the exception of SelectionRequest, the *Request events are intended for use 
only by window managers. The selection events are described in Chapter 11, Interclient 
Communications. 
The keyboard traversal code built into the Motif Primitive class handles W.nterNotify, 
LeaveNotify, FocusIn, and FocusOut events. 
Whether or not they are already handled by Xt or in translations, events can also be selected 
explicitly by installing event handlers in a widget (as described in Chapter 9, More Input 
Techniques). 

Details in Keyboard Events 

As you've seen, Xt provides special event abbreviations to specify which pointer button was 
pressed or released. With key events, this approach would be a little impractical, since there 
are so many keys. Instead, the Translation Manager allows you to follow the event specifica- 
tion with an optional detail field. That is: 
<Key> : doit () 
means that you want the doit () action to be invoked when any key has been pressed, 
while: 
<Key>y : dolt () 
means that you want the doit ( ) action to be invoked only if the y key has been pressed. 
What you actually specify as the detail field of a Key event is a keysym, as defined in the 
header file <Xll/keysymdef.h>.* Keysyms begin with an XK_ prefix, which is omitted when 
they are used in translations. 
Before we explain any further, we need to review X's keyboard model, which, like many 
things in X, is complicated by the design goal of allowing applications to run equally well on 
machines with very different hardware. 
The keyboard generates KeyPress events, and may or may not also generate Key- 
Release events. These events contain a server-dependent code that describes the key 
pressed, called a keycode. Modifier keys, such as Shift and Control, generate events just like 
every other key. In addition, all key events also contain information about which modifier 
keys and pointer buttons were held down at the time the event occurred. 
Xt provides a routine that translates keycode and modifier key information from an event into 
a portable symbolic constant called a keysym. A keysym represents the meaning of the key 
pressed, which is usually the symbol that appears on the cap of the key. For example, when 
the a key is pressed, the keysym is XK_a; when the same key is pressed while the Shift key is 
*Note, however, that this file includes foreign language keysym sets that are not always available. Only the MIS- 
CELLANY, LATIN1 through LATIN4, and GREEK sets are always available. 

244 X Toolkit Intrinsics Programming Manual, Motif Edition 



For these events, you can specify a desired modifier state using one or more of the modifier 
keywords listed in Table 8-5. An error is generated if you specify modifiers with any other 
types of events. 

Table 8-5. Modifiers Used in Translation Tables 

Modifier 

Ctrl 
Shift 
Lock 
Meta 
Hyper 
Super 
Alt 
Modl 
Mod2 
Mod3 
Mod4 
Mod5 
Buttonl 
Button2 
Button3 
Button4 
Button5 

Abbreviation* 

c 
s 
su 
a 

Description 

Control key is held down. 
Shift key is held down. 
Caps Lock is in effect. 
Meta key is held down. 
Hyper key is held down. 
Super key is held down. 
Alt key is held down. 
Modl key is held down. 
Mod2 key is held down. 
Mod3 key is held down. 
Mod4 key is held down. 
Mod5 key is held down. 
Pointer Button 1 is held down. 
Pointer Button 2 is held down. 
Pointer Button 3 is held down. 
Pointer Button 4 is held down. 
Pointer Button 5 is held down. 

8.1.5.1 

Physical Keys Used as Modifiers 

The meaning of the Meta, Hyper, Super, Alt, and Modl through Hod5 keyw0rds may 
differ from server to server. Not every keyboard has keys with these names, and even if 
keysyms are defined for them in <Xll/keysymdef.h>, they may not be available on the physi- 
cal keyboard.-[ 

For example, the file <X11/keysymdef.h> includes the following definitions: 

/* Modifiers */ 

#define XK Shift L 0xFFEI 
_ -- 
#define XK Shift R 0xFFE2 
#define XK--Contrl L 0xFFE3 
-- -- 
#define XK Control R 0xFFE4 
_ -- 

/* Left shift */ 
/* Right shift */ 
/* Left control */ 
/* Right control */ 

*The abbreviations did not work in MIT's R3 sample implementation, but they work in R4. 
#The contents of <X11/keysymdefh> are the same on every machine. What is different is the default mapping of 
keysyms to physical keycodes, which occurs in the server source. The only way to find out the mappings is through 
documentation (which is usually not available) or experimentation (as described in Chapter 11 of Volume Three, X 
Window System User's Guide, Second or Third Edition). 

248 X Toolkit Intrinsics Programming Manual, Motif Edition 



8.2 Accelerators and Mnemonics 

As defined by Xt, accelerators are simply translation tables registered to map event 
sequences in one widget to actions in another. This is a general mechanism, but its name is 
based on a common use--adding keyboard shortcuts for widgets that are normally triggered 
by mouse button presses, such as PushButton widgets--because for advanced users a key- 
board interface is often faster. 

What Motif calls accelerators are implemented using Xt's accelerators, but the two are not at 
all the same. Motif implements a more convenient interface for providing keyboard shortcuts 
in menus, which it calls accelerators, but at the same time disables the more general accelera- 
tors feature in standard Xt. We will begin with a discussion of accelerators as defined by Xt, 
using the Athena widget set in the examples since they will not work in Motif. Then we will 
proceed with how Motif accelerators and mnemonics work. If you are interested only in how 
to program with Motif, then you can skip to Section 8.2.5. 

8.2.1 Xt Accelerators 

Every widget has an xtNaccelerators resource, inherited from the Core widget class. 
This resource contains an accelerator table, which is identical in format to a translation table; 
it maps event sequences to action sequences. Accelerator tables can be set into the xt- 
Naccelerators resource in all the same ways translation tables can. The widget on 
which the XtNaccelerators resource is set is the widget whose actions are to be 
invoked from events in other widgets. 
Once the XtNaccelerator resource of a widget is set, the application must call Xt- 
InstallAccelerators or XtInstallAllAccelerators tO specify which 
widget will be the source of the events to invoke the actions specified in the accelerator table. 
The MIT Intrinsics documentation refers to these two widgets as the source and desti- 
nation. This can be confusing, especially since the arguments are referenced in reverse 
order in the call to XtTntallAccelerator: 
void XtlnstallAccelerators(destination, source) 
Widget destination; 
Widget source; 
Just remember that the source is the widget whose actions you want executed, and the desti- 
nation is the widget you want the events to be gathered in. To understand the use of the 
phrase install accelerators, think of the accelerators as the XtNaccelerators resource 
of the source widget, together with the actions of that widget, and the destinati on as 
the widget to which these actions are transplanted (i.e., "installed"). 
XtIntallAccelerator is always called from the application. (Widgets never 
install accelerators, because by definition they don't know about any other widgets.) In 
applications, accelerators can be installed any time, before or after the widgets are realized. 
Just before the XtAppHainr,oop call is a good place. 

Events, Translations, and Accelerators 257 



As an example, we'll add accelerators to the xboxl application from Chapter 3, More Tech- 
niques for Using Widgets. This application displays two Command widgets in a Box, as 
shown in Figure 8-1. 

Figure 8-1. xboxl: two Command widgets in a Box 

To add accelerators requires a single line of code--a call to XtrnstallAccelerators, 
as shown in Example 8-1. 

Examp 8-1. slling acce  an applicatbn 
main(argc, argv) 
int argc; 
char **argv; 
{ 
XtAppContext app_context; 
Widget topLevel, box, quit; 

/* allow quit widget's actions to be invoked by events in box. */ 
XtInstallAccelerators(box, quit) ; 
XtAppMainLoop (app_context) ; 
} 
The actual value of the accelerator table is set through the resource mechanism. The xt- 
Naccelerators resource is set for the widget whose actions are to be invoked from 
another widget. Xt stores this accelerator table, in compiled form, in the widget's instance 
structure when the widget is created. When the application calls Xtrnstall- 
Accelerators, the accelerator table stored in the widget is merged with the translation 
table of the widget that will be capturing the events. (If XtRemoveAccelerators is 
called, the original translation table, prior to merging with the accelerators from the source 
widget, is restored.) 

258 X Toolkit Intrinsics Programming Manual, Motif Edition 



But consider the resource settings in Example 8-3. 

Example 8-3. Conflicting translations and accelerators 
*quit. label : Quit 
*pressme. label : Press me 
*pressme. translations : #override\n\ 
<KeyPress>p : set() notify() 
*quit. accelerators : \n\ 
<KeyPress>q : set() notify() 
No key event will propagate through a widget that has a translation for any key event. With 
the resource settings in Example 8-3, since pressme has a translation for the p key, the q 
key will not propagate through the widget. Therefore, it is often better to specify all key 
events as accelerators and install them on a common ancestor. 
Accelerators are just merged into translations mthey are not a completely different mecha- 
nism. The #augment (default) or #override directives used in accelerator tables spec- 
ify whether the accelerator should override or augment existing translations for the destina- 
tion widget. For example, if box had a translation of its own that matched the event 
sequence in the accelerator installed on the same widget, whether the translation or the accel- 
erator would be invoked depends on whether #augment (the default) or #override had 
been specified as the accelerator directive. (This example is a little farfetched, since the Box 
widget defines no actions or translations--but it illustrates the point.) 
When using or writing widgets, event propagation is usually important only for accelerators, 
because widgets are rarely layered in such a way that any of the ones that accept input are 
obscured. 

Installing Accelerators in Multiple Widgets 

If you want to install accelerators from more than one widget, you can call XtInstall- 
Accelerators once for every widget whose actions you want executable from the desti- 
nation. Alternatively, you can call xt'rnstallAllAccelerators just once for a 
whole application, specifying the application's top-level window as both the destination and 
the source. XtInstallAllAccelerators recursively traverses the widget tree rooted 
at the source, and installs the accelerators of each widget onto the destination. 

For example, to install accelerators from both the quit and pressme widgets onto box, you 
could replace the call to XtInstallAccelerators shown in Example 8-3 with:* 

Example 8-4. Installing accelerators from both command widgets 
XtInstallAllAccelerators(box, box) ; 

*In a more complex application, where the Box widget was not the main window but only a subarea containing com- 
mand buttons, you might instead use the call: 
XtInstallAllAccelerators(topLevel, box); 
which would make the actions from only the widgets contained in box available from anywhere in the application. 

Events, Translations, and Accelerators 261 



XmCreateSimple*Menu routines. The list contains one element for each button, separa- 
tor, and title created. The mnemonic for a particular button can also be set using the Xm- 
Nmnemonic resource of any kind of button widget. 

Further discussion of mnemonics is provided in the forthcoming Volume Six, X Motif Pro- 
gramming Manual. 

The display_accelerators Method 

Xt calls the source widget's display_accelerators method when the accelerators are 
installed. The purpose of this method is to display to the user the installed accelerators. The 
method is passed a string representation of the accelerator table, which the method can theo- 
retically manipulate into a form understandable by the user. 
All Motif widgets just set this method to NULL. All of the Athena widgets inherit the Core 
widget's display_accelerators method by initializing the appropriate member of 
the class structure to XtInheritDisplayAccelerators. This default method, as 
implemented in the MIT distribution, does nothing. 

264 X Too&# Intrinsics Programming Manual Motif Edition 



9 

More Input Techniques 

This chapter describes how to handle events with event handlers, and how to 
use information from the event structure inside an event handler or action 
routine. It also describes how to get file, pipe or socket input, how to use 
timeouts to call a function after a delay or at particular intervals, and how to 
use work procedures to do background processing. Finally, it discusses 
some low-level features of Xt for directly interacting with the event queue. 

In. This Chapter: 

Event Handlers .................................................................................. 268 
Adding Event Handlers .................................................................. 271 
Adding Nonmaskable Event Handlers ............................................ 272 
Removing Event Handlers ............................................................. 273 
Adding Raw Event Handlers .......................................................... 274 
Writing Routines That Use Specific Event Data .................................. 274 
Event Types and Structure Names ................................................. 276 
File, Pipe, and Socket Input ............................................................... 278 
Getting File Input ........................................................................... 278 
Getting Pipe Input .......................................................................... 280 
Timeouts ........................................................................................... 281 
Visibility Interest ............................................................................. 284 
Work Procedures ............................................................................... 286 
Low-level Management of the Event Queue ....................................... 288 
XtPending and XtPeekEvent .......................................................... 288 
Event Filters .................................................................................. 289 
Input Sensitivity ............................................................................. 290 



9.1 Event Handlers 

An event handler is a function you provide to handle a particular type of event or group of 
event types. You register this function with a call to XtAddEvontHandlor or Xt- 
Insort.vontHandlor, specifying the widget in which the events are to be monitored. 
The difference between these two functions is described below. 
You can later stop the function from being called with XtRoraovoEvontHandlor. On 
any widget, you can register as many event handlers as you want, each for the same or for 
different types of events. When more than one routine is registered for an event, the order in 
which they are invoked is undefined. 
Within Motif applications, event handlers have one common use; they are used to pop up 
Motif popup menus. A popup menu is mapped where the user presses a mouse button in a 
particular widget, usually the application's main window. Since the application's main win- 
dow probably doesn't have an XmNactivateCallback resource, the function that pops 
up the menu can't be registered as a callback. It can be registered as an event handler, how- 
ever, because this requires no prior agreement from the widget. This function could also be 
added as an action from the application, but the required translations could interfere with the 
operation of the main window if it already uses ButtonPress events. Event handlers have the 
advantage that they work in parallel with Xt's other event dispatching mechanisms, and 
therefore they don't interfere. Example 9-1 shows how a typical application uses an event 
handler. The meaning of each argument will be described in a moment. 

Examp 9-1. Usg an event hander  pop up a popup menu 
static void 
PostMenu (w, client_data, event) 
Widget w; 
XtPointer client data; 
-- 
XEvent *event; 
{ 
Widget popup = (Widget) client_data; 
if (event->button != Button3) 
return; 
XmMenuPosition(popup, event); 
XtManageChild (popup) ; 
} 
main(argc, argv) 
int argc; 
char **argv; 
{ 
Widget mainW, Menu; 

Menu = XmCreatePopupMenu(mainW, "popMenu", NULL, 0); 
XtAddEventHandler(mainW, /* events sent to this widget */ 
ButtonPressMask, /* events desired */ 
False, /* non-maskable events */ 

268 X Toolkit Intrinsics Programming Manual Motif Edition 



Table 9-1. Event Masks and Event Types 

Event Mask 

KeyPressMask 
KeyReleaseMask 
ButtonPressMask 
ButtonReleaseMask 
OwnerGrabButtonMask 
KeymapStateMask 
PointerMotionMask 
PointerMotionHintMask 
ButtonMotionMask 
ButtonlMotionMask 
Button2MotionMask 
Button3MotionMask 
Button4MotionMask 
Button5MotionMask 
EnterWindowMask 
LeaveWindowMask 
FocusChangeMask 

ExposureMask 
selecd  OC by 
qraphics_exposecomponent) 
ColormapChanqeMask 
PropertyChangeMask 
VisibilityChangeMask 
ResizeRedirectMask 
StructureNotifyMask 

SubstructureNotifyMask 

SubstructureRedirectMask 

(always selected) 

Event Type 

KeyPress 
KeyRelease 
ButtonPress 
ButtonRelease 
KeymapNotify 
MotionNotify 

EnterNotify 
LeaveNotify 
Focusln 
FocusOut 
Expose 
GraphicsExpose 
NoExpose 
ColormapNotify 
PropertyNotify 
VisibilityNotify 
ResizeRequest 
CirculateNotify 
ConfigureNotify 
DestroyNotify 
GravityNotify 
MapNotify 
ReparentNotify 
UnmapNotify 
CirculateNotify 
ConfigureNotify 
CreateNotify 
DestroyNotify 
GravityNotify 
MapNotify 
ReparentNotify 
UnmapNotify 
CirculateRequest 
ConfigureRequest 
MapRequest 
MappingNotify 

270 X Toolkit Intrinsics Programming Manual Motif Edition 



Table 9-1. Event Masks and Event Types (continued) 

Event Mask 

(always selected) 
(always selected) 
(always selected) 
(always selected) 

Event Type 

ClientMessage 
SelectionClear 
SelectionNotify 
SelectionRequest 

The events that are always selected are called nonmaskable events. These can also be han- 
dled with an event handler, but not by specifying them in the event mask. An argument to the 
XtAddEventHandler call, non_maskable, is a Boolean value that, if True, specifies 
that the event handler should be called for nonmaskable events. This event handler then must 
branch according to which of the seven types of nonmaskable events it is passed. A typical 
nonmaskable event handler is shown in Section 9.1.2. 

9.1.1 

Adding Event Handlers 

Event handlers are added with a call to XtAddEventHandler or XtInsertEvent- 
Handler. XtAddEventHandler takes five arguments: the widget for which the han- 
dler is being added, an event mask, a flag that specifies whether or not this handler is for non- 
maskable events (see below), the name of the handler, and optional client data. Xt- 
InsertEventHandler takes these and one additional argument: the position, either 
XtListTail or XtListHead. 
A list of event handlers-can be registered for the same event; but the same function will 
appear only once in the list with the same client data. If the same function/client 
-- __ 
data pair is registered again with XtAddEventHandler, nothing will happen except 
that the event mask for that function may change. But if the same function/client data 
-- 
pair is registered again with XtInsertEventHandler, the function will be moved to 
the beginning or the end of the function list. 
XtAddEventHandler or XtInsertEventHandler may be called before or after a 
widget is realized. In application code, this means the call can appear anywhere before Xt- 
AppMainLoop. In a widget, XtAddEventHandler or XtInsertEventHandler 
calls are placed in the initialize or realize methods. 
Example 9-2 shows the code from xterm that registers an event handler for FocusIn and 
FocusOut events, and a gutted version of the event handler itself. 

Example 9-2. Registering an event handler, and the handler function itself 
extern void HandleFocusChange() ; 

static void VTInitialize (request, new) 
XtermWidget request, new; 
l 

More Input Techniques 271 



cur. MappingNotify is automatically handled by Xt, so it isn't passed to event handlers 
and you don't need to worry about it. The selection events are described in Chapter 11, In- 
terclient Communications. 
Because there are several nonmaskable event types, a nonmaskable event handler must be 
sure to branch according to the type of event, and throw away any event types not handled. 
You need not have all the code to handle all the types in a single event handler. Instead, you 
can handle each type in a separate handler, each registered separately. However, each han- 
dler would still need to check the event type because the entire list of them would be called 
for every nonmaskable event. 
Example 9-3 shows the registration of a nonmaskable event handler and the handler itself, 
from xman. 

Examp 9-3. Adding a nonmaskab event handler 
static void 
Realize(w, valueMask, attributes) 
register Widget w; 
Mask *valueMask; 
XSetWindowAttributes *attributes; 
l 

XtAddEventHandler(w, 0, True, 
GExpose, NULL); /* Get Graphics Exposures */ 
} /* Realize */ 
/* ARGSUSED */ 
static void 
GExpose(w, client_ata, event) 
Widget w; 
XtPointer client data; 
-- 
XEvent *event; 
l 
if (event->type == GraphicsExpose) 
Redisplay(w, event, NULL); /*call the expose method directly*/ 
) 
This event handler is sometimes used because Xt does not normally call the expose meod 
in response to GraphicsExpose evenS. But in R4, another way to accomplish ts has 
been inoduced. If the compress_exposure field in the Core structure is set to (Xt- 
ExposeCompressMultiple I XtExposeGraphicsExpose), Xt will call the 
expose meod wi these evenS. 

Removing Event Handlers 

XtRemoveEventHandler hakes He me argumenS as XtAddEventHandler; if 
there are parameter mismatches, the call is quietly ignored. For example, the client data ar- 
gument may be used to distinguish between different event handlers; if the client data argu- 
ment does not match that which was passed in the XtAddEventHandler, then Xt- 

More Input Techniques 273 



Many action routines are intentionally written not to depend on the detailed information in- 
side any particular type of event, so that the user can specify translations to call the action in 
response to different types of events. For example, it is useful for an action routine normal- 
ly triggered by a pointer click to work when called in response to a key instead. Such an ac- 
tion should not depend on the event structure fields unique to button events. 

However, many other action routines, and most event handlers, do use the detailed informa- 
tion inside event structures. The first member, type, identifies which type of event this 
structure represents, and hence implies which other fields are present in the structure. 

To access event structure fields other than type you need to cast XEvent into the appropri- 
ate event structure type. If you are expecting only one type of event to trigger this action, 
then you can simply declare the argument as the appropriate type, as shown in Example 9-4. 

!ii!iiiiii Example 9-4. Casting the event structure by declaring action routine arguments 
i!iiii / * ARGSU SED * / 
: static void 
ActionA(w, event, params, num_params) 
Widget w; 
XEvent *event; 
: String *params; 
Cardinal *num_params; 
if ((event->type != ButtonPress) && (event->type != KeyPress)) 
-- XtWarning("ActionA invoked by wrong event type."); 
iiii! /* possible exit here */ 

) 
When an action routine or event handler depends on the fields in a particular event structure, 
it is a good practice to check the event type in that action unless you are sure that the user 
can't change the translation (and thus the events used to invoke the action). 
If you want the same code called for two event types, then you would do better to create two 
separate translations and two separate actions that each call a common routine. However, it 
is sometimes more convenient to have an action called by two different events. Example 9-5 
shows the ToggleCell action from the BitmapEdit widget, which is called in response to 
either MotionNotify or ButtonPress events. This action inverts a pixel in the bit- 
map either if the pointer is clicked on a cell in the widget, or if it is dragged across the cell 
with the pointer buttons held down. 

Example 9-5. Handling multiple event types in an action routine 
static void 
ToggleCell(w, event) 
Widget w; 
XEvent *event; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
static int oldx = -i, oldy = -I; 
GC gc; 
int mode; 

More Input Techniques 275 



Examp 9-5. Handling multip event pes  an action routine Continued) 
int newx, newy; 
if (event->type == ButtonPress) { 
newx = (w->bitmapEdit.cur x + ((XButtonEvent *)event)->x) / 
-- 
w->bitmapEdit.cell_size_in_pixels; 
newy = (w->bitmapEdit.cur_y + ((XButtonEvent *)event)->y) / 
w->bitmapEdit.cell_size_in_pixels; 
) 
else if (event->type == MotionNotify) { 
newx = (w->bitmapEdit.cur x + ((XMotionEvent *)event)->x) / 
-- 
w->bitmapEdit.cell_size_in_pixels; 
newy = (w->bitmapEdit.cur_y + ((XMotionEvent *)event)->y) / 
w->bitmapEdit.cell_size_in_pixels; 
) 
else 
XtWarning("BitmapEdit: ToggleCell called with wrong event\ 
type\n"); 

} 
Notice that some code is repeated to cast the event structure to the two different event types. 
With the current MIT implementation of Xlib, the positions of the x and y fields in the 
XButtonEvent and XMotionEvent structures are the same, and therefore this casting 
is unnecessary on many compilers. However, for strict ANSI C conformance these casts are 
necessary, and furthermore it is improper to depend on any particular implementation of 
Xlib. The order of the fields in one of these events could be different in some vendor's im- 
plementation of Xlib. 

9.2.1 

Event Types and Structure Names 

Table 9-2 lists the event types and the matching event structure types. The event descriptions 
in the table will give you a general idea of what each event is for. Many of these events are 
not often used in applications, and more of them are automatically handled by Xt. We've al- 
ready discussed how to use the most common event types and thei abbreviations in transla- 
tion tables in Chapter 8, Events, Translations, and Accelerators. Appendix C, Event Refer- 
ence, in Volume Five, X Toolkit lntrinsics Reference Manual, provides a complete reference 
to the circumstances under which each event is generated, what it is for, and the fields in each 
of the event structures. You will need this information to write action routines that use event- 
specific data. 

276 X Toolkit Intrinsics Programming Manual, Motif Edition 



Table 9-2. Event Types and Event Structures 

Event Type 

KeyPress 
KeyRelease 
ButtonPress 
ButtonRelease 
KeymapNotify 
MotionNotify 
EnterNotify 
LeaveNotify 
FocusIn 
FocusOut 
Expose 
GraphicsExpose 
NoExpose 
ColormapNotify 
PropertyNotify 
VisibilityNotify 
ResizeReguest 

CirculateNotify 
ConfigureNotify 
DestroyNotify 
GravityNotify 

MapNotify 
ReparentNotify 
UnmapNotify 
CirculateRequest 

ConfigureRequest 

MapRequest 

MappingNotify 
ClientMessage 
SelectionClear 
SelectionNotify 
SelectionRequest 

S tructure 

XKeyPressedEvent 
XKeyReleasedEvent 
XButtonPressedEvent 
XButtonReleasedEvent 
XKeymapEvent 
XPointerMovedEvent 
XEnterWindowEvent 
XLeaveWindowEvent 
XFocusInEvent 
XFocusOutEvent 
XExposeEvent 
XGraphicsExposeEvent 
XNoExposeEvent 
XColormapEvent 
XPropertyEvent 
XVisibilityEvent 
XResizeRequestEvent 

XCirculateEvent 
XConfigureEvent 
XDestroyWindowEvent 
XGravityEvent 

.XMapEvent 
XReparentEvent 
XUnmapEvent 
XCirculateRequestEvent 

XConfigureRequestEvent 

XMapRequestEvent 

XMappingEvent 
XClientMessageEvent 
XSetSelectClearEvent 
XSelectionEvent 
XSelectionRequestEvent 

Description 

Key pressed. 
Key released. 
Pointer button pressed. 
Pointer button released. 
State of all keys when pointer entered. 
Pointer motion. 
Pointer entered window. 
Pointer left window. 
This window is now keyboard focus. 
This window was keyboard focus. 
Part of window needs redrawing. 
Source of copy unavailable. 
Source of copy available. 
Window's colormap changed. 
Property value changed. 
Window has been obscured. 
Redirect resize request to window 
manager. 
Stacking order modified. 
Window rcsizcd or moved. 
Window destroyed. 
Window moved due to win gravity at- 
tribute. 
Window mapped. 
Window reparented. 
Window unmapped. 
Redirect stacking order change to 
window manager. 
Redirect move or resize request to 
window manager. 
Redirect window map request to win- 
dow manager. 
Keyboard mapping changed. 
Client-dependent. 
Current owner is losing selection. 
Selection is ready for requestor. 
Request for selection to current owner. 

More Input Techniques 277 



9.3 File, Pipe, and Socket Input 

XtAppAddInput allows a program to obtain input from a file. This is not merely reading 
the file once, but monitoring it for further activity. Under UNIX this can be used to get input 
from pipes and sockets, since they are variations of files. We will demonslrate getting file 
and pipe input in this section. 
The XtAppAddInput routine takes four arguments: a file descriptor, a flag (see below), 
your function, and c2 i en t da t a. 
XtAppAddInput returns an ID that uniquely identifies the XtAppAddInput request. 
You can use the ID to cancel the request later with XtReraoveInput. 
One argument of XtAppAddInput is a file descriptor (this file must be open before calling 
XtAppAddInput). Since implementation of files varies between operating systems, the 
actual contents of the parameter passed as the file descriptor argument to these routines is 
operating system-dependent. Therefore, this code is inherently nonportable. 
Possible values for the mask and their meanings are as shown in Table 9-3. 

Table 9-3. Other Input Source Masks 

Mask 

XtInputReadMask 
XtInputWriteMask 
XtInputExceptMask 
XtInputNoneMask 

Description 

File descriptor has data available. 
File descriptor available for writing. 
I/O errors have occurred (exceptions). 
Never call function registered. 

Calling these argument values masks is something of a misnomer, since they cannot be ORed 
together. However, you can call XtAppAddInput additional times to register a separate 
function (or the same function) for each of these masks on the same file descriptor. 

9.3.1 

Getting File Input 

In Example 9-6, a program called xJileinput reads new characters from a file whenever they 
appear. In other words, the program will initially print to the standard output the contents of 
the file specified on the command line, and it will print any characters that are later appended 
to that file. Try the program x]ileinput as follows: 
echo "test string" > testfile 
xfileinput test file & 
echo "more text" >> testfile 
A program such as this functions similarly to the UNIX command tail -f. It could be used to 
monitor system log files, or other similar files that grow. 

278 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 9-6. Getting file input with XtAppAddlnput (continued) 
XtAppAddInput (app_context, fileno(fid), XtInputReadMask, 
get_file_input, NULL) ; 
XtRealizeWidget (topLevel) ; 
XtAppMa inLoop (app_context) ; 
} 
The function registered with XtAppAddInput is called with client data (used for 
passing in any application data), a pointer to the file descriptor, and the ID of the XtApp- 
AddInput request. You can use a call to XtRemoveInput in the function registered 
with XtAppAddInput if that function is only to be called once. One argument of the Xt- 
Remove I nput call is the ID of the XtAppAddI nput requesL 
Under some operating systems, the function registered with XtAppAddInput is called 
very frequently even when no new input is available. This is because Xt makes a system call 
to detect whether the file is "ready for reading," and some operating systems say the file is 
ready even when there is nothing new to read. The example shown above works, but it loads 
down the system much more than necessary. You may wish to check the file every quarter 
second instead of continuously, by adding and removing your input handler periodically us- 
ing timeouts (as described in Section 9.4). The same goes for input from a pipe. 

Getting Pipe Input 

The code to get pipe input is almost identical to the code just shown that gets file input. The 
only difference is that we use popen instead offopen, and change the various error messages. 
Now instead of treating the command-line argument as a filename, it is treated as a program 
run under a shell. This program's output is piped into our application. For example, here is 
an example of how to invoke this version ofxpipeinput: 
spike% xpipeinput "cal ii 1989" 
November 1989 
S M Tu W Th F S 
1 2 3 4 
5 6 7 8 9 i0 ii 
12 13 14 15 16 17 18 
19 20 21 22 23 24 25 
26 27 28 29 30 
(Program continues to monitor pipe for further input until application exits.) 
Note that xpipeinput is reading the string "cal 11 1989" from the command line, invoking a 
shell, running the command specified by the string under this shell, reading the output of the 
shell, and then printing it on the standard output. This is an easy way to use all kinds of shell 
scripts and utilities from within a program. 
If you want your application to accept standard input, this is even easier. Remove the code 
that reads the filename from the command line and remove the popen call to open the pipe, 
since the pipe from stalin is always open. Then use the XtAppAddInput function as 
shown in Example 9-7. 

280 X Toolkit Intrinsics Programming Manual, Motif Edition 



mmmm 

mmm mmmm 

Figure 9-1. xtetris in play 

Every time a row is completely filled, it is removed and all the blocks above it move down 
one row. The window in which the blocks fall is a specialized widget. This game uses 
timeouts to time the falling of the blocks. 
Example 9-8 is an excerpt from a widget used by xtetris that adds the timeout. The timeout 
function itself is also shown. 

282 X Toolkit Intrinsics Programming Manual Motif Edition 



Example 9-9. xtetris: calling XtRemoveTimeOut 
/*ARGSUSED*/ 
static void 
Drop(tw, tevent, params, num_params) 
Widget tw; 
XEvent *tevent ; 
String *params; 
Cardinal *num_params; 
TetrisWidget w = (TetrisWidget) tw; 
XButtonEvent *event = (XButtonEvent *) tevent; 
XtRemoveTimeOut (timer) ; 
while (CanMoveDown(w)) ( 
DrawBlock(w, UNDRAW); 
w->t et r is. cur_y++ ; 
DrawBlock(w, DRAW) ; 
CopyBlock (w) ; 
} 
UpdateCellArray (w) ; 
KillRows (w) ; 
score++; 
Score (w) ; 
w->tetris.delay -= 5; 
StartBlock (w) ; 
) 
Notice that the timer ID returned from the calls to XtAppAddTimeOut is a global vat- 
able. Xt calls the timeout function with only one argument, and that argument passes in the 
widget instance pointer. We could have created a structure containing the widget instance 
pointer and the timer ID and passed its pointer to the timeout function. But this wouldn't 
help, because the action routine in which we remove the timeout is passed with no 
client data argument. (It has string parameters, but these are hardcoded in the actions 
-- 
table.) Therefore, we are forced to have a global variable for the timer ID. 
Note that between the time when the timeout is registered and when it triggers, the applica- 
tion processes events in XtAppMainLoop. Therefore, all the widget's actions and ex- 
pose method are in operation between the invocations of the timeout function. 

9.4.1 

Visibility Interest 

Timeouts operate regardless of the visibility of the application. Since it is pointless for most 
games to continue operating while obscured, it makes sense to remove the game's timeouts 
when the game is partially or fully obscured (or iconified). To do this, you can set the vi s- 
ible interest field in the Core class structure to True, and then check the visible 
-- 
field of the Core instance structure periodically. When the application is fully obscured, you 
add a separate timeout to continue testing the visibility status. When the visibility status is 
satisfactory once again, the game can add its timeout again. All these changes are in the 
widget's .c file. First we set the visible_interest field to True in the Core structure: 

284 X Too&# Intrinsics Programming Manual, Motif Edition 



TetrisClassRec tetrisClassRec 
/* core class fields */ 
-- 

= { 

/* visible interest 

*/ True, 

l 
Second we change: 
timer = XtAppAddTimeOut(XtWidgetToApplicationContext 
(w), w->tetris.delay, MoveDown, w); 

to: 

if (w->core.visible == False) 
timer = XtAppAddTimeOut (XtWidgetToApplicationContext 
(w) 250, CheckVisibility, w); 
else 
timer = XtAppAddTimeOut (XtWidgetToApplicationContext 
(w) 
w->tetris.delay, MoveDown, w) ; 
And finally, we add the timeout function that continues to check the visibility status. 
static void 
CheckVisibility (w) 
BitmapEditWidget w; /* client data */ 
-- 
{ 
if (w->core.visible == False) 
timer = XtAppAddTimeOut(250, CheckVisibility, w) ; 
else 
timer = XtAppAddTimeOut(w->tetris.delay, 
MoveDown, w) ; 
l 
Unfortunately, the Core visible field is True even if a tiny sliver of the widget is visible. 
The only way to get around this is to add an event handler (or translation) for 
VisibilityNotify events and to add an instance variable to maintain the visibility 
state. The event handler or action would check the state field of the event, and put the 
game into hibernation if the window is only partially obscured. However, this approach has 
the opposite problem; it disables the game even when only a sliver is obscured. 
There is nothing you can do about the game continuing to run while being moved or resized 
with the window manager. However, using the Core visible_interest field does stop 
the game when it is iconified. 

More Input Techniques 285 



The client_data argument passes application data into the work procedure It is used 
just like the same argument in callback functions. Example 9-11 shows a work procedure to 
create a popup widget. 

Examp 9-11. A woprocedu  ca apopupwidget 
Widget getHelp; 
/* work procedure */ 
Boolean 
create_popup(client data) 
XtPointer client data; 
Widget parent = (Widget) client data; 
Widget helpBox; 
Widget temp; 
helpBox = XmCreateMessageDialog(parent, "message", NULL, 0); 
temp = XmMessageBoxGetChild (helpBox, XmDIALOG CANCEL BUTTON); 
XtUnmanageChild (temp); 
temp = XmMessageBoxGetChild (helpBox, XmDIALOG HELP BUTTON); 
XtUnmanageChild (temp); 
/* arrange for getHelp button to pop up helpBox */ 
XtAddCallback(getHelp, XmNactivateCallback, PopupDialog, helpBox); 
return(True); /* makes Xt remove this work proc automatically */ 

Remember that Xt cannot interrupt a work procedure while it is running; the procedure must 
voluntarily give up control by returning, and it must do so quickly to avoid slowing uscr re- 
sponseo 
If your application has any big jobs that it must do, the only way to do them without resulting 
in long delays is to write the code that does the big job in a way that voluntarily interrupts it- 
self and saves its state so that it can be restarted where it left off. One way to run such a task 
is as a work procedure, but this is only useful for tasks that need not be done before other ap- 
plication tasks can begin. If you want Expose processing to continue but no other applica- 
tion task to begin until your task is done, you would use the same type of code but place low- 
level event management routines in it, or make the rest of the application insensitive until the 
task is done. 

More Input Techniques 287 



9.6 Low-level Management of the Event Queue 

As you know, an X Toolkit application simply calls XtAppMainLoop tO begin processing 
events. XtAppMainLoop itself is quite simple: it consists of an infinite loop calling two 
lower-level routines, XtAppNextEvent and XtDispatchEvent. XtAppNext- 
Event extracts the next event from the application's event queue; XtDispatchEvent 
actually uses the event to invoke the appropriate actions or event handlers. (The functions 
registered by XtAppAddInput and XtAppAddTimeOut are dispatched directly by Xt- 
AppNextEvent; if no events are available, XtAppNextEvent flushes the X output buf- 
fer, and calls any work procedures registered by XtAppAddWorkP roe.) 

An application can provide its own version of this loop, as shown in Example 9-12. For ex- 
ample, it might test some application-dependent global flag or other termination condition 
before looping back and calling XtAppNextEvent. Or for fine-grained debugging, it 
might be worthwhile to insert a routine that prints out the type of each event dispatched. 

Example 9-12. Skeleton of a custom main loop 
void MyMainLoop (app_con) 
XtAppContext app_con; 
( 
XEvent event; 
for (;;) { 
XtAppNextEvent (app_con, &event) ; 
XtDispatchEvent (&event) ; 
/* Do application-specific processing here */ 
} 
} 

9.6.1 

XtPending and XtPeekEvent 

All event sources depend on idle time in the application to return to XtAppMainLoop 
where Xt can check to see if input is available from any of the various sources. If an applica- 
tion has long calculations to make, the program may not return to XtAppMainLoop fre- 
quently enough to detect important input in a timely fashion. The application itself should, if 
possible, suspend lengthy calculations for a moment to check whether input is available. 
Then it can determine whether to process the input before continuing, or finish the calcula- 
tion. 
To detect whether input from any input source is available, you can call XtPending. This 
function returns a mask composed of a bitwise OR of the symbolic constants xt TMXV.vent, 
XtIMTimer, and XtIMAlternateInput. These constants refer to X events, timer 
events, and alternate input events, respectively. 
To find out what the first event in the queue contains, you can call XtPeekEvent. This 
function returns an event structure without removing the event from Xlib's queue. 

288 X Too&# Intrinsics Programming Manual, Motif Edition 



10 

Resource Management 
and Type Conversion 

This chapter is a more thorough discussion of how resources work and how 
they should be used. This chapter describes in detail the resource file format 
and the rules that govern the precedence of resource settings. It also 
describes how to add your own type converter so that you can have applica- 
tion or widget-specific data set through resources. Finally, it describes 
subresources and how to use them. 

In This Chapter: 

Review of Resource Fundamentals .................................................... 294 
How the Resource Database Works ................................................... 297 
Form of Resource Specifications ................................................... 298 
Merging of Resource Files ............................................................. 300 
The Language String ..................................................................... 302 
Fallback Resources ....................................................................... 304 
Resource Matching Algorithm ........................................................ 305 
Resource Precedence Rules .......................................................... 307 
Type Conversion ................................................................................ 311 
Conversions from XmRString ......................................................... 311 
Other Built-in Type Conversions ..................................................... 313 
Special Resource Defaults That Do Not Use Conversion ............... 314 
Registering Type Converters .......................................................... 316 
Passing Arguments to a Type Converter ...................................... 319 
Explicitly Invoking a Converter ....................................................... 321 
Writing a Type Converter ................................................................ 323 
Defining the Default Value ............................................................ 324 
Subparts and Subresources ............................................................... 325 
The Hook Methods ........................................................................ 325 
Managing Subresources ................................................................ 326 



10 
Resource Management 
and Type Conversion 

This chapter provides a thorough discussion of how resources work and how they should be 
used. First, we describe how to define resources, the complete syntax of resource files, and 
the rules that describe the precedence of one resource setting over another. For the sake of 
completeness, and to make sure that the ideas are presented in context, there is some repeti- 
tion of material that has been presented earlier. 
Next, the chapter describes the resource conversions performed automatically by Xt. As you 
may recall from the discussion in Chapter 2, Introduction to the X Toolkit and Motif, a value 
converter is invoked by Xt to convert a resource from the string form specified in resource 
files to the representation type actually used in the application or widget. For the representa- 
tion types understood by Xt, simply listing the representation symbol (a constant beginning 
with Xrn_R, or X: R in standard Xt) in the resource list is enough to make Xt automatically per- 
form the conversion. But if you create a representation type unknown to Xt, you need to 
write a type converter routine and register it with Xt before the automatic conversion can 
take place. We discuss both the standard converters and how to write a new one. 
Finally, the chapter describes a mechanism Xt provides whereby widgets or applications may 
have subparts with separate sets of resources. Special routines are provided for setting and 
getting these resources. The R3 Athena Text widget used subparts to implement replaceable 
units that provide the data storage and display for text data. This allowed the same central 
code to edit a disk file or a string. But using subparts is now out of favor; the R4 Text widget 
and the Motif Text widgets now use objects to accomplish the same modularity (see 
Chapter 14, Miscellaneous Toolkit Programming Techniques). 

Resource Management and Type Conversion 293 



10.1 Review of Resource Fundamentals 

As we've previously discussed, widgets and applications can declare some or all of their 
variables as resources. Not every variable need be a resource--only those for which values 
need to be supplied by the user (or for a widget, also by the application programmer) through 
the Resource Manager. Both applications and widgets may use nonresource variables for 
internal bookkeeping, or for storing values calculated or otherwise derived from resources. 
Resources are defined using an xtResource structure, which is declared as follows: 

typedef struct { 
String resource name; 
-- 
String resource class; 
-- 
String resource_type; 
Cardinal resource size; 
-- 
Cardinal resource offset; 
-- 

/* specify using XmN symbol */ 
/* specify using XmC symbol */ 
/* actual data type of variable */ 
/* specify using sizeof() */ 
/* specify using XtOffsetOf() */ 

String default_type; /* will be converted to resrce_type */ 
XtPointer default address; /* address of default value */ 
-- 
} XtResource, *XtResourceList; 

For example, Example 10-1 shows three of thc resources defined by the Primitive widget: 

Examp 10-1. Threeresourcesdefinedbye MoPrimive widget 
static XtResource resources[] = { 

{ 
XmNforeground, /* Resource name is foreground */ 
XmCForeground, /* Resource class is Foreground */ 
XmRPixel, /* Resource type is Pixel */ 
sizeof(Pixel), /* allocate enough space to hold a Pixel value */ 
XtOffsetOf(XmPrimitiveRec, 
primitive.foreground), /* where in instance strct */ 
XmRCallProc, /* type of default value */ 
_XmForegroundColorDefault /* Address of deflt value, or function */ 
}, 

{ 
XmNhighlightColor, 
XmCHighlightColor, 
XmRPixel, 
sizeof (Pixel), 
XtOffsetOf (XmPrimitiveRec, primitive.highlight_color), 
XmRString, 
"Black" 
}, 

{ 
XmNtraversalOn, 
XmCTraversalOn, 

294 X Toolkit Intrinsics Programming Manual, Motif Edition 



*Background: offwhite 
*Foreground: darkblue 

The representation type of the resource is specified by the resource_type field of the 
resource list, using a symbolic constant prefixed by XmR. Table 10-1 lists the correspon- 
dence between the XmR symbols defined by Xt, and actual C data types or X data types 
and structures. 

Table 10-1. Resource Type Strings 
Resource Type Data type 
XmRAcceleratorTable XtAccelerators 

XmRAtom 
XmRBitmap 
XmRBoolean 
XmRBool 
XmRCallback 
XmRCallProc 

Atom 
Pixmap (ofdep one) 
Boolean 
Bool 
XtCallbackList 
see nal built bew 

XmRCardinal 
XmRColor 
XmRColormap 
XmRCursor 
XmRDimension 
XmRDisplay 
XmREnum 
XmRFile 
XmRFloat 
XmRFont 
XmRFontStruct 
XmRFunction 
XmRGeometry 

XmRImmediate 
XmRInitialState 
XmRInt 
XmRLongBoolean 
XmRObject 
XmRPixel 
XmRPixmap 
XmRPointer 
XmRPosition 
XmRScreen 
XmRShort 
XmRString 
XmRStringArray 
XmRStringTable 
XmRTranslationTable 

Cardinal 
XColor 
Colormap 
Cursor 
Dimension 
Display * 
XtEnum 
FILE * 
float 
Font 
XFontStruct * 
(*) () 
String - rmat as defined by 
XParseGeometry 
see nal bullet bew 
int 
int 
long 
Object 
Pixel 
Pixmap 
XtPointer 
Position 
Screen * 
short 
char * 
String * 
char ** 
XtTranslations 

296 X Toolkit Intrinsics Programming Manual, Motif Edition 



Table 10-1. Resource Type Strings (continued) 

Resource Type 

XmRUnsignedChar 
XmRVisual 
XmRWidget 
XmRWidgetClass 
XmRWidgetList 
XmRWindow 

Data type 

unsigned char 
Visual * 
Widget 
WidgetClass 
WidgetList 
Window 

As we'll discuss in detail in Section 10.3.5, Xt automatically converts values in the 
resource database (which always have the type XmRString, since resource files are 
made up entirely of strings) into the target type defined by resource_type. 
The resource_size field is the size of the resource's actual representation in bytes; 
it should always be specified as sizeof (type) (where type is the C-Language type 
of the resource) so that the compiler fills in the value. 
The resource_offset field is the offset in bytes of the field within the widget 
instance structure or application data structure. The xtOffsetOf macro is normally 
used to obtain this value. This macro takes as arguments the data structure type, and the 
name of the structure field to be set by the resource. 
If no value is found in the resource database, the value pointed to by the 
default_address field will be used instead. The type of this default value is given 
by the default_type field. If the default_type is different from the 
resource_type, a conversion will be performed automatically in this case as well. 
There are two special resource types that can be used only as the default_type. 
XmRImmediate means that the value in the default address field is to be used 
-- 
as the actual resource value, rather than as a pointer to it (or in the case of a string, the 
value is a pointer to a string, rather than a pointer to a pointer to a string). The other spe- 
cial resource type, XmRCallProc, is a pointer to a function that will supply the default 
value at run time. We'll demonstrate the use of these values in Section 10.3.3. 

10.2 How the Resource Database Works 

Xt's resource handling is based on the resource manager built into Xlib, but Xt adds a great 
deal. While using the resource manager from Xlib is cumbersome, from Xt it is easy: to use 
resources in existing widgets, all you have to do is write the app-defaults file. 

Xt's handling of resources occurs in two stages: 

1. When the application starts up, with a call to XtAppTnitialize, Xt reads the app- 
defaults file, along with several other resource files, command-line options, and the 
RESOURCE_MANAGER property stored in the server by the user with xrdb. (Any, all, or 

Resource Management and Type Conversion 297 



10.2.2 Merging of Resource Files 

XtAppInitialize constructs the resource database by consulting the following sources 
of resource settings, in this order: 
1. A file usually in the directory /usr/lib/Xll/LANG/app-defaults (implementation depen- 
den0 on the machine running the client, where LANG is an optional language string (see 
Section 10.2.3 for details). This file is commonly called the app-defaults file, named after 
the directory containing it. It is intended to be written by the application developer. The 
name of this file is the application class (specified in the XtAppInitialize call), 
usually the same as the application name except with the first letter capitalized. If the 
application name begins with x, then the first two letters are capitalized. (This latter con- 
vention is not always followed.) The installation procedure for the application should 
install this file in the correct directory (or one per language, each in a different directory). 
2. A file in the directory named by the shell environment variable XUSERFILE- 
SEARCHPATH, or XAPPLRESDIR with LANG optionally appended (see Section 10.2.3). 
The filename searched for is the class name of the application. If XAPPLRESDIR is not 
set, the file is looked for in the user's home directory. This file is intended to be the 
user's, or possibly the site administrator's, customization for the particular application. 
The application developer can also set XAPPLRESDIR so that resource files for an appli- 
cation can be in the same directory as the application. (This is particularly useful when 
debugging the app-defaults file.) Note that the value of this variable must end with a 
slash (/).* 
3. Resources loaded into the RESOURCE_MANAGER property of the root window by xrdb. 
Unlike any of the resource files, these resources are accessible regardless of the machine 
on which the client is running. Therefore, xrdb saves you from having to keep track of 
resource files on several differcnt systems. Typically, the user arranges to have xrdb run 
automatically from .xinitrc or its equivalent under xdm, the display manager. This is 
intended to be the method whercby the user specifies server-wide resources (to apply to 
all clients no matter which system they are running on). 
If the RESOURCE_MANAGER property is not set, the resource manager looks for an 
.Xdefaults file in the user's home directory. Support for .Xdefaults is mostly for compati- 
bility with earlier releases of X. (See Volume Three, X Window System User's Guide, 
Motif Edition, for more information on using xrdb.) 
4. Next, the contents of any file (on the system running the client) specified by the shell 
environment variable XENVIRONMENT will be loaded. The difference between this and 
APPLRESDIR above is that this is a complete path name including the file name. 
If this variable is not defined, the resource manager looks for a file named .Xdefaults- 
hostname (with a hyphen) in the user's home directory, where hostname is the name of 
the host where the client is running. (On systems with a network file system, the home 
*If you break the conventions by giving your program binary a capitalized name, or by giving your app-defaults file 
a lower-case name, it is possible to have the binary accidentally interpreted as an app-defaults file. The entire binary 
will be searched for resource lines! Since the binary is so large, your application will start up very slowly. No error 
will be reported because the resource manager quietly ignores entries it doesn't understand. 

300 X Toolkit Intrinsics Programming Manual, Motif Edition 



directory may be on a system different from the one where the application is running, the 
one where the server is running, or both.) 

5. Any values specified on the command line with the -xrm option will be loaded for that 
instance of the program. 

6. If the application has defined any command-line options by passing an options table to 
xl:/ppTnil:iaa__ze, values from the command line will override those specified by 
any other resource settings. 

The order in which these various sources are loaded, as shown in the list above, is the reverse 
order of their priority. That is, those that are loaded first will be overridden by those loaded 
later if an identical specification is found. 
If a resource value is hardcoded in the arguments of the call to create a widget, that value 
takes precedence over any value for that resource in the resource database. If a widget is 
created and no setting exists in the database for a particular resource, the value pointed to by 
the defau! l:_address field of the resource list in the widget is used. This is also true for 
application resources and subresources. 
Figure 10-1 shows where Xt looks for resource files and in what order, on most UNIX-based 
systems. The exact directories are operating system and implementation dependent. 
Remember that the app-defaults file is written by the application writer, and all the rest of the 
resource sources are for the user. In practice, few users use more than one or two of these 
sources of resource settings. 

Resource Management and Type Conversion 301 



/usr/lib/$LANG/app-defaults/class 
else /usr/lib/app-defaults/class 

$XUSERF I LESEARCHPATH/class 
else $XAPP LRESD IR/$ LANG/clas s 
else $XAPPLRESDIR/class 
else $HOME/$LANG/class 
else $HOME/class 
RESOURCE MANAGER property (xrdb) 
_ 
else $HOME/. Xdefault s 

$XENVIRONMENT 
else $HOME/.Xdefaults-hostname 

Command line options 

Figure 10-1. Typical resource setting search path on UNiX-based systems 

10.2.3 

The Language String 

In R4, Xt's resource handling was modified to support resource files for different languages. 
The goal is to have all the language dependencies of an application in files, so that just by 
selecting a different set of resource files at run time, the application will operate correctly in 
another language.* 
The language to use is selected with a language string, which is an application resource 
defined by Xt: "xnlLanguage" (no symbol xmt,lxnll.anguage is defined for it). The 
default language string is NULL, which makes Xt behave as it did in R3. But when the 
*It is important to note that no one has actually done this yet! The mechanism is too new. In fact, the X Consortium 
is currently reviewing the support for internationalization in Xt and Xlib to determine whether they are sufficient to 
achieve the above goal. Most likdy they will recommend some additional features, but of course since both Xt and 
Xlib are Consortium standards, all changes must be backwards compatible. 

302 X Toolkit Intrinsics Programming Manual, Motif Edition 



The matching process can be thought of as a process of elimination. Let's assume the 
merged resource database is as shown in Example 10-4. 

Examp 10-4. A sample meed source dabase 
*rowColumn.background: blue 
*background: red 
*quit.background: green 
*quit.labelString: Quit 
*XmPushButton.background: yellow 
*XmRowColumn.XmPushButton.background: violet 
*rowColumn*background: pink 
xrowcolumn.background: orange 

(entry 1 ) 
(entry 2 ) 
( entry 3 ) 
( entry 4 ) 
( entry 5 ) 
( entry 6) 
(entry 7) 
(entry 8) 

Only resource database entries that specify background as the last element before the co- 
lon are possible matches. That eliminates entry 4. The fully specified instance and class 
hierarchies are then compared with each possible match, beginning with the first component 
in each hierarchy. 
1. Every entry beginning with the asterisk wildcard binding (*) as well as the one beginning 
with xrowcolumn, matches xrowcolumn, the first component of the fully specified 
instance name. All those beginning with * also match the first component of the fully 
specified class name, XRowColumn. Since entry 8 actually contains the string 
xrowcolumn, the xrowcolumn component is removed for comparison at the next 
level. Entry 8 now begins with . background. 
2. The first component of each resource specification (after removal of previously matched 
components) is now compared to the second element in the widget's class and instance 
hierarchies. This should be either rowColumn or XmRowColumn. All the entries 
that begin with * still match, because * matches any number of levels in the hierarchy. 
However, there is no second element in entry 8, once the resource name background 
is removed. Therefore, entry 8 is eliminated. Also, since entries 1,6, and 7 actually con- 
tain the strings rowColumn or XmRowColumn, the leading asterisk and the strings 
rowColumn and XmRowColumn are removed before comparison of the next level. 
Example 10-5 shows the resource database as it would appear after the components and 
entries eliminated so far. 

Example 10-5. Sample resource database with eliminated entries and components 

.background: 
*background: 
*quit.background: 
*XmPushButton.background: 
.XmPushButton.background: 
*background: 

blue (entry 1 ) 
red (entry 2) 
green (entry 3) 
yellow (ent 5) 
violet (entry6) 
pink (entry7) 

Note that entries 2 and 7 are now duplicates except for the resource value. The resource 
manager actually eliminates one of these entries based upon the levels at which each en- 
try matched, whether the instance name or class name matched, whether a tight or loose 
binding was used, and which had more elements specified. These are the precedence 
rules to be described in the next section. In order to keep the example clearer, we'll pre- 
tend that the resource manager keeps the information necessary to apply all the prece- 
dence rules, and keeps all the entries, until the end. 

306 X Toolkit Intrinsics Programming Manual, Motif Edition 



1. A specification that includes higher components in the instance or class hierarchy takes 
precedence over one that includes only lower ones. 

*topLevel*quit.background: 
*rowColumn*quit.background: 

takes precedence over 

2. Instance names take precedence over class names at the same level in the hierarchy. 
* qu i t. b a c k g r ou n d : takes precedence over 
*XmPushButton. background : 

3. Tight bindings take precedence over loose bindings at the same level in the hierarchy. 
* rowColumn, background : takes precedence over 
* rowColumn*background : 

4. A name or class that is explicitly stated takes precedence ovff one that is omiUed. 
*rowColumn*quit.background: takesprecedenceover 
*rowColumn*background: 

To understand the application of these rules, let's return to our extended example. In the 
course of developing that example, we eliminated information about the level at which com- 
ponents occurred. However, the actual process of matching applies the precedence rules at 
each step. As a result, let's start again with the original appearance of the entries that pass 
the matching test. The remaining five as they appeared originally are shown in Example 
10-7. 

Example 10-7. Resource database finalists in original form 

*background: red 
*quit.background: green 
*XmPushButton.background: yellow 
*XmRowColumn. XmPushButton.background: violet 
*rowColumn*background: pink 

( entry 2 ) 
( entry 3 ) 
( entry 5 ) 
( entry 6) 
(entry 7) 

From here on, we will determine not only which one of these five will take effect, but the ac- 
tual precedence of the five. In other words, once the one with highest precedence is deter- 
mined, we'll see which would take effect if that one was commented out, and so on. 
The precedence rules are applied in order to determine the order of the finalist entries. 
1. Rule 1 specifies that a specification that contains higher components in the instance or 
class hierarchy takes precedence over one that contains only lower ones. The highest 
components that appear in our example are rowColumn and XmRowColumn in entries 
6 and 7. Therefore, these two have higher priority than any others. 
2. To choose between these two, we continue to Rule 2. Instance names (rowColumn) 
take precedence over class names (XmRowColumn). Therefore, entry 7 has the highest 
precedence, followed by entry 6. Note that the precedence comparison of two finalists 
proceeds in the same manner as the original matching--from left to right in the entry, 
one component at a time. 

308 X Toolkit Intrinsics Programming Manual, Motif Edition 



3. To determine the precedence of the remaining three entries, 2, 3, and 5, we begin again 
with Rule 1. However, Rule 1 does not apply because no two entries here specify differ- 
ent levels in the hierarchy. Entries 3 and 5 contain the quit level and entry 2 nothing 
(an asterisk does not count for Rule 1 because it is not a specified level--it is any level). 
Rule 2 specifies that the instance name quit takes precedence over the class name Xm- 
PushButton, and therefore entry 3 has higher priority than entry 5. Rule 3 does not 
apply, because no two entries are identical except for binding. Because of Rule 4 we 
know that both entries 3 and 5 are higher priority than entry 2, because 3 and 5 state a 
name or class that is omitted in 2. 

Therefore, the final precedence is as shown here: 

i. *rowColumn*background: pink (entry7) 
2. *XmRowColumn.XmPushButton.background: violet (entry6) 
3. *quit.background: green (entry3) 
4. *XmPushButton.background: yellow (entry5) 
5. *background: red (em 2) 

Rules 2, 3, and 4 are fairly easy to understand and apply, but many people forget or are con- 
fused by Rule 1. People get used to the fact that they can set the resources of all the children 
of rowColumn with something like entry 7, but then are shocked to find that nothing hap- 
pens when they attempt to override entry 7 with entry 3--entry 3 seems more specific to 
them. Even the following entry (using a class name) takes precedence over entry 3 because 
the rule about being higher in the widget hierarchy carries more weight than the rule that in- 
stance names take precedence over class names: 
*XmRowColumn*background : pink (entry 7) 
The moral of this story is that there is only one way to be sure you are setting a particular re- 
source of a particular widget in such a way as to override all other settings that might apply 
to that resource: you must specify all the levels in the instance hierarchy, with tight bindings 
between each component (But of course, this will not work when another resource file that 
is merged later also specifies the same resource and all components of the same widget with 
the instance hierarchy separated by tight bindings.) Since there arc no messages telling you 
which resource specifications are actually being used, you can be tricked into thinking that 
you have set resources that you actually haven't. Using only tight bindings in the app-de- 
faults file, while more trouble initially, is probably wise in the long run. 
Figure 10-3 illustrates the entire process of resource matching. 

A useful tool for figuring out the priority of resource files is the appres utility. You specify 
the class name of the application on the command line, and appres shows you what resource 
settings that application will see when run. Note, however, that this does not tell you how 
these resource settings will actually apply to the widgets in the application, since appres has 
no knowledge of the widget instance hierarchy in your application. 

Another tactic in tracing resource settings is to build a routine into your application that gets 
and prints all the critical resources of a widget Using XtGetResourceList you can get 
the list of resources supported by a widget class. Then you can query each of those resources 
and print most of them out Remember that certain resources are compiled into internal 
forms, so you can't print out translation tables, accelerator tables, or callback lists. It may 
also be difficult to interpret other values, since many of them will have already been convert- 

Resource Management and Type Conversion 309 



Table 10-2. Built-in Type Converters from XmRStdng (continued) 

Target Type 

XmRFile 
XmRFloat 
XmRFont 

XmRFontStruct 

XmRGeometry 

XmRInitialState 

XmRInt 
XmRPixel 

XmRPosition 
XmRShort 
XmRTranslationTable 

XmRUnsignedChar 
XmRVisual 

Description of Converter 

Given a filename, opens the file and returns the file descriptor. 
Converts a numeric string to floating point 
Given a font name, loads the font (if it is not already loaded), 
and returns the font ID. See Appendix B, Specifying Fonts 
and Colors, for more information on legal values. The value 
XtDefaultFont will return the default font for the screen. 
Given a font name, loads the font (if it is not already loaded), 
and returns a pointer to the FontStruct containing font 
metrics. The value XtDefaultFont will return the default 
font for the screen. 
Given a standard geometry string, this convener simply 
copies a pointer to the string and calls it a new resource type. 
Converts strings "Normal" or "Iconic" into the symbols Nor- 
malState or IconicState. 
Converts a numeric string to an integer. 
Converts a color name string (e.g., "red" or "#FFO000") into 
the pixel value that will produce the closest color possible on 
the hardware. See Appendix B, Specifying Fonts and Colors, 
for more information on legal values. The two values XtDe- 
faultBackground and XtDefaultForeground are 
always guaranteed to exist, and to contrast, on any server. 
However, Motif calculates its own colors to implement its 
four-color shadow scheme. 
Converts an x or y value to a Position. 
Converts a numeric string to a short integer. 
Compiles string translation table into internal translation table 
format (no need to call XtParseTranslationTable). 
Converts a string to an unsigned char. 
Converts a string specifying a visual class to a pointer to a 
supported visual structure of that class. 

If there is no convener from XmRString tO a particular resource type, it may not be pos- 
sible to specify that resource type in a resource file. For example, there is no converter for 
XmRCallback since it would be meaningless to specify a function in a resource file. The 
only ways to set a callback resource are with XtAddCallback or a static callback list de- 
clared in the application. 

Most of the Xt conveners allow the resources of the base classes Core, Composite, Con- 
straint, and Shell to be set from resource files. Motif provides numerous conveners that al- 
low the resources of its widgets to be set from resource files. However, not all Motif widget 
resources can be set from resource files, because conveners are not provided for some. For 
example, there is currently no widget name to widget ID convener in Motif 1.1. Such a con- 

312 X Toolkit Intrinsics Programming Manual Motif Edition 



verter would make it possible to specify Form constraint resources such as XmNtopWidget 
from resource files. 

In addition, the Xmu library contains several useful converters. For example, Xmu provides 
a converter that converts from a filename (string) to a bitmap suitable for use as an icon pix- 
map. Even though Xmu (like Xaw) is not part of the X Consortium standard, it is part of 
MIT's core distribution and is available on most systems. However, because the Xmu con- 
veners are not built into Xt, you need to register them with a call to XtSetType- 
Converter or XtAddConverter (from widget code) or XtAppSetType- 
Converter or XtAppAddConverter (from application code) before using them in an 
application or widget. (We'll describe the converters and show how to register them in Sec- 
tion 10.3.4.) Xmu also provides a widget name to widget ID converter that could be regis- 
tered to remedy the lack of one in Motif mentioned above. 

10.3.2 

Other Built-in Type Conversions 

While the conversions from XmRString are the most widely used, since they allow a re- 
source to be specified from a resource file, there are also a number of built-in converters be- 
tween other data types, for use internally within Toolkit programs. 

Most commonly, these converters are used to convert between the resource_type and 
default_type fields of a resource definition. 

Table 10-3 lists those converters automatically recognized by Xt. 

Table 10-3. Other Built-in Converters 

From 

XmRColor 
XmRPixel 
XmRInt 

XmRPixel 
XmRColor 
XmRBoolean 
XmRBool 
XmRColor 
XmRDimension 
XmRFloat 
XmRFont 
XmRPixel 
XmRPixmap 
XmRPosition 
XmRShort 
XmRUnsignedChar 

Description of Converter 

Converts an XColor structure to a pixel value. 
Converts a pixel value to an XColor structure. 
Converts an int to a Boolean. 
Converts an int to a Boolean. 
Converts an int to an XColor. 
Converts an int to a Dimension. 
Converts an int to a float. 
Converts an int to a Font. 
Converts an int to a pixel value. 
Converts an int to a Pixmap. 
Converts an int to a Position. 
Converts an int to a short. 
Converts an int to an unsigned char. 

For example, the default value of the Core resource XmNborderPixmap is set as shown in 
Example 10-8. 

Resource Management and Type Conversion 313 



Example 10-8. A resource definition converting an integer to a pixmap 
static XtResource resources[] = { 

XmNborderPixmap, 
XmCPixmap, 
XmRPixmap, 
sizeof(Pixmap), 
XtOffsetOf(CoreRec, core.border_pixmap), 
XtRImmediate, 
(XtPointer) XtUnspecifiedPixmap 
}, 

} 
(Note that the code for the base classes defined by Xt use constants beginning with xt, not 
xm. However, the value of each of these constants is the same in both versions.) 
The specified default value XtUnspecifiedPixmap is an integer defined to have a value 
that does not equal the constant CopyFromParent or any valid Pixmap ID. The ini- 
tialize method for the Core widget class checks for this value, and does not set the 
background window attribute unless the application or a resource file has set the Xra- 
NborderPixmap resource to some value other than the default. 

10.3.3 

Special Resource Defaults That Do Not Use Conversion 

There are two special values, XmRImmediate and XmRCallProc that can be used only 
in the default_type field of a resource definition. These values require no type conver- 
sion. The value provided in the default_address field must be of the correct type. 
The type XmRImmediate means that the value in the default_address field is the 
default value itself, not its address. For a string, this means that the default_address 
field is a pointer to the string, not a pointer to a pointer. 
In Example 10-9, the value in the default address field of the XmNheight resource 
-- 
definition is the actual default--in this case, zero. 

Example 10-9. A resource definition using XmRImmediate 
static XtResource resources[] = { 

{ 
XmNheight, 
XmCHeight, 
XmRDimension, 
sizeof(Dimension), 
XmOffsetOf(RectObjRec, rectangle.height), 

314 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 10-9. A resource definition using XmRImmediate (continued) 

XmRImmediate, 
(XtPointer) 0 
}, 

}; 

The type XmRCallProc means that the value in the default_address field is a point- 
er to a function. This function is of type XtResourceDefaultProc,* and it is expected 
to retrieve the desired default value at run time. When the widget instance is created, the 
function is automatically invoked with these parameters: the widget ID, the resource offset, 
and a pointer to the XrmValve in which to store the result. The function should fill in the 
addr field of the XrmValue with a pointer to the default data in its correct type. 

In Example 10-10, the value in the default_address field of the XmNscreen resource 
definition is the name of a function that retrieves the screen on which the widget is displayed. 

Example I0- I0. A resource definition using XmROallProc 
static XtResource resources[] = { 

XmNscreen, 
XmCScreen, 
XmRPointer, 
sizeof(int), 
XtOffsetOf(CoreRec, core.screen), 
XmRCallProc, 
(XtPointer) XtC0pyScreen 
1, 

}; 
Example 10-11 shows an example of an XtResourceDefaultProc. 

Examp 10-1 I. An examp of an XtResourceDeultProc 
/*ARGSUSED*/ 
void XtCopyScreen(widget, offset, value) 
Widget widget; 
int offset; 
XrmValue *value; 
( 
value->addr = (XtPointer) (&widget->core.screen); 

*This function type is relevant primarily because the reference page in Volume Five, X Toolkit Intrinsics Reference 
Manual, that describes its calling sequence is listed under this name, XtResourceDefaultProc. This refer- 
ence page is in the Prototype Procedures section in Volume 5. 

Resource Management and Type Conversion 315 



Note that XtSetTypeConverter was added to Xt in R4. Its predecessor, XtAdd- 
TypeConverter, is still available and can still be used, but has reduced functionality. 
XtAddTypeConverter cannot be used for conversions that require a server query (such 
as those involving colors or fonts), and does not provide the caching control provided by 
XtSetTypeConverter. Note that the explicit application context version of the call 
(XtAppSetTypeConverter) is not used in this case, because the class initial- 
-- 
i ze method does not pass in a widget from which the application context could be deter- 
mined. 
The first two arguments of XtSetTypeConverter are the source and target type, respec- 
tively, specified using XmR symbolic constants defined in <Xm/Xm.h> (or defined in an appli- 
cation header file or the widget public header file if the type is not standard in Xt). 
The third argument is the name of the convener routine, which by convention contains the 
string cve. The Xmu conveners all add the prefix Xmu. 
The fourth and fifth arguments of XtSetTypeConverter are an argument list that will 
be passed to the converter routine when it is called. Some converter routines require infor- 
mation about the context in which the converter is called. This is usually passed in via an 
XtConvertArgRec structure, as described in the next section. If no arguments are need- 
ed, the fourth and fifth arguments of XtSetTypeConverter can be NULL and 0 respec- 
tively. 
The sixth argument specifies whether the results of the conversion should be cached. The ba- 
sic symbols are XtCacheNone, XtCacheAll, and XtCacheByDisplay. Expensive 
conversions should be cached. Xt caches resource values to avoid repetitive conversions of 
the same value, which are common in an application made up of many identical widgets. It 
is especially important to cache conversions that require round-trips to the server, such as 
color, font, and atom conversions. But it is wasteful of memory to cache silly conversions 
such as XtCvtStringToGeometry, which actually doesn't do any conversion or even 
validity checking. (The XmRGeomet ry representation type is a geometry string, as defined 
by XParseGeometry. It takes no conversion to convert XtRString to Xt- 
RGeomet ry. The converter could at least test the string to make sure it looks like a geome- 
try string.) Another benefit of caching is that Xt remembers unsuccessful conversions and ef- 
ficiently generates warning messages without attempting any conversion more than once. 
The symbol XtCacheRefCount can be ORed with any of the above values, in which case 
Xt keeps track of how many widgets still exist that used a converted value, and frees the 
cached value when the count reaches zero. The application, if it uses the converted value in 
a call to XtGetApplicationResources, is also counted as one reference. Reference 
counting is needed only if an application destroys widgets whose resource values may take 
up extensive space. Because reference counting takes up space and requires time, it should 
not be done unless necessary. To control reference counting on a widget-by-widget basis, an 
application must explicitly set the XmNinitialResourcesPersistent resource to 
False for each widget whose conversions are to be reference counted. These should be 
widgets that might be destroyed before the application exits. 
The seventh argument of XtSetTypeConverter is a pointer to a procedure called a des- 
tructor. If the reference count for a particular resource reaches zero, Xt calls the destructor 
function, and removes the resource value from the conversion cache. The destructor will also 
be called when XtCloseDisplay is called if the convener was registered with xt- 

318 X Toolkit Intrinsics Programming Manual Motif Edition 



10.3.6.1 

XtDisplayStringConversionWarning takes as arguments a pointer to the 
Display structure, the string that could not be converted, and the type to which it could not 
be converted. It issues a warning message with name conversionError, type string, 
class XtToolkitError, and the default message string "Cannot convert "src" to type 
dst_type." (See Chapter 14, Miscellaneous Toolkit Programming Techniques, for more 
information on error and warning messages.) 
Many converters need to compare multiple strings in order to convert a value. For example, 
Motif's string to arrow-direction converter has to determine whether a string matches Xm- 
ARROW_UP, XmARROW_DOWN, XmARROW_LEFT, or XmARROW_RIGHT. Normally this 
would require up to four time-consuming string comparisons for each conversion. Instead, 
converters of this type use a shortcut based on quarks. A quark is a unique integer ID for a 
string, of type XrmQuark (defined by Xlib). A call to the Xlib routine XrmString- 
ToQuark returns the quark for a string. A converter determines quarks for each of its refer- 
ence strings (such as XmARROW_UP) only once during run time, and determines a quark for 
each string to be converted. Then quarks can be compared quickly since they are just inte- 
gers. (See Volume Two, Xlib Reference Manual, for details on quarks.) 
When a nonstandard type converter that uses quarks is defined and registered in widget code, 
the XrmStringToQuark calls are normally placed in the class_initialize 
method just before the xt SetTypeConverter call. 

Defining the Default Value 

When performing conversions, such as from strings to fonts or colors, for which there is no 
string representation that all server implementations will necessarily recognize, a type con- 
verter should define some set of conversion values that the converter is guaranteed to succeed 
on, so that these can be used as resource defaults. 
For example, Xt's default string-to-pixel converter recognizes the symbols XtDefault- 
Foreground and XtDefaultBackground. As part of its conversion, it tests for these 
values, and establishes the appropriate value based on the string value. The code is shown in 
Example 10-16. 

Example 10-16. Testing for a special-case default value 
/* 
* CompareISOLatinl is an undocumented Xt function, allowed 
* since this converter is within Xt. In your converters, 
* you would use XmuCompareISOLatinl. 
*/ 
if (CompareISOLatinl(str, XtDefaultBackground) == O) { 
*destructor data = False; 
-- 
if (pd->rv) 
done(Pixel, BlackPixelOfScreen(screen)) 
else 
done(Pixel, WhitePixelOfScreen(screen)) ; 
} 
if (CompareISOLatinl(str, XtDefaultForeground) == O) { 
*destructor data = False; 
-- 
if (pd->rv) 
done(Pixel, WhitePixelOfScreen(screen)) 

324 X Too&# Intrinsics Programming Manual, Motif Edition 



The get_values_hook method is passed a single copy of the widget instance structure 
(the new copy already modified in the nonhook methods), and the argument list passed to the 
Xt routine that triggered the method. The set values and get_values hook meth- 
ods simply take this widget ID and argument list and pass them to XtSetSubvalues or 
XtGetSubvalues respectively. The initialize method uses the contents of the ar- 
gument list to validate resource settings for subparts and to set nonresource subpart data. 

The get_values_hook method is still used in R4. Example 10-17 shows the get_ 
values_hook for the AscSrc subpan of the R3 Text widget (somewhat simpled to 
show the essential elements). 

Examp 10-1Z Simplified get vaes__hook meMod of Me AsciiS subpa of Me Text widget 
static void 
GetValuesHook(src, args, num_args) 
XawTextSource src; 
ArgList args; 
Cardinal * num_args; 
{ 

XtGetSubvalues((XtPointer) src, 
sourceResources, 
XtNumber(sourceResources), 
args, 
*num_args); 

10.4.2 

Managing Subresources 

Managing subresources is very similar to managing application resources. Like the applica- 
tion, the subpart must have a structure containing the fields to set through resources. In the 
application you call XtGetApplicationResources or XtVaGetApplication- 
Resources to set these fields. In a subpart, the analogous calls are XtGet- 
Subresources or XtVaGetSubresources, which is called from the initialize 
method. 

Like widgets, the resources of subparts can be queried and set manually. XtVaGet- 
Subvalues or XtGetSubvalues queries the values, and XtVaSetSubvalues or 
XtSetSubvalues sets them. However, because subvalues are not part of any widgeL 
these calls cannot identify what object is being queried or set simply by passing the widget 
ID. These calls have different arguments than xtSetValues and XtGetValues. In- 
stead of the widget ID, you pass the pointer to the data structure, the resource list, and the 
number of resources. Therefore, XtSetSubvalues and XtGetSubvalues can be in- 
voked only from within the widget or subpart. Actually, all these routine do is set or get the 
value in the specified structure. 

326 X Toolkit Intrinsics Programming Manual, Motif Edition 



Any application using the widget will set or get subresources using XtSetValues and 
XtGetValues as for normal resources, specifying only the coordinating widget as the first 
argument. These calls are translated into XtSetSubvalues and XtGetSubvalues 
calls by the set_values and get_values_hook methods. These methods are passed 
the arguments from the XtSetValues or XtGetValues calls and translate them into 
XtSetSubvalues or XtGetSubvalues calls by adding the data structure and resource 
list arguments. But in addition, the set_values method is responsible for validating the 
resource settings passed in before it calls XtSetSubvalues, and for changing any non- 
resource subpart structure fields like GCs that depend on resources. 

Resource Management and Type Conversion 327 



11 

Interclient Communications 

This chapter discusses communication through the X server between an 
application and the window manager, and between two applications. The 
application-window manager communication is performed by code in the 
Shell widget. The application sets shell resources to control this communica- 
tion with the window manager. Application-application communication is 
usually done with a process called selections. This form of communication is 
already implemented in most widgets that display text, but you may want to 
implement it in your own custom widgets. Selections can also pass other 
kinds of data such as graphics. How to use the Motif Clipboard is also 
described. 

In This Chapter: 

Window Manager Interactions ............................................................ 332 
Shell Subclasses ........................................................................... 332 
Setting Shell Resources ................................................................. 333 
Screen Space ................................................................................ 335 
Input Model .................................................................................... 337 
Colormaps ..................................................................................... 338 
Icons ............................................................................................. 340 
Window Manager Decorations ....................................................... 342 
Interacting With the Motif Window Manager ................................... 342 
WM PROTOCOLS ...................................................................... 343 
-- 
MOTIF WM MESSAGES ......................................................... 343 
-- -- -- 
MOTIF WM HINTS ................................................................... 344 
-- -- -- 
Selections: Widget-to-Widget Communication ................................... 344 
How Atomic Selection Works ......................................................... 346 
Highlighting the Selected Data (Owner) .......................................... 349 
Making the Selection with XtOwnSelection (Owner) ....................... 354 
Requesting the Selection (Requestor) ............................................ 355 



Possible Target Type Atoms ......................................................... 356 
The Paste Action from BitmapEdit ............................................... 358 
Converting the Selection (Owner) .................................................. 358 
Finally Pasting the Selection (Requestor) ....................................... 360 
If the Selection is Lost (Owner) ...................................................... 362 
When the Selection Transfer is Complete (Owner) ......................... 363 
ICCCM Compliance ........................................................................ 363 
Xmu Atom Caching ...................................................................... 365 
Converting the Standard Selections ............................................. 365 
How Incremental Selection Works .................................................. 367 
Miscellaneous Selection Routines .................................................. 368 
Motif Cut and Paste Functions and the Clipboard ............................... 369 



11 
Interclient Communications 

Applications share the server with other clients. Server resources, such as screen space and 
colormaps, must be used in a responsible, consistent manner so that applications can work 
effectively together. In most window systems, the window system itself embodies a set of 
rules for application interaction. However, the X Protocol, Xlib, and Xt were all specifically 
designed to avoid arbitrary conventions, so that they provide "mechanism, not policy." 
Instead, the conventions covering interclient communication are described in a separate doc- 
ument, adopted as an X Consortium standard in July, 1989, called the Inter-Client Commu- 
nication Conventions Manual (ICCCM). This chapter will not fully describe the ICCCM, 
because the job of implementing its rules is given over to a special client called the window 
manager and a special widget class called Shell and its subclasses.* As a result the details of 
the ICCCM are, for the most part, irrelevant to the application writer's needs. 
In X Toolkit programs, the Shell widget returned by xt:Apprn.t:.al..ze and used as the 
top-level window of the application automatically handles most of the required interactions 
with the window manager. However, the Shell widget needs additional information in certain 
areas. For example, the application needs to provide an icon pixmap so that the window 
manager can iconify it properly. The first section in this chapter describes how to set Shell 
resources to control how an application interacts with the window manager. This portion of 
the chapter is for application writers, regardless of whether you need to write widgets for 
your application. 
The ICCCM defines the required information that must be sent by the client. The Shell 
widget class takes care of sending this information. However, mwm, the Motif Window Man- 
ager, also allows the application to send or be sent optional information. One set of informa- 
tion warns the application when it is about to be killed or when one of its windows is about to 
be destroyed. A separate set lets the application specify what kind of decorations it wants on 
its top-level shell widgets. The final set allows mwm to notify the application when a certain 
entry on its system menu has been selected. This entry is normally added to the user's 
.mwmrc as part of the application's installation procedure. 

*If you do need to look up certain details of the ICCCM, see Appendix L, Inter-Client Communication Conventions, 
in a version of Volume Zero, X Protocol Reference Manual, printed on or after June, 1990 (the conventions have 
changed since the version of the ICCCM printed in earlier editions of Volume One). The ICCCM is also included in 
troffsource form in the standard X distribution from MIT. 

Interclient Communications 331 



commonly used in applications. One is the OverrideShellWidgetClass, passed to 
XtCreatePopupShell when the shell is used for popup menus. The convention is this: 
the shell should be an OverrideShell when the pointer is grabbed to prevent other windows 
from getting input while the popup is up, and the shell should be TransientShell for other 
popups. This is discussed further in Chapter 13, Menus, Gadgets, and Cascaded Popups. 

The other additional subclass of Shell is topLevelShellWidgetClass, which is used 
to cream additional, non-popup, top-level shells. Some applications have multiple permanent 
top-level windows. One of the top-level shells would be of the applicationShell- 
WidgetClass, and the rest would be of the topLevelShellWidgetClass. Each 
would have a separate icon. 

11.1.2 

Setting Shell Resources 

Shell resources are primarily a way for the user and the application to send in data to be com- 
municated to the window manager. These window manager hints control several major areas 
of window manager activity: they manage screen space, icons, and keyboard input. We'll 
discuss these areas one at a time in the following sections. Table 11-1 lists the Shell widget's 
resources with a brief description of what they control, and whether the application, the user, 
or Xt normally sets them. 

As indicated in Column 3 of the table, some Shell resources are intended to be set only once. 
These set-once resources can be left to their default values, set in the app-defaults file, or 
they can be set in the code before the Shell widget is realized; but they should not be set with 
xt S etva 1 ue s after realization. 

Table 11-1. Shell Resources 

Resource 

usually set by Xt or Shell itse 
depending on e subcss : 
XmNargc 
XmNargv 
XmNoverrideRedirect 

Purpose 

Command-line args count 
Command-line args 
Set for popup shells not to be decorated 

When Settable 

XmNtransient 
XmNwaitForWm 
XmNwindowGroup 
XmNwmTimeout 
usually set by user: 
XmNiconX 
XmNiconY 
XmNiconic 
XmNgeometry 
XmNtitle 
usually set by application: 

Set for popup shells 
Whether to wait at all 
Links popups to main window 
Waiting time for slow wm 

Icon position 
Icon posidon 
Sets XmNinitialState  iconic 
Initial size and position 
String for tide bar 

Before realization 
Before realization 
Before realization 
Before realization 
Anytime 

Interclient Communications 333 



the keyboard focus even if it is in some other window. It wants to temporarily set and 
then reset the keyboard focus when the user clicks in the scrolled region, but not when 
the user clicks in the scrollbar itself. Thus, it wants to prevent the window manager from 
setting the keyboard focus to any of its windows. This type of client sets XmNinput to 
False. 

Note that even if the XmNinput resource is not set to True, your application will still work 
under some window managers, including uwm, twm, and mwm. This is because these win- 
dow managers use the pointer-following keyboard focus model or ignore this hint. However, 
it is not wise to assume that all window managers will ignore this hint. Therefore, if your 
application expects keyboard input, and is not of the globally active type described above, 
you can use the code shown in Example 11-1 to set the XmNinput resource. 

Examp 11-1. Seing e XmNinputresourceofa Shefl widget 
main(argc, argv) 
int argc; 
char *argv[]; 
{ 

/* create the Shell widget, setting resource */ 
topLevel = XtVaAppInitialize(&app_context, "Xmh", 
table, XtNumber(table), 
&argc, argv, NULL, 
XmNinput, (XtArgVal)True, 
NULL); 

} 
Note that the XmNinput resource should always be hardcoded, since the application may 
fail if the user is allowed to change the expected style of keyboard focus. 
For a further discussion of the keyboard focus, see Section 14.4. 

11.1.5 

Colormaps 

On most color systems, the display uses one or more hardware registers called colormaps to 
store the mapping between pixel values and actual colors, which are specified as relative 
intensities of red, green, and blue primaries (RGB values). 

X allows virtual colormaps to be created by applications. Some high-performance systems 
even allow all virtual colormaps to be installed in hardware colormaps and used at the same 
time, even to the level of one colormap per window. Far more commonly, though, there is 
only one hardware colormap, and virtual colormaps have to be copied into the hardware 
colormap one at a time as needed. Copying a virtual colormap into the hardware colormap is 
called installing the colormap, and the reverse process where the default colormap is 

338 X Toolkit Intrinsics Programming Manual, Motif Edition 



installed is called uninstalling. The window manager is responsible for installing and unin- 
stalling colormaps. 
If your application has standard color needs (decoration only), then you do not have to worry 
about the effects of colormaps being installed and uninstalled. Your application should use 
the standard Xrn_RString to Xrn_RPixel converter to translate color names into pixel val- 
ues. If the colormap is full, or becomes full at any of the color allocations in the converter, 
the warning messages place the burden on the user to kill some applications in order to free 
some colormap cells. (If the converter cannot allocate the desired color, it prints a warning 
message, and the default for that resource is used. If the default is not XtDefault- 
Foreground or XtDefaultBackground, it also must be converted and this may also 
fail. If both allocations fail, the color will default to black. If this is not acceptable, then you 
will need to write your own type converter.) 
If your application absolutely requires accurate colors, a certain number of distinguishable 
colors, or dynamically changeable colors, you will need to write your own converter to allo- 
cate colors. For example, if a color allocation for a known correct color name string fails, it 
means that all the colormap entries have already been allocated and no entry for that color is 
available. In this case, your converter might call the Xlib call XCopyColorrnapAndFree 
tO copy the allocations your application has already made into a new colormap. Then the 
converter would allocate the color (and all subsequent colors) from the new colormap. 
See Chapter 7, Color, in Volume One, Xlib Programming Manual, for details of various 
color allocation techniques. 
The window manager is responsible for installing and uninstalling colormaps according to its 
own policy. Typically, the policy is to install the colormap of the application that has the 
keyboard focus or that contains the pointer. When an application has created a new colormap 
on a system that supports only one hardware colormap, and that colormap is installed, all 
applications that were using the other colormap will be displayed using the new colormap. 
Since the pixel values from the old colormap have not been allocated in the new colormap, 
all applications that use the old colormap will be displayed with false colors. This is known 
as "going technicolor." 
The window manager may also create standard colormaps to facilitate the sharing of colors 
between applications. A standard colormap is a colormap allocated with a publicly known 
arrangement of colors. The Xlib routine XGetStandardColorrnap allows an applica- 
tion to determine whether the window manager has created a specific standard colormap, and 
it gets a structure describing the colormap. Xmu provides numerous utilities for creating and 
using standard colormaps--see Volumes One and Two for a description. 
If your application requires more than one colormap, each installed at the same time in a dif- 
ferent window, you need to tell the window manager about this so that these colormaps can 
be properly installed when the application is active. You do this by calling XtSet- 
WMCo 1 o rmapWindow s, specifying the ApplicationShell widget as the first argument, a list 
of widgets that need certain colormaps as the second argument, and the length of the list as 
the third argument. This instructs the window manager to read the colormap window attri- 
bute of each of the listed widgets, and to install that colormap in each widget (if possible) 
whenever the application is active. (Of course, any application that depends on the existence 
of multiple simultaneous colormaps is doomed to run on only a small percentage of existing 
systems.) 

Interclient Communications 339 



Example 11-2. Creating an icon pixmap, and setting XmNiconPixmap 

* The following needed if not using Motif: 
* #include <Xll/Shell.h> 
*/ 
#include "icon" 
main(argc, argv) 
int argc; 
char **argv; 
( 
Pixmap icon_pixmap; 

/* create topLevel here */ 

icon_pixmap = XCreateBitmapFromData(XtDisplay(topLevel), 
RootWindowOfScreen(XtScreen(topLevel)), 
icon_bits, 
icon width, icon height ); 
-- -- 

XtVaSetValues(topLevel, XmNiconPixmap, icon_pixmap, NULL); 

/* realize widgets */ 

The included file, icon, is in standard X11 bitmap file format. You can create such a file 
using the bitmap application from the standard distribution, or xbitmap5 from the examples 
for this book. 

The window manager may have a preferred standard size for icons. If so, it will set a prop- 
erty. The application can read this property with the Xlib call XGetrconSizes. To fully 
support a variety of window managers, an application should be capable of creating icon pix- 
maps of different sizes, depending on the values returned by XGetr conSi zes. 

An application has the option of creating its own icon window, and then passing its ID to the 
Window manager for management. This might be done so that the application can draw a 
multi-colored picture in the icon, instead of the traditional two-color bitmap, or animate the 
icon. However, as with all hints, the window manager is not guaranteed to honor your desires 
and may just ignore the icon window you provide. But if you want to try anyway, create the 
window using Xlib calls, and select input on it so that your application receives Expose 
events when they occur. Then set the ID of the window using the XmNiconWindow 
resource, before realizing the application. Then make sure your event loop redraws the icon 
when it receives Expose events on it. Accomplishing this will require writing your own 
modified version of XtAppMainLoop to handle the icon events. 

Interclient Communications 341 



11.1.7 Window Manager Decorations 

Virtually all current window managers decorate windows on the screen.* These decorations 
typically include a title bar for the window with gizmos for moving and resizing the window. 
Current decorating window managers include twm, awm, mwm, olwm, and gwm. 
The way these decorations are implemented can have an impact on Toolkit applications. The 
window manager places the decorations in a window slightly bigger than the application, and 
then reparents the application's top-level window into the decoration window. Reparenting 
gives the top-level window a new parent instead of the root window. The window manager 
actually creates the frame window as a child of the root window, then reparents the applica- 
tion's top-level window into the frame, and then maps the frame window. 
Reparenting affects the application mainly when you try to determine a global position (rela- 
tive to the root window) from the xnx and xny, resources of the Shell widget. This is 
usually done in order to place popups. Under a nonreparenting window manager such as 
uwm, these coordinates are indeed relative to the root window, because the parent of the shell 
is the root window. However, under a window manager that reparents, the coordinates of the 
application's main Shell widget are relative to the decoration window, not the root window. 
Therefore, these coordinates cannot be used for placing popups within the application. 
Motif's internal code that places a popup uses XtTranslateCoords instead of relying 
on the position resources. 

11.1.8 

Interacting With the Motif Window Manager 

The application and mwm can communicate back and forth through properties stored on the 
server. The properties are associated with the top-level window of your application, so 
unlike selections, similar communications can be going on at the same time between differ- 
ent clients and the window manager without interference. The ICCCM, Inter-Client Commu- 
nication Conventions Manual, defines a starting point for what information can be sent back 
and forth.t mwm also defines some other information it is willing to send and receive. 
All Shell widgets handle the required communication with the window manager; this section 
concerns optional communication. Note that applications should not depend on this type of 
communication. An application may run under a different window manager that doesn't lis- 
ten to this type of message. Furthermore, an application is not required to use this type of 
communication, because mwm runs fine without it. This type of communication is just icing 
on the cake. (If you want to know whether mwm is running anyway, use the xm- 
I shot i fWMRunni ng function.) 
The next three sections describe the two major groups of protocols and a set of supplemen- 
tary window manager hints. The first protocol group is defined by the ICCCM, and the second 
by Motif. You must include the header file <XlllProtocols.h> to use any of these features. 

*The uwm window manager doesn't decorate, but it is defunct as of R4 since it doesn't honor the current ICCCM. 
tThe ICCCM is reprinted as an appendix of Volume Zero, X Protocol Reference Manual. 

342 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 11-3. BitmapEdit: actions that highlight selection (continued) 

{"StartHighlight", StartHighlight}, 
{"ExtendHighlight", ExtendHighlight }, 
{"MakeSelection", MakeSelection}, 
{"PasteSelection", PasteSelection}, 

}; 

* User presses first button (by default), starting highlighting. 
static void 
StartHighlight(w, event) 
Widget w; 
XButtonEvent *event; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
cw->bitmapEdit.first box = False; 
-- 

cw->bitmapEdit.select start x = (cw->bitmapEdit.cur x + event->x) 
-- -- -- 
/ cw->bitmapEdit.cell_size_in_pixels; 
cw->bitmapEdit.select_start_y = (cw->bitmapEdit.cur_y + event->y) 
/ cw->bitmapEdit.cell_size_in_pixels; 

/* clear old selection */ 
Redisplay(cw, NULL); 

* MakeSelection is call when the first button is released (by 
* default). This finishes the user's highlighting, and means 
* triggers ownership of the PRIMARY selection. 
,/ 
static void 
MakeSelection(w, event) 
Widget w; 
XButtonEvent *event; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int temp; 

cw->bitmapEdit.select end x = (cw->bitmapEdit.cur_x + event->x) 
/ cw->bitmapEit.ell_size_in_pixels; 
cw->bitmapEdit.select_end_y = (cw->bitmapEdit.cur_y + event->y) 
/ cw->bitmapEdit.cell_size_in_pixels; 

if ((cw->bitmapEdit.select end x == cw->bitmapEdit.select_start_x) 
-- -- 
&& (cw->bitmapEdit.select_end_y == 
cw->bitmapEdit.select_start_y)) { 
Redisplay(cw, NULL); 
return; /* no selection */ 
} 

/* swap start and end if end is greater than start */ 
if (cw->bitmapEdit.select end x < cw->bitmapEdit.select_start_x) { 
temp = cw->bitmapEdit.select end x; 
cw->bitmapEdit.select end x = cw->bitmapEdit.select_start_x; 
cw->bitmapEdit.select start x = temp; 

350 X Toolkit Intrinsics Programming Manual, Motif Edition 



SelectionClear event arrives. The lose_ownership_proc is of type Xt- 
LoseSelectionProc. 

The transfer_done_proc is called by Xt when the requester has successfully 
retrieved the convened value. If this selection is intended to be erased after being 
transferred once, this function should free any storage allocated in the transfer. If, 
instead, the owner remains ready for pasting the same selection into other widgets, this 
function pointer should be NULL. (For example, xterm does not clear its selection after 
pasting once.) The transfer_done_proc is of type XtSelectionDoneProc. 

The XtOwnSelection call also takes a time argument--this should be the time from 
the event that completed the highlighting, not the constant CurrentTime. If XtOwn- 
Selection returns False, it means that because of network conditions another client has 
called xtOwnSeIection with a more recent time argument. 
xtOwnSelection returns True or False tO indicate whether Widget A has been 
granted ownership. If True, and if this widget was not already the owner, then the old 
owner (if any) will receive a SelectionClear event and will clear its highlighted area. 
The process may end here if the user never pastes the selected data anywhere. If the user 
selects a different piece of data, the selection owner will receive a SelectionClear 
itself before ever having convened the data for a requestor. 
Otherwise the owner code waits to hear from the requester that it is ready to paste the selec- 
tion. 

11.2.4 

Requesting the Selection (Requestor) 

When the user pastes the selection into Widget B, Widget B becomes the requester and the 
second part of the process begins. First of all, Widget B needs a translation that maps a cer- 
tain key or button event to an action that pastes data. This action calls XtGet- 
SelectionValue. 
XtGet Select ionValue is called with six arguments: 
void XtGetSelectionValue (widget, selection, target, callback, 
client data, time) 
-- 
Widget widget; 
Atom selection; 
Atom target; 
XtSelectionCallbackProc callback; 
XtPointer client data; 
-- 
Time time; 
The selection argument is an atom specifying which property is being used to transfer 
the selection. This will typically be XA_PRIMARY, though in theory two widgets (or two 
instances of the same widgeO could agree to transfer some particular data using other proper- 
ties. 
The target argument is another atom, this one specifying a target representation type in 
which the requestor wants the information. We'll talk more about the possible values for this 
atom in a moment. 

Interclient Communications 355 



11.2.4.1 

The callback argument is a pointer to a callback procedure that actually pastes the dam. 
Xt will call this procedure when the owner has converted the data. The XtGet- 
SelectionValue call registers the callback with Xt, and sends a Selection- 
Request event to the owner. 
When the selection owner has successfully converted the data, the owner sends back a 
SelectionNotify event to Xt. Xt then calls the requestor's callback procedure. The 
callback procedure must handle the pasting of the data into the widget's data structures, and 
it must handle the case where the data could not be converted into the requested representa- 
tion. We'll discuss the responsibilities of this procedure in more detail once we've seen the 
owner's conversion procedure. 
The client_data argument of XGetSelectionValue is normally used to pass the 
event that triggered the pasting into the requestor callback. The callback will use the coordi- 
nates at which the event occurred as the location at which to paste the data. 
As in the call to XtOwnSelection, the time argument should be the time from the event 
that initiated the pasting, not the constant CurrentTime. 

Possible Target Type Atoms 

The target argument to XtGetSelectionValue is an atom that the requestor uses to 
tell the owner what kind of information it is looking for from the selection.* This is not nec- 
essarily a conversion of the actual selection data. For example, it might be a timestamp on 
the data, or some characteristic of it, such as its size or font. 
To take full advantage of the Xt selection mechanism, you need to understand what atoms 
can be used as selection targets. However, apart from some standard, predefined atoms, the 
atom for a property is not known by a client until it queries the server for the atom using an 
XInternAtom call. This call specifies the string name of the property and returns the 
atom. 
Some atoms needed by almost all applications are predefined in the header file 
<X11/Xatom.h>. These atoms are symbolic constants that can be used without an 
XInternAtom call. The constants always start with the prefix XA See <X11/Xatom.h> 
_. 
for the complete list of predefined atoms. 
Note that many of the predefined atoms have uses in X other than as target types, and not all 
are appropriate as selection targets. A few of those that might be useful as targets include: 
XA STRING 
-- 
XA INTEGER 
-- 
XA BITMAP 
-- 
At present, the Athena widgets and the clients in the MIT core X distribution use only 
XA_STRING as a target. However, one can imagine uses for other targets as well. For 
example, XA_FONT might be used as a target to indicate that the requestor doesn't want the 
text of a selection, but wants only to know its font. XA_TIMESTAMP might be used to indi- 
cate that the requestor wants a timestamp for the data. Once the 

*As described earlier, atoms (rather than strings) are always used in network transmissions to identify properties. 

356 X Toolkit Intrinsics Programming Manual, Motif Edition 



11.2.4.2 

This XInternAtom call occurs in every instance of the BitmapEdit widget, since all 
instances need to know the atom to participate in selections using that target type. Both the 
owner and requestor widgets, in separate applications, will get the same atom in return. 

The Paste Action from BitmapEdit 

To initiate the requestor role, you need to assign an event sequence to trigger the pasting, 
write an action that calls XtGetSelectionValue, and write a callback function that 
inserts the returned data. 

Traditionally, the action to paste data is triggered by a press of the second pointer button. 
BitmapEdit will use the shifted second button since it uses the unshifted button for other pur- 
poses. Example 11-5 shows the action mapped to Shi ft<Btn2Down>. 

Examp 11-5. BitmapEdit: action  pas a section 
static void 
PasteSelection(w, event) 
Widget w; 
XButtonEvent *event; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
XtGetSelectionValue(cw, XA_PRIMARY, cw->bitmapEdit.target_atom, 
requestor_callback, event, 
event->time); 
) 
This action can be dropped verbatim into your widget, replacing only the widget name and 
the name of the instance fields you are using to store the target atom. 

11.2.5 

Converting the Selection (Owner) 

The real challenge in handling selections is writing the convert_proc, which converts 
data to the format specified by the requestor and prepares it for transfer. 
As mentioned above, the widget's convert_proc is called by Xt when the requestor calls 
XtGetSelectionValue. The procedure is passed the selection atom and the target 
atom, and is expected to return in its arguments the type, value, size, and format of the con- 
verted selection data. 
To support the possibility of having to convert the data to any one of several targets, the code 
branches according to the value of the target passed in, and does its conversions accordingly. 
In the version of BitmapEdit's convert_proc shown here, only one target type is 
handled. Section 11.2.9.2 describes how to add more target types, including some that are 
required by the ICCCM such as TARGETS. 
Once the conversion is made, the procedure sets the va2 ue_return argument passed in to 
a pointer to a block of memory, and 2ength_return to the size of the block. This block 
of memory will be set into a property by Xt and passed to the requestor's callback in the 
same formmas a pointer to a block of memory and a length. This puts constraints on the for- 
mats that can be used for the data. 

358 X Toolkit Intrinsics Programming Manual, Motif Edition 



For text selections, the data is usually a simple character string. The convert_proc sim- 
ply needs to set *value_return to a pointer to the string, and length_return to the 
length of the string. For BitmapEdit, however, the required data is a string (of bitmap cell 
states) plus width and height values. Since C provides easy ways to put numeric values into 
strings and to get them out again at the other end, we've chosen to handle this data by con- 
vening the numbers to characters and tacking them on to the beginning of the string. 
If your selection is composed of a number of numeric values, you can create a structure con- 
mining the values and then pass a pointer to the structure. However, the structure cannot 
contain pointers, because the data pointed to by these pointers will not be set into the selec- 
tion property. For example, BitmapEdit cannot pass a pointer to a structure containing a 
string pointer field and width and height fields because the block of memory pointed to by the 
string pointer will not be copied. 
In this case, the type_return can simply be the target atom that was passed in, indicating 
that the data is of the requested type. 
The format_return is the size in bits of each element in the array. Since we are passing 
a compound string, this value is 8. If we were passing a structure, length_ret urn would 
be 1 and * format_return would be 8 times the size of the structure in bytes. 
Example 11-6 shows BitmapEdit's convert__proc. 

Examp 11-6. BmapEdit: conveing e sectbn vae 
static Boolean 
convert_proc(w, selection, target, type_return, value_return, 
length_return, format_return) 
Widget w; 
Atom *selection; 
Atom *target; 
Atom *type_return; 
XtPointer *value return; 
-- 
unsigned long *length_return; 
int *format return; 
-- 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int x, y; 
int width, height; 

/* handle all required atoms, and the one that we use */ 
/* Xt already handles MULTIPLE, no branch necessary */ 
if (*target == XA TARGETS(XtDisplay(cw))) { 
-- 
/* Required atom: see Example i0-i0 */ 

else if (*target == cw->bitmapEdit.target_atom) 
char *data; 
width = cw->bitmapEdit.select end x - 
-- -- 
cw->bitmapEdit.select start x; 
-- 
height = cw->bitmapEdit.selec_end_y - 
cw->bitmapEdit.select_start_y; 
/* 8 chars is enough for two 3-digit 

Interclient Communications 359 



Example 11-6. BitmapEdit: converting the selection value (continued) 

* numbers and two delimiters */ 
*length_return = ((width * height) + 8) * sizeof(char); 
data = XtMalloc(*length_return); 
sprintf(data, "%d@%d-", width, height); 
for (x = 0; x < width; x++) { 
for (y = 0; y < height; y++) { 
data|8 + x + (y * width)] = cw->bitmapEdit.cell|(x + 
cw->bitmapEdit.select start x) + 
-- _ 
((y + cw->bitmapEdit.select_start_y) * 
cw->bitmapEdit.pixmap_width_in_cells)]; 
} 
} 
*value return = data; 
-- 
*type_return = cw->bitmapEdit.target_atom; 
*format return = 8; /* number of bits in char */ 
-- 
return(True); 
} 
else { 
/* code to handle standard selections: see Example I0-I0 */ 

} 
} 

This code determines the width and height of the selected rectangle from the instance part 
fields, and then allocates enough memory to fit a character array big enough to fit the width 
and height values, delimiters, and a width by height character array. Then it copies the cur- 
rent contents of the selected area into the allocated character array. Finally, it sets 
*value_return to point to the compound string, and sets *length_return to the 
length of this string. *format_return is the size in bits of each element in the array, 
which in this case is 8 bits. 

11.2.6 

Finally Pasting the Selection (Requestor) 

When the owner's convert_proc returns, Xt sends a SelectionNotify event to the 
requestor. The Xt code on the requestor side then invokes the callback routine the requestor 
registered with the call to XtGetSelectionValue. 
The requestor callback function is passed all the same arguments that the owner 
-- 
received in the convert_proc, plus the values that the owner returned through the argu- 
ment of convert_proc. In the BitmapEdit widget, it sets instance part fields to paste the 
data. 
Example 11-7 shows the requestor callback function from BitmapEdit. 

360 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 11- BitmapEd#: pasting section  requescallbacknction 
/* ARGSUSED */ 
static void 
requestor_callback(w, client_data, selection,type,value,length, format) 
Widget w; 
XtPointer client data; /* cast to XButtonEvent below */ 
-- 
:i Atom *selection; 
Atom *type; 
XtPointer value; 
unsigned long *length; 
! int *format; 
BitmapEditWidget cw = (BitmapEditWidget) w; 
if ((*value == NULL) && (*length == 0)) { 
XBell(XtDisplay(cw), I00); 
XtWarning("bitmapEdit: no selection or selection timed out:\ 
try again\n"); 
} 
else { 
XButtonEvent *event = (XButtonEvent *) client data; 
-- 
int width, height; 
int x, y; 
int dst_offset_x, dst_offset_y; 
char *ptr; 
dst offset x = (cw->bitmapEdit.cur x + event->x) / 
-- cw>bitmapEdit.cell size_iX pixels; 
-- 
-- 
dst_offset_y = (cw->bitmapEdit.cur_y + event->y) / 
cw->bitmapEdit.cell_size_in_pixels; 
printf("dst offset is %d, %d\n", dst_offset_x, dst_offset_y); 
ptr = (char *) value; 
width = atoi(ptr); 
ptr = index(ptr, "@'); 
ptr++; 
height = atoi(ptr); 
ptr = &value[8]; 

for (x = 0; x < width; x++) { 
for (y = 0; y < height; y++) { 
/* range checking */ 
if (((dst offset x + x) > 
-- _ 
cw->bitmapEdit.pixmap_width_in_cells) 
  ((dst offset x + x) < 0)) 
-- _ 
break; 
if (((dst_offset_y + y) > 
cw->bitmapEdit.pixmap_height_in_cells) 
I I ((dst_offset_y + y) < 0)) 
break; 
cw->bitmapEdit.cell[(dst offset x + x) 
-- _ 
+ ((dst_offset_y + y) * 
cw->bitmapEdit.pixmap_width in cells)] 
= ptr[x + (y * width)]; 
if (cw->bitmapEdit.cell[(dst offset x + x) 
-- _ 
+ ((dst_offset_y + y) * 
cw->bitmapEdit.pixmap_width in cells)] 
DRAWN) 

Interclient Communications 361 



Example 11-7. BitmapEdit: pasting selection in requestor__callback function (continued) 
DrawCell(cw, dst offset x + x, 
-- -- 
dst_offset_y + y, 
cw->bitmapEdit, draw_gc) ; 
else 
DrawCell(cw, dst offset x + x, 
-- -- 
dst_offset_y + y, 
cw->bitmapEdit, undraw_gc) ; 
) 
) 
/* Regardless of the presence of a 
* transfer_done_proc in the owner, 
* the requestor must free the data passed by 
* Xt after using it. */ 
XtFree (value) ; 
Redisplay(cw, NULL) ; 
) 
) 
The requestor_callback first determines whether the conversion was a success by 
checking the vlue and dam length. If it was not, it beeps and prints a mesge. This can 
happen if no selection has been made, or if there is some delay that causes the selection to 
have timed out before the owner could convert the data. 
If the conversion was a success, the requeseor_ca22back pastes the data. In Bitmap- 
Edit's case, the requestor must first convert the data into a more useful form. This means 
extracting the width and height values, and then setting the widget's cell array based on the 
data in the character array passed in. Note that the code should check to make sure that the 
data can be pasted in the desired position. BitmapEdit must make sure that no attempt is 
made to set a cell array member outside of the bitmap. The routine then updates the screen 
display of the widget. 
The final responsibility of the requestor_callback is to free the memory passed in by 
Xt. 

11.2.7 

If the Selection is Lost (Owner) 

If the owner loses the selection, either because the selection timed out or because the user 
made a different selection, the 2 ose_ownership_proc that was registered with its call 
to XtOwnSelection will be invoked. Typically, this function simply clears any high- 
lighting or other visual feedback about the selection, and resets to their initial state any inter- 
nal variables used in handling selections. 

Example 11-8 shows the l ose_ownership_proc from the BitmapEdit widget. 

Examp 11-8. BitmapEdit: He bse_ownehip_proc 
/* ARGSUSED */ 
static void 
lose_ownership_proc(w, selection) 
Widget w; 
Atom *selection; 

362 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 11-10. BitmapEdit: conveing standard e  e conve_proc ontinue 
XtPointer *value return; 
-- 
unsigned long *length_return; 
int *format_return; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int x, y; 
int width, height; 
XSelectionRequestEvent* req = XtGetSelectionRequest(w, 
*selection, (XtRequestId) NULL); 
/* handle all required atoms, and the one that we use */ 
if (*target == XA TARGETS(XtDisplay(cw))) { 
-- 
/* TARGETS handling copied from xclipboard.c */ 
Atom* targetP; 
Atom* std_targets; 
unsigned long std_length; 
XmuConvertStandardSelection(cw, req->time, selection, 
target, type_return, 
(XtPointer*)&std_targets, 
&std_length, format return); 
-- 
*value_return = XtMalloc(sizeof(Atom)* (std_length + I)) ; 
targetP = *(Atom**)value return; 
-- 
*length_return = std_length + i; 
*targetP++ = cw->bitmapEdit.target_atom; 
bcopy((char*)std_targets, (char*)targetP, 
sizeof(Atom)*std_length); 
XtFree((char*)std_targets); 
*type_return = XA_ATOM; 
*format return = sizeof(Atom) * 8; 
-- 
return(True); 
} 
/* Xt already handles MULTIPLE, no branch necessary */ 
else if (*target == cw->bitmapEdit.target_atom) { 
/* handle normal selection - code shown in Example 10-6 */ 

} 
else { 
if (XmuConvertStandardSelection(cw, CurrentTime, selection, 
target, type_return, value_return, 
length_return, format_return)) 
return True; 
else { 
XtWarning("bitmapEdit: requestor is requesting\ 
unsupported selection target type.\n"); 
return(False); 

} 
} 
} 

Overall, this code handles the TARGETS atom in the first branch, the normal selection target 
in the second, and any remaining standard atoms and any unknown atoms as two cases in the 
third branch. For ICCCM-compliant code, you can copy this entire function into your widget 

366 X Toolkit Intrinsics Programming Manual, Motif Edition 



and then write just the second branch. Note that branches that successfully provide the 
requested data return True, and branches that don't return False.* 

In the first branch you will also need to change the reference to the instance part field that 
stores the target atom used for selections, bitmapEdit, target_atom. If your widget 
uses a predefined atom or one supported by the Xmu facility, you would reference that atom 
here instead of the instance part field. If you called XInternAtom in initialize and 
stored the result in an instance part field, you specify that here. 

Note that XtGetSelectionRequest is used to get the time from the Selection- 
Request event that the owner received before Xt called the convert_proc function. 
XtGetSelectionRequest was introduced in R4 for this specific reason; it needs to 
meet the current ICCCM and work around the fact that the convert_proc is defined with- 
out an event argument. (The convert_proc definition could not be changed because of 
the required backwards compatibility with R3.) 

11.2.10 

How Incremental Selection Works 

An incremental selection is very similar to an atomic transfer, except that you use different 
set of routines and procedure types, and Xt calls the procedures you register multiple times 
instead of just once as in atomic transfers. Incremental transfers and atomic transfers are 
mutually exclusive--an owner can support both, but if the owner doesn't, a requestor cannot 
use the incremental routines to request a selection owned atomically, or vice versa. 
As in an atomic transfer, the owner and the requestor in an incremental transfer only have to 
make one call each in order to initiate this multiple-section transfer. Here is the procedure: 

The owner calls Xt0wnSelectionIncremental in response to the user selecting 
something. XtOwnSelectionTncremental returns True or False to indicate 
whether ownership was granted. XtOwnSelectionIncremental registers four 
callbacks: 
XtConvert SelectionIncrP roc convert_proc; 
XtLoseSelectionlncrProc lose selection_proc; 
XtSelectionDonelncrProc transfer done_proc; 
-- 
XtCancelConvertSelectionProc cancel_conversi on_proc; 

The user pastes the selection in a widget, which causes that widget to request the selec- 
tion with XtGetSelectionValueIncremental. XtGetSelectionValue- 
I nc rement a 1 registers one callback: 
Xt SelectionCa llbackProc requestor_proc; 
This callback receives the selection data. The requestor__proc is called once upon 
delivery of each segment of the selection value. It is called with type 

*The ICCCM also specifies that functions implementing selections must be able to respond to a MULTIPLE target val- 
ue, which is used to handle selections too large to fit into a single property. However, the necessary handling is done 
by the lntrinsics. Your procedures do not need to worry about responding to the MULTIPLE target value; a selection 
request with this target type will be transparently transformed into a series of smaller transfers. 

Interclient Communications 367 



ownership of the CLIPBOARD selection. If it loses the selection (which will happen when- 
ever a widget or client has newly deleted the contents of a selection), it obtains the contents 
of the selection from the new owner, then reasserts its own ownership of the selection. 
Clients wishing to restore deleted data should request the contents of the CLIPBOARD, using 
the same techniques as we've shown for the PRIMARY selection, xclipboard will respond to 
these requests, returning the deleted data. 
The use of xclipboard allows the value of a selection to survive the termination of the origi- 
nal selection owner. 

370 X Toolkit Intrinsics Programming Manual Motif Edition 



12 

Geometry Management 

This chapter discusses how composite and constraint widgets manage the 
layout of widgets, and how to write your own simple composite and constraint 
widgets. 

In This Chapter: 

How Composite Management Works ................................................. 374 
Initial Geometry Negotiation ........................................................... 376 
User Resizes the Application ......................................................... 379 
Widget Desires a Size Change ...................................................... 379 
Application Resizes a Widget ......................................................... 381 
Writing a Composite Widget ............................................................... 382 
Basic Core Methods in Composite Widgets .................................... 384 
Laying Out Child Widgets ............................................................... 386 
The change_managed Method ....................................................... 388 
The geometry_manager Method .................................................... 388 
XtQueryGeometry and the query_geometry Method ...................... 389 
XtMakeGeometryRequest and the geometry_manager Method ..... 390 
The insert_child and delete_child Methods ..................................... 391 
How Constraint Management Works .................................................. 392 
Writing a Constraint Widget ................................................................ 392 
The Core Resource List ................................................................. 393 
The Constraint Resource List ......................................................... 394 
Class Structure Initialization ........................................................... 396 
The Constraint initialize Method ..................................................... 398 
The class_part_init Method ............................................................ 399 
The geometry_manager Method .................................................... 400 
The resize Method ......................................................................... 404 
The Core and Constraint set values Methods ................................ 406 
-- 
The change_managed Method ....................................................... 407 



The query_geometry Method ......................................................... 408 
Delaying Geometry Recalculation .................................................. 408 
Compound Widgets ........................................................................... 409 
Stacking Order ................................................................................... 410 



12 
Geometry Management 

Geometry managing widgets lay out your application's widgets on screen according to cer- 
tain rules. You cannot hardcode the position of widgets in an application because X applica- 
tions can be resized and they must reposition their widgets to take advantage of the available 
space. Because of the window manager, even the initial size of the application may not be 
the application's preferred size. 

Chapter 3, More Techniques for Using Widgets, demonstrated how you can use existing 
composite widgets such as RowColumn and constraint widgets such as Form in the applica- 
tion. You can control widget layout rules with resources. However, you may find that no 
existing composite or constraint widget can be configured with resources to have the layout 
rules you need. In this case, you will need to write your own composite or constraint widget 
or modify an existing one. However, before embarking on writing one of these widgets, you 
should realize that composite and constraint widgets are complex. First investigate the alter- 
natives! Perhaps you can find a composite or constraint widget from another widget set that 
has the layout characteristics you need. If you determine that you have no alternative but to 
write your own composite or constraint widget, you should keep it as simple as possible. It is 
much easier to write a special-purpose widget that handles a limited layout situation than it is 
to write a general-purpose composite or constraint widget like RowColumn or Form. 

A composite widget is defined as any widget that is a subclass of the Xt-defined class Com- 
posite. A constraint widget is any widget that is a subclass of the Xt-defined class Con- 
straint- Constraint is a subclass of Composite. As you may recall, a composite widget is the 
simplest kind of geometry-managing widget; it handles all its children equally, or handles 
each child in a fixed way. For example, the RowColumn widget handles all of its children 
equally. As an example of a special-purpose composite widget, Section 12.2 describes a 
composite widget called ScrollBox that manages two scrollbars and a main window. This 
widget requires that it have exactly three children added in a particular order. 

A constraint widget has all the characteristics of composite widgets but maintains configur- 
able data about each child so that it can cater to the needs of each child. By setting the con- 
straint resources of a child of a constraint widget, you configure the constraint widget's lay- 
out policy for that child. Constraint widgets are inherently more powerful than composite 
widgets, but are also more complicated to write. A constraint widget requires all the code of a 
composite widget, plus code to handle the constraints of each child. Because of this com- 
plexity, you should hesitate even further before attempting to write a constraint widget. As 

Geometry Management 373 



Shell  Xt 
lntrinsics 
Form ,-- routines 

RowColumn 

PushButton 

I PushButton 

change, managed method called from bottom up 

Figure 12-2. Initial geometry negotiation, assuming sufficient shell space 

change_managed methods are called until the one in the Shell widget. (Remember that 
the Shell widget is a composite widget that has only one child.) The child is also a composite 
widget (except in single-widget applications such as xhello). When the Shell widget is 
reached, the Shell widget size is set to the size of its child and the process stops unless the 
user has specified an initial geometry for the entire application through the resource database 
or command line. 
A change_managed method can (but is not required to) determine each of its children's 
preferred geometry by calling XtQueryGeometry for each child. This will result in the 
query_geometry method of each child being called. Instead of calling XtQuery- 
Geometry, the change__managed method may use the child's Core width and 
height fields. 
The change__managed method does not determine the composite widget's own size. That 
job is for the parent of the composite widget, which is another composite widget. 
If the user-specified, top-level widget geometry is different from the geometry of the Shell 
widget's child after all the change__managed methods are called, then the Shell widget 
resizes its child to the user-specified size. This makes Xt call the resize method of the 
child composite, and this resize method reconsiders the layout of its children. This pro- 
cess proceeds down the chain of widgets to the bottom. At each stage the resize method 

Geometry Management 377 



Notice that this process can result in the resize, change_managed, and possibly the 
que ry__geomet ry methods of every widget being called, but the geomet ry__manage r 
method does not play a part. 

Once this process is complete, XtReali zeWidget calls the reali ze methods of all the 
widgets and actually creates windows for them. Up to this point, all the methods were simply 
changing the widget size and position parameters in Xt structures, not the sizes of actual win- 
dows. XtRealizeWidget also maps all managed widgets. 

12.1.2 

User Resizes the Application 

When XtReali zeWidget returns, most applications call XtAppMainLoop. Internally, 
this calls the Xlib call XNextEvent which sends the batch of queued window creation and 
window map requests to the server.* Most window managers can intercept the mapping 
request for the top-level window and draw a rubber-band outline of the application on the 
screen, ready for the user to place or resize the application. With certain settings mwm can 
either place windows for you or allow you to place and size them. If the user simply places 
the application, no new geometry negotiation takes place. But if the user resizes the applica- 
tion, a new round of geometry negotiation takes place, identical to the process described 
above where the user specified a top-level widget geometry. 
In other words, the process that occurs when the user resizes the application with the window 
manager is the same as when the user specifies top-level widget geometry with resources or 
the command line. This is also the same as when the user later resizes the existing applica- 
tion. This process was illustrated in Figure 12-2 and Figure 12-3. 
This process uses all the methods except geometry_manager. 

12.1.3 Widget Desires a Size Change 

When an application sets a widget resource that affects what is displayed in the widget, it 
may be logical for the widget to ask its parent for a new size. This would occur in the 
set values method of the widget. The widget sets its desired geometry into its Core 
geometry fields (width, height, x, y, and border_width). Xt finishes calling all the 
set values methods (because they chain), and then calls XtMakeGeometry- 
Request to ask the parent widget for a geometry change. Note that the set_values and 
initialize methods are the only place where widgets are allowed to set their own size 
directly. (In set_values they can do so only because of an xtvaSetValues call to 
change a resource that affects geometry.) 

Figure 12-4 shows what happens when a widget requests a size change. 

*You can find out more about the network optimization done by Xlib in Volume One or Volume Zero. 

Geometry Management 379 



For both simple and composite widgets, Xt calls the geometry__manager method of the 
parent widget when XtMakeGeometryRequest is called, and the method is responsible 
for deciding whether to except, reject, or compromise on the requested geometry. The 
geometry_manager method may have to ask its parent to decide whether it can accept 
its child's proposal. If so, it makes another XtMakeGeometryRequest call. This can 
go on to arbitrary depth, and the final answer will trickle back down to the parent of the origi- 
nal requestor. The XtMakeGeometryRequest call itself will change the child's geome- 
try if the answer is yes. If the answer is no, the child gets this information and may try 
another geometry. If the answer is a compromise, then the child will get the compromise 
information returned in its call to XtMakeGeometryRequest and make another request 
to be able to proceed. More on this interaction in Section 12.2.4 and 12.2.6. 
This process uses only the geometry_manager methods of each widget. However, this 
method may call XtQueryGeomet ry to determine the needs of each of its children before 
replying to the XtMakeGeometryRequest requesL When the process is finished, the 
resize method is called for any widgets that have been resized. However, the 
change_managed method is never involved. 

12.1.4 

Application Resizes a Widget 

An application may change the size of a widget by setting the XtNx, XtNy, XtNwidth, 
XtNheight, or XtNborderWidth resources dectly (as opposed to setting a resource 
which indirectly affects the size, as covered in the last section). If that widget has no chil- 
dren, the widget code does nothing, but Xt queries the parent with an XtMakeGeomet ry- 
Request. The complete negotiation process as described for XtRealizeWidget is 
repeated, except that the current top-level Shell size is used as a user-specified size (because 
ultimately it is). 
Although the widget code did nothing, the set__values method sets the new values speci- 
fied through resources into the Core fields. If the XtMakeGeometryRequest request is 
denied by the parent, Xt sets these Core fields back to their original values. If the parent sug- 
gests a compromise, the set_values_almost method, which is described below, is 
called. 
If the widget whose size is changed is a widget with children, the negotiation process is the 
same, except that when it is complete the children of the widget need to be laid out, and if the 
children have children they need to be laid out too, and so on. 

Geometry Management 381 



12.2.1 Basic Core Methods in Composite Widgets 

Both composite and constraint widgets are subclasses of Core. Therefore, they have all the 
Core methods described in Chapters 6 and 7. However, since composite and constraint widg- 
ets usually have no input and output semantics, the expose method is set to NUt.r. and the 
widget has no default translation table or actions. As a result, all the event-oriented fields in 
the Core class structure become irrelevant to composite and constraint widgets. 
But composite and constraint widgets do use the Core initialize, realize, and 
set values methods. These methods have the same roles as for simple widgets. The 
-- 
i nitiali z e method initializes instance part variables and checks initial resource values. 
The realize method sets window attribute values and then creates a window for the 
widget. The set_values method updates any instance part fields that depend on 
resources. Since composite and constraint widgets don't need GCs, initialize and 
set values don't contain code to create and change GCs as in simple widgets. 
These three methods for ScrollBox are absolutely minimal, and call a common routine called 
DoLayout when any actual sizing or positioning of widgets is required. The initial- 
ize method simply sets the widget's default width and height, the realize method is 
inherited, and the set values method changes the layout of children when either of 
-- 
ScrollBox's two resources is changed. These resources control the vertical and horizontal 
distance in pixels that will be left between the Scrollbar widgets and the main widget, and 
between each of these widgets and the borders of ScrollBox. Example 12-1 shows the 
set values method of ScrollBox. 

Examp 12-1. ScrollBox: e setvaes meod 
/* ARGSUSED */ 
static Boolean SetValues(current, request, new, args, num_args) 
Widget current, request, new; 
ArgList args; 
Cardinal *num_args; 
{ 
ScrollBoxWidget sbwcurrent = (ScrollBoxWidget) current; 
ScrollBoxWidget sbwnew = (ScrollBoxWidget) new; 

/* need to relayout if h_space or v_space change */ 
if ((sbwnew->scrollBox.h_space != sbwcurrent->scrollBox.h_space) 
(sbwnew->scrollBox.v_space != 
sbwcurrent->scrollBox.v_space)) 
DoLayout(sbwnew); 

return False; 

Two more Core methods are used in composite widgets: resize and query_geometry. 
The resi ze method changes the layout of its children and is shown in Example 12-2. 

384 X Toolkit Intrinsics Programming Manual Motif Edition 



geometry suggestions are unpredictable. ScrollBox ignores this complexity because it knows 
exactly what kinds of children it will have and what their characteristics are. Therefore, its 
query_geometry method is basically the same as the query_geometry method of a 
simple widget. 
To be more precise, what this query_geometry method does is accept any size suggested 
by the parent which is larger than the minimum useful size of the application. When the sug- 
gested size is too small, the query_geometry method uses the minimum useful size as a 
compromise. Note, however, that this is really hardcoding the characteristics of the child into 
our composite widget. It would be better to add resources to control the minimum useful 
size. 

12.2.2 

Laying Out Child Widgets 

Composite widgets need to calculate a layout and manipulate their child widgets from 
set values, from resize, and from change_managed. Therefore, in most compos- 
-- 
ite widgets this common code is placed in a single routine called DoLayout. Example 12-4 
shows the DoLayout routine from ScrollBox. 

Examp 12-4. ScrollBox: pdvate route  lay out child widge 
/* ARGSUSED */ 
static DoLayout(w) 
Widget w; 
{ 
ScrollBoxWidget sbw = (ScrollBoxWidget) w; 
Widget main, vscroll, hscroll; 
Widget child; 
Dimension mw, mh; /* main window */ 
Dimension vh; /* vertical scrollbar length (height) */ 
Dimension hw; /* horizontal scrollbar length (width) */ 
Position vx; 
Position hy; 
int i; 
if (sbw->composite.num children != 3) 
-- 
XtAppError(XtWidgetToApplicationContext(sbw), 
"ScrollBox: must manage exactly three widgets."); 
for (i = 0; i < sbw->composite.num children; i++) { 
-- 
child = sbw->composite.children[i]; 
if (!XtlsManaged(child)) { 
XtAppError(XtWidgetToApplicationContext(sbw), 
"ScrollBox: all three widgets must be managed."); 
) 
) 
/* Child one is the main window, two is the vertical scrollbar, 
* and three is the horizontal scrollbar. */ 
main = sbw->composite.children[0]; 
vscroll = sbw->composite.children[l]; 
hscroll = sbw->composite.children|2]; 
/* Size all three widgets so that space is fully utilized. */ 

386 X Toolkit Intrinsics Programming Manual Motif Edition 



12.2.3 The change_managed Method 

In every composite widget, the change_managed method is called once (and only once, 
even when there are multiple children) during the XtRealizeWidget process to deter- 
mine an application's initial layout, change_managed is also called when an application 
later unmanages a managed widget or manages an unmanaged widget (as long as the Xt- 
NmappedWhenManaged resource has its default value). Therefore, change_managed 
also calls DoLayout. 
An application unmanages a widget to remove the widget from visibility without destroying 
it, and at the same time to tell the composite widget to change the layout of the remaining 
widgets to fill the gap. This is done by calling XtUnmanageChild or XtUnmanage- 
Children. The application can then make the composite widget redisplay the widget by 
calling XtManageChild or XtManageChildren. This response depends on the Core 
XtNmappedWhenManaged resource having its default value, True. When set to 
False, the management state has no effect on mapping, and the application must call Xt- 
MapWidget and XtUnmapWidget instead. Usually an application does this so that a 
widget will become invisible without triggering a re-layout to fill in the space it has vacated. 
Therefore, change_managed need not check the XtNmapWhenManaged resource of 
each child. Example 12-5 shows the change_managed method of ScrollBox. 

Example 12-5. A basic change_managed method 

static void ChangeManaged(w) 
ScrollBoxWidget w; 
{ 
ScrollBoxWidget sbw = (ScrollBoxWidget) w; 
DoLayout(sbw); 

12.2.4 

The geometry_manager Method 

The geometry_manager method responds to requests by the children to be resized. 
ScrollBox does not manage widgets that request to be resized, so theoretically it should not 
need a geometry_manager, but as of R4, Xt requires that all composite widgets have 
one. ScrollBox's geometry manager method is very simple, and is shown in Example 12-6. 

Examp 12-& A simp geomet_manager meod 
static XtGeometryResult 
GeometryManager(w, request, reply) 
Widget w; 
XtWidgetGeometry *request; 
XtWidgetGeometry *reply; 
{ 
return XtGeometryYes; 
Section 12.2.6 describes what would take place in a more complex geometry_manager, 
and Section 12.4.6 provides an example. 

388 X Too&# Intrinsics Programming Manual, Motif Edition 



Xt calls parent 
geometry_manager again. 

Parent's 
geometry_manager 
analyses child suggestion and 
returns value and possibly a 
compromise. Must make 
sure this is not an infinite 
loop. XtGeometryYes 
means compromise accepted. 

If returned value is XtGeometryNo 
or XtGeometryAlmost, Xt calls 
child's set values almost 
-- _ 
method. 

Child 

Child's set values almost method 
-- _ 
proposes a new geometry based on 
information passed in, or gives up. If new 
geometry back to [- 

Figure 12-6. Geometry negotiation by the set_values_almost method 

procedure must copy the contents of the reply geometry into the request geometry; to attempt 
an alternate geometry, the procedure may modify any part of the request argument; to termi- 
nate the geometry negotiation and retain the original geometry, the procedure must set 
request->request_mode to zero. 

If geomet ry_manager returned XtGeomet ryNo, it will not have generated a compro- 
mise. In this case, the set_values_almost method may suggest a new geometry, but it 
is probably not worth it since the method has no information upon which to base its changes 
to its previous suggestion. The set__values_almost method at this point should usually 
just set request->request, mode to zero to terminate the geometry negotiation. 

12.2.7 

The insert child and delete child Methods 

The Composite class has an instance part structure that contains an array of all the widget's 
children (even those not currently managed), the current number of children, and the total 
number of child slots available. The insert child method inserts the ID of a child into 
this array. It is called when the child is created by a call to XtCreateWidget or Xt- 
CreateManagedWidget. Most widgets inherit the insert child method from the 
Composite class by specifying the symbolic constant XtInheritInsertChild in the 

Geometry Management 391 



.... Example 12-7. Form: the Core resource list (continued) 

XtRInt, 
sizeof(int), 
Offset(default_spacing), 
XtRImmediate, 
(XtPointer)4 
} 
}; 
#undef Offset 

12.4.2 

The Constraint Resource List 

The Form widget has three groups of constraint resources. XtNhorizDistance, Xt- 
NfromHoriz, XtNvertDistance, and XtNfromVert together control the initial 19o - 
sition of a child. XtNtop, XtNleft, XtNbottom, and XtNright govern repositioning 
of the child when Form is resized. The XtNresizable resource controls whether the 
geometry_manager of this widget will honor requests to change the geometry of this 
child. Note that XtNresi zable does not control whether this constraint widget can resize 
a child--only whether or not it will do so because of a request from the child.* 

For more details about how these constraint resources work, read about them on the reference 
page for the Form widget in Volume Five, X Toolkit Intrinsics Reference Manual. 

Constraint resources are also called simply constraints, particularly because they are stored 
in a Core instance field called constraints. Example 12-8 shows Form's constraint re- 
source list. 

Example 12-8. Form: constraint resource list 

static XtEdgeType defEdge = XtRubber; 

#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field) 
static XtResource formConstraintResources[] = { 
XtNhorizDistance, 
XtCThickness, 
XtRInt, 
sizeof(int), 
Offset(dx), 
XtRImmediate, 
(XtPointer)DEFAULTVALUE 
), 
{XtNfromHoriz, XtCWidget, XtRWidget, sizeof(Widget), 
Offset(horiz base), XtRWidget, (XtPointer)NULL}, 
{XtNvertDistance, XtCThickness, XtRInt, sizeof(int), 
Offset(dy), XtRImmediate, (XtPointer)DEFAULTVALUE}, 
{XtNfromVert, XtCWidget, XtRWidget, sizeof(Widget), 
Offset(vert base), XtRWidget, (XtPointer)NULL}, 

{XtNtop, XtCEdge, XtREdgeType, sizeof(XtEdgeType), 

*The fact that Form does not provide individual control over the resizability of each child is a major weakness. 

394 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 12-8. Form: constrat source t ontinue 
Offset(top), XtREdgeType, (XtPointer)&defEdge}, 
{XtNbottom, XtCEdge, XtREdgeType, sizeof(XtEdgeType), 
Offset(bottom), XtREdgeType, (XtPointer)&defEdge}, 
{XtNleft, XtCEdge, XtREdgeType, sizeof(XtEdgeType), 
Offset(left), XtREdgeType, (XtPointer)&defEdge}, 
{XtNright, XtCEdge, XtREdgeType, sizeof(XtEdgeType), 
Offset(right), XtREdgeType, (XtPointer)&defEdge}, 
{XtNresizable, XtCBoolean, XtRBoolean, sizeof(Boolean), 
Offset(allow resize), XtRImmediate, (XtPointer)False}, 
-- 
}; 
#undef Offset 
The coespondingdam structe thatthis sourcelistrences, FormConstraints, is 
defined in the pfiva include file r the widget. I definition is shown in Example 12-9. 

Examp 12-9. Form: constratda struc 
typedef struct FormConstraintsPart { 
-- 
/* 
* constraint Resources. 
*/ 
XtEdgeType 

top, bottom, /* where to drag edge on resize */ 
left, right; 
dx; /* desired horiz offset */ 
dy; /* desired vertical offset */ 
horiz base; /* measure dx from here if non-null */ 
vert base; /* measure dy from here if non-null */ 
-- 
allow resize; /* True if child may request resize */ 
-- 

int 
int 
Widget 
Widget 
Boolean 
/* 
* Private constraint variables. 
* These store the dimensions of the child prior to layout. 
*/ 
int virtual_width, virtual_height; 
/* 
* Size of this child as it would be if we did not impose the 
* constraint that its width and height must be greater than zero (0). 
*/ 
LayoutState layout_state; /* temporary layout state */ 
} FormConstraintsPart; 
typedef struct FormConstraintsRec { 
FormConstraintsPart form; 
} FormConstraintsRec, *FormConstraints; 
The consn put sucte should be consided an instance put sucte. This sucte 
has public fields set through sources and pfiva fields that hold state dam, just le an in- 
stance put sucte. No so that the FormConstraints structe is built the same 
way as instance suctes, by combining part structes r each class into a comple con- 
snt sucte. This lows subclasses of Form to cate thek own constant put structe 
and add it after the Form constant part. 

Geometry Management 395 



When a widget is created as a child of a constraint widget, the constraint instance structure 
(FormConstraintsRec, in this case) is placed in the constraints field of the Core 
instance structure. Xt makes the constraint resources stored there settable, like resources de- 
fined by the child even though they are actually defined and used by the parent. 
Note that the constraint resource list of a widget can be queried with XtGet- 
ConstraintResourceList, although this is rarely needed in widget or application 
code. 

12.4.3 Class Structure Initialization 

The Form class is a subclass of Constraint. Therefore, its class structure contains class parts 
for Core, Composite, Constraint, and Form. Example 12-10 shows the class structure initiali- 
zation of Form. Several methods referenced here have not been discussed so far in this book. 
They are the Core methods class_initialize and class_part_init, and the 
Constraint methods initialize and set values. These and all the geometry man- 
-- 
agement-related methods of Form are discussed in Section 12.4.6. 

Example 12-I0. Form: class structure initialization 

FormClassRec formClassRec = { 
{ /* Core class fields */ 
/* superclass */ 
/* class name */ 
-- 
/* widget_size */ 
/* class initialize */ 
-- 
/* class_part_init */ 
/* class inited */ 
-- 
/* initialize */ 
/* initialize hook */ 
-- 
/* realize */ 
/* actions */ 
/* num actions */ 
-- 
/* resources */ 
/* num resources */ 
-- 
/* xrm class */ 
-- 
/* compress_motion */ 
/* compress_exposure */ 
/* compress_enterleave*/ 
/* visible interest */ 
-- 
/* destroy */ 
/* resize */ 
/* expose */ 
/* set values */ 
-- 
/* set values hook */ 
__ -- 
/* set values almost */ 
__ -- 
/* get_values_hook */ 
/* accept_focus */ 
/* version */ 
/* callback_private */ 
/* tm table */ 
-- 
/* query_geometry */ 
/* display_accelerator*/ 

(WidgetClass) &constraintClassRec, 
"Form", 
sizeof(FormRec), 
ClassInitialize, 
ClassPartInitialize, 
False, 
Initialize, 
NULL, 
XtInheritRealize, 
NULL, 
0, 
resources, 
XtNumber(resources), 
NULLQUARK, 
True, 
True, 
True, 
False, 
NULL, 
Resize, 
XtInheritExpose, 
SetValues, 
NULL, 
XtInheritSetValuesAlmost, 
NULL, 
NULL, 
XtVersion, 
NULL, 
NULL, 
PreferredGeometry, 
XtInheritDisplayAccelerator, 

396 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 
/. 
}, 
{ /* 
/. 
/. 
/. 
/. 
/. 
}, 
{ /* 
/. 
/. 
/. 
/. 
/. 
/. 
/. 
}, 
{ /* 
/. 
} 
}; 

12-10. Form: class structure initialization (continued) 
extension */ NULL 

Composite class fields */ 
geometry_manager */ GeometryManager, 
change_managed */ ChangeManaged, 
insert child */ XtInheritInsertChild, 
-- 
delete child */ XtInheritDeleteChild, 
-- 
extension */ NULL 

Constraint class fields */ 

subresourses 
subresource count 
-- 
constraint size 
-- 
initialize 
destroy 
set values 
-- 
extension 

*/ formConstraintResources, 
*/ XtNumber(formConstraintResources), 
*/ sizeof(FormConstraintsRec), 
*/ ConstraintInitialize, 
*/ NULL, 
*/ ConstraintSetValues, 
*/ NULL 

Form class fields */ 
layout */ Layout 

WidgetClass formWidgetClass = (WidgetClass)&formClassRec; 
Note that the Form class is the first widget we have shown that defines a class part field--a 
method of its own, called layout. Since this method is not known to Xt, Xt will never call 
it. The widget must invoke this method itself at the appropriate times (you will see this invo- 
cation in the methods below). This code is made into a method instead of just a private func- 
tion only to make it possible for subclasses of this widget to inherit or replace the method. 
Having such a method requires that the widget have a classart_init method to 
handle the inheritance if a subclass specifies the i ayout method with the symbolic constant 
xt I nhe ri t Layout (also defined in this class's private header file). 
Section 12.2.1 described which Core and Composite methods are required for composite 
widgets, and how to initialize the other Core and Composite fields for a composite widget. 
The same is true for constraint widgets. 
However, the Constraint part is probably new to you. The ConstraintClassPart 
structure contains seven fields. The first three fields are where the constraint resource list, the 
number of resources, and the size of the constraint instance structure are entered. This re- 
source list and instance structure were described in the last section. These fields are analo- 
gous to the resources, num_resources, and widget_size fields in the Core class 
part. 
The three next fields, initialize, destroy, and set values are methods defined 
by the Constraint class. These methods have the same field names as methods of Core, but 
are fields of a different structure, and contain pointers to different functions that you may 
need to write. To differentiate Constraint methods from the Core methods, we will precede 
the names of Constraint fields with the word "Constraint" and the names of Core fields with 
the word "Core" throughout this chapter. 

Geometry Management 397 



Example 12-11. Form: the Constraint initialize method 
#define DEFAULTVALUE -9999 
/* ARGSUSED */ 
static void ConstraintInitialize(request, new) 
Widget request, new; 
{ 
FormConstraints form = (FormConstraints)new->core.constraints; 
FormWidget fw = (FormWidget)new->core.parent; 
form->form.virtual width = (int) new->core.width; 
-- 
form->form.virtual_height = (int) new->core.height; 
if (form->form. dx == DEFAULTVALUE) 
form->form.dx = fw->form.default_spacing; 
if (form->form. dy == DEFAULTVALUE) 
form->form.dy = fw->form.default_spacing; 
) 
Note that the Constraint instance part structure (FormConst taints) and the Form widget 
instance structure (FormWidget) are accessed by casting two different fields of the child's 
instance structure passed in. 
The Constraint initialize method and the child's Core initialize are passed the 
same two copies of the child's instance structure: request, and new. The request 
widget is the widget as originally requested. The new widget starts with the values in the 
request, but it has already been updated by calling all superclass initiali ze methods. 

12.4.5 

The class_part_init Method 

The class_part_init method should be present in a class that defines new methods in 
its class part structure. These new methods will never be called by Xt since Xt has no knowl- 
edge of when to call them. They can only be invoked directly from the widget code. The 
purpose of making them methods instead of just functions is to allow subclasses to inherit or 
replace the functions. The class___part_init method actually resolves this inheritance 
by setting each method field to the pointer provided by this class (the subclass is inheriting 
the method) or to the pointer provided by the subclass (the subclass is replacing the method). 
Example 12-12 shows a class___part_init method for a class that defines only one new 
method in its class part structure. This method is the Form widget's layout code. 

Example 12-12. Form: the class_part_init method 
static void ClassPartInitialize(class) 
WidgetClass class; 
{ 
register FormWidgetClass c = (FormWidgetClass) class; 
if (c->form class.layout == XtInheritLayout) 
c->form--class.layout = Layout; 
) 
The XtInheritLayout symbol is defined in the private include file for any class that de- 
fines new class part methods (one for each new method). Its value is always _XtInherit. 

Geometry Management 399 



!.#i::#i if ( (request->request mode & - (XtCWQueryOnly I 
--:-.-.:-:.:.. __ 
'form->form.allow resize) 
.:i:.ii... return XtGeometryNo; 
.-.:.:.:.:.:.: 
iiiii.ii if (request->request_mode & CWWidth) 
iii.!ii allowed, width = request->width; 
m allowed, width = w->core, width; 
if (request->request_mode & CWHeight) 
allowed, height = request->height; 
else 
allowed.height = w->core.height; 
-. if (allowed.width == w->core.width && allowed.height 
w->core, height ) 
return XtGeometryNo; 
if (! (request->request_mode & XtCWQueryOnly)) { 
/* reset virtual width and height. */ 
form->form.virtual width = w->core.width = allowed.width; 
-- 
form->form.virtual_height = w->core.height = allowed.height; 
RefigureLocations((FormWidget)w->core.parent) ; 
-. 
} 
:.. return XtGeometryYes; 
} 
The RefigureLocations called from the geometry_manager method is a private 
function analogous to the DoLayout roufne used in ScrolIBox, except that Refigure- 
Locations calls Form's layout method that conhns the actual layout code so that the 
method can be inherited or replaced by subclasses. The layout method calculates a layout 
and moves and resizes the children. RefigureLocations is also called from the 
change_managed method, as described in Section 12.4.9. Example 12-14 shows the 
RefigureLocations function and Form's layout method, which it calls. (The if 
statement that branches depending on the value of the no_refigure field allows an appli- 
cation to turn relayout on and off, as described in Section 12.4.11.) 

Example 12-14. Form: private functions: RefigureLocations and the layout method 
static void RefigureLocations(w) 
FormWidget w; 
( 
/* no refigure supports the relayout recalculation 
-- 
delay described later in this chapter */ 
if (w->form.no_refigure) { 
w->form.needs relayout = True; 
-- 
) 
else { 
(* ((FormWidgetClass) w->core, widget_class) ->form_class. layout ) 
( w, w->core.width, w->core.height ); 
w->form.needs relayout = False; 
-- 
) 
) 

/* ARGSUSED */ 

Geometry Management 401 



Examp 12-14. Form: priva nctions: RefigureLocations and e layout meod Con- 
tinue 
static Boolean Layout(fw, width, height) 
FormWidget fw; 
Dimension width, height; 
{ 
int num children = fw->composite.num children; 
-- _ 
WidgetList children = fw->composite.children; 
Widget *childP; 
Position maxx, maxy; 
static void LayoutChild(); 
Boolean ret val; 
-- 
for (childP = children; childP - children < hum children; 
-- 
childP++) { 
FormConstraints form = (FormConstraints) 
(*childP)->core.constraints; 
form->form.layout_state = LayoutPending; 
} 
maxx = maxy = I; 
/* 
* Layout children one at a time, and determine 
* necessary size for self 
*/ 
for (childP = children; childP - children 
< hum children; childP++) { 
-- 
/* 
* Layout child then find position of bottom right 
* outside corner of child 
*/ 
if (XtIsManaged(*childP)) { 
Position x, y; 
LayoutChild(*childP); 
x = (*childP)->core.x + (*childP)->core.width 
+ ((*childP)->core.border width << I); 
-- 
y = (*childP)->core.y + (*childP)->core.height 
+ ((*childP)->core.border width << I); 
-- 
if (maxx < x) maxx = x; 
if (maxy < y) maxy = y; 
} 
} 
fw->form.preferred_width = (maxx += fw->form.default_spacing); 
fw->form.preferred_height = (maxy += fw->form.default_spacing); 
/* Now ask parent to resize us. If it says Almost, accept the 
* compromise. If Almost and parent chose smaller size, or No 
* and we were smaller than necessary, children will be clipped, 
* not laid out again. 
*/ 
if (fw->form.resize_in_layout 
&& (maxx != fw->core.width II maxy != fw->core.height)) { 
XtGeometryResult result; 
result = XtMakeResizeRequest( fw, (Dimension)maxx, 
(Dimension)maxy, (Dimension*)&maxx, 
(Dimension*)&maxy); 
if (result == XtGeometryAlmost) 

402 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example 12-14. Form: private functions: RefigureLocations and the layout method (con- 
tinued) 
result = XtMakeResizeRequest( fw, (Dimension)maxx, 
(Dimension)maxy, NULL, NULL ); 
fw->form.old width = fw->core.width; 
-- 
fw->form.old_height = fw->core.height; 
ret val = (result == XtGeometryYes); 
-- 
} else ret val = False; 
-- 
return ret val; 
-- 
) 
The layout method treats one child at a time, first initializing the layout_state pri- 
vate constraint instance field of each child to LayoutPending. The LayoutChild rou- 
tine will start from this value. Next, it calls LayoutChild for each child, and at the same 
time keeps a running total of the sizes of the children so that when the loop is finished it 
knows how big to be to fit all the children. Finally, it requests of its parent that it be just big 
enough to fit its children. If the parent denies the request, the code makes no attempt to make 
another request. If the parent offers a compromise, it is accepted. The Form widget, in either 
case, may be too big or too small to fit its children. If it is too small, some of its children will 
be clipped. 
The LayoutChild routine is shown in Example 12-15. What it does is simple, although it 
is a little hard to follow because it is called recursively. It moves the child according to the 
XtNfromHori z and XtNfromVert constraint resources.* These resources specify that 
a child be placed to the right of or below another particular child. 

Examp 12-15. Form: e LayoutChild private nction 
static void LayoutChild(w) 
Widget w; 
{ 
FormConstraints form = (FormConstraints)w->core.constraints; 
Position x, y; 
Widget ref; 
switch (form->form.layout_state) { 
case LayoutPending: 
form->form.layout_state = LayoutInProgress; 
break; 
case LayoutDone: 
return; 
case LayoutInProgress: 
String subs[2]; 
Cardinal hum subs = 2; 
-- 
subs[0] = w->core.name; 
subs[l] = w->core.parent->core.name; 
XtAppWarningMsg(XtWidgetToApplicationContext(w), 
"constraintLoop","xawFormLayout", 
"XawToolkitError", "constraint loop\ 

*Form resizes children only when it is resized--never during normal layout. 

Geometry Management 403 



Example 12-15. Form: the LayoutChild private function (continued) 

detected while laying out child\ 
'%s' in FormWidget '%s'", 
subs, &hum subs); 
-- 

return; 
} 
x = form->form.dx; 
y = form->form.dy; 
if ((ref = form->form.horiz base) != (Widget)NULL) { 
-- 
LayoutChild(ref); 
x += ref->core.x + ref->core.width + 
(ref->core.border width 
-- 
<< i); 
} 
if ((ref = form->form.vert base) != (Widget)NULL) 
-- 
LayoutChild(ref); 
y += ref->core.y + ref->core.height + 
(ref->core.border width 
-- 
<< i); 
} 
XtMoveWidget( w, x, y ); 
form->form.layout_state = LayoutDone; 

} 
If neither XtNfromHori z nor XtNfromVert are set for the child, it is simply placed the 
default distance from the top-left comer of the Form. When one child is set, the next child 
must be placed relative to that child. However, the other child may be later in the list and not 
properly positioned yet. Therefore, the code calls LayoutChild to lay out the child that 
this child is positioned relative to. 
The layout_state field catches circular settings for the XtNfromHoriz and Xt- 
NfromVert resources. For example, if widget A is specified to the right of widget B, and 
widget B is specified to the right of widget A, there is no solution. LayoutChild would be 
caught in an infinite loop of calling itself. When first called from the layout method, the 
layout_state is LayoutPending. This is changed to LayoutInProgress in the 
switch statement. If the function is called again for the same child, this state will cause the 
warning message to be printed and the function to exit. The Form widget does not exit--it 
just gives up processing the invalid constraint resource setting and prints a warning message. 

12.4.7 

The resize Method 

The resize method calculates a layout to fit in the new dimensions of Form and moves and 
resizes the children accordingly. Form's resize method is shown in Example 12-16. It 
consists of a loop that treats each managed child one at a time. The position and dimensions 
of each child are calculated with the help of the private function TransformCoord (also 
shown in Example 12-16) and the child is moved and resized. TransformCoord handles 
one parameter at a time, and uses a position, the size before resizing, the size after resizing, 
and the constraints settings to arrive at the appropriate value for the parameter. The old 

404 X Toolkit Intrinsics Programming Manual Motif Edition 



width and height of the Form widget are initialized in the Core initialize method and 
updated at the end of the resi ze method. 

Examp 12-1& Form: e rese meod 
static void Resize(w) 
Widget w; 
{ 
FormWidget fw = (FormWidget)w; 
WidgetList children = fw->composite.children; 
int hum children = fw->composite.num children; 
Widget *childP; 
Position x, y; 
Dimension width, height; 
for (childP = children; childP - children < hum children; 
childP++) { 
FormConstraints form = (FormConstraints) 
(*childP)->core.constraints; 
if (!XtIsManaged(*childP)) continue; 
x = TransformCoord( (*childP)->core.x, fw->form.old_width, 
fw->core.width, form->form.left ); 
y = TransformCoord( (*childP)->core.y, fw->form.old_height, 
fw->core.height, form->form.top ); 
form->form.virtual width = 
TransformCoord((Position) ((*childP)->core.x 
+ form->form.virtual width 
+ 2 * (*childP)->cor.border width), 
fw->form.old_width, fw->core.width, 
form->form.right ) 
- (x + 2 * (*childP)->core.border width); 
form->form.virtual_height = 
TransformCoord((Position) ((*childP)->core.y 
+ form->form.virtual height 
+ 2 * (*childP)->core.border width), 
fw->form.old_height, fw->core.height, 
form->form.bottom ) 
- ( y + 2 * (*childP)->core.border width); 
width = (Dimension) 
(form->form.virtual width < I) ? 1 : 
form->form.virtual width; 
height = (Dimension) 
(form->form.virtual_height < I) ? 1 : 
form->form.virtual_height; 
XtConfigureWidget( *childP, x, y, (Dimension)width, 
(Dimension)height, (*childP)->core.border width); 
fw->form.old width = fw->core.width; 
fw->form.old_height = fw->core.height; 

static Position TransformCoord(loc, old, new, type) 
register Position loc; 
Dimension old, new; 
XtEdgeType type; 

Geometry Management 405 



Example 12-16. Form: the resize method (continued) 

if (type == XtRubber) { 
if ( ((int) old) > 0) 
loc = (loc * new) / old; 
} 
else if (type == XtChainBottom I  type == XtChainRight) 
loc += (Position) new - (Position) old; 
return (loc) ; 
} 
This resize method stores the new size of the children in the virtual width and 
virtual_height cons[rsint part fields, and uses the previous vzlues to ardve at the 
new size. This is done because Form's XtNtop, XtNbottom, XtNleft, and XtNright 
constraints specify the geometry of the child based on its previous geometry. 
Notice that the for loop in this particular resize method loops through the children di- 
rectly, using pointer arithmetic. This is equivalent to using a loop that increments an integer 
and then uses the integer to index the children array. For example, the first five lines of 
the loop could also be expressed as: 
int i ; 
for (i = 0; i < hum children; i++) { 
FormConstraints form = (FormConstraints) 
(children [i] ) ->core. constraints; 
if (!XtIsManaged(children[i])) continue; 
x = TransformCoord( (children[i])->core.x, 
fw->form.old_width, fw->core.width, form->form.left ) ; 

12.4.8 

The Core and Constraint set values Methods 

When the application calls xtSetValues to set the resources of a child of a constraint 
widget, Xt calls the child's Core set__values method and then the parent's Constraint 
set values method. Both methods are passed the same arguments. Constraint 
-- 
set_values validates the ranges of constraint resource settings and computes the value of 
any private constraint instance part fields that depend on constraint resource values. It 
should also set child Core geometry fields to match the changes in constraint resources. For 
example, if a constraint for the maximum height of a widget is changed to a value smaller 
than the widget's current height, then the Constraint set values procedure should reset 
-- 
the height field in the widget. 
Both Core and Constraint set values must return True or False to indicate whether 
redisplay of the widget is necessary. For composite and constraint widgets, this value is 
usually meaningless because there is nothing to redisplay. But these might be useful if, for 
some reason, you write a composite widget that does have display semantics. 

406 X Toolkit Intrinsics Programming Manual, Motif Edition 



12.4.10 The query_geometry Method 

Form's query_geometry method (shown in Example 12-18) is the minimal version, al- 
most identical to the one described for simple widgets in Chapter 7, Basic Widget Methods. 
The preferred_width and preferred.height instance variables are set in the 
Form class Layout method to the size that just fits the current layout. 

Examp 12-1 Form: e que_geomet meod 
static XtGeometryResult PreferredGeometry( widget, request, reply 
Widget widget; 
XtWidgetGeometry *request, *reply; 
( 
FormWidget w = (FormWidget)widget; 

reply->width = w->form.preferred_width; 
reply->height = w->form.preferred_height; 
reply->request_mode = CWWidth I CWHeight; 
if ( request->request_mode & (CWWidth I CWHeight) 
reply->request_mode & CWWidth I CWHeight 
&& request->width == reply->width 
&& request->height == reply->height) 
return XtGeometryYes; 
else if (reply->width == w->core.width && reply->height == 
w->core.height) 
return XtGeometryNo; 
else 
return XtGeometryAlmost; 

12.4.11 

Delaying Geometry Recalculation 

During an application's initial layout, the change_managed method of a composite widg- 
et is called only once even though many children may have been managed. However, after 
that, change_managed is called once for every child that changes management state. 
Many composite or constraint widgets, especially ones that have complicated layout code, 
provide a public function (such as the one shown in Example 12-19) that the application can 
call to turn off layout recalculation until a group of windows is managed or unmanaged, and 
then call again to trigger recalculation once the whole group of children has been managed or 
unmanaged. 
To implement this delay, you need an instance variable to hold a Boolean value indicating 
whether to delay or not (no_refigure, in this case). You set and unset this variable in 
this public routine and you test it in change_managed. 

408 X Toolkit Intrinsics Programming Manual Motif Edition 



Examp 12-19. Form: Me publ nction r delaying calls  change_managed 
void XawFormDoLayout(w, doit) 
Widget w; 
Boolean doit; /* False, don't recalculate; True, do */ 
{ 
register FormWidget fw = (FormWidget)w; 

fw->form.no_refigure = !dolt; 

if (XtIsRealized(w) && fw->form.needs_relayout ) 
RefigureLocations( fw ); 

12.5 

Compound Widgets 

A compound widget is a combination of widgets put together to make a higher-level, user-in- 
terface object. For example, a ScrolledWindow widget is itself a composite widget, but it 
automatically creates its own ScrollBar children. Similarly, the code for MessageBox can 
create its own Shell parent, and it creates PushButtonGadget children that read OK, Cancel, 
and Help. 
Compound widgets create their children in their initialize method, and set resources to 
position them. Often they also provide resources of functions that make it easy for the appli- 
cation to configure some characteristics of their children. The application can manipulate the 
children only through these resources, because it cannot access the widget IDs of the com- 
pound widget's subwidgets without breaking the rules of data hiding. Thus, compound widg- 
ets are convenient for programming, but they make it more difficult to take advantage of all 
the configurable aspects of the subwidgets. 
The main widget of the compound widget may be a subclass of Core, Composite, or Con- 
straint. If it is a subclass of Core, the widget manages the positions and sizes of its children 
manually whenever it is resized. The success of this strategy is dependent on the children 
never trying to resize themselves and on the application never trying to resize the children di- 
rectly.* The latter will not be a problem unless the application breaks the data-hiding rules 
by manipulating the child directly. The Text widget is an example of this kind of widget. It 
creates and manages its own scrollbar. 
Compound widgets normally define only a few methods and inherit the rest. Compound 
widgets based on Core will move and resize their children manually in their resize meth- 
od. If the widget is a subclass of Composite or Constraint, the normal geometry management 
facilities manage the position and size of the children. If it is a subclass of Constraint, the 
main widget sets the constraints of the children to control the geometry management process 
by providing a Constraint i ni t: i a 1 i z e method. 

*When a child of a simple widget calls XtMakeGeometryRequest because it wants to change its size, Xt- 
MakeGeometryRequest always makes the requested changes and returns XtGeometryYes. Therefore, a 
simple widget parent really has no control over its child if the child wants to resize itself. A simple widget cannot 
even tell that the child has resized itself. 

Geometry Management 409 



A compound widget always needs a destroy method that destroys the children it created. 
Compound widgets also need a set_values method to manage their resources. 

12.6 Stacking Order 

We promised earlier to say a bit more about how composite or constraint widgets can control 
the stacking order of their children. We noted that this must be done manually, because Xt 
doesn't provide much support for it. This is because most applications do not stack widg- 
ets--the whole concept of geometry management is based on each widget trying to lay out 
its children without stacking them. However, there are applications where it makes sense to 
stack widgets. For example, an application that provides note cards, where each card is a 
widget, would want to stack them showing only the corner of hidden cards. 
There is no Core resource for stacking order, and therefore it can't be set with xtset- 
Values unless you define the resources in your own widget class. Xt provides no call to 
restack windows; you must use the Xlib functions XConfigureraindow, XRestack- 
raJ_ndows, XRa J. s eraJ_ndow, or XLowe z:raJ_ndow. When a widget suggests a stacking or- 
der for itself through its query_cjeornet z:y method, Xt takes care of making the required 
Xlib call if the parent agrees with the change. However, stacking requests of unrealized 
widgets have no effect (so stacking order won't be set this way in the initial geometry negoti- 
ation). Therefore, the most robust method to handle stacking order is for your composite 
widget to make the appropriate Xlib calls directly to change the stacking order of its chil- 
dren. XRestackraindows is probably the best call to use. Since restacking the windows 
doesn't change their requirements for screen space, it shouldn't affect either the parent or the 
children adversely. The appropriate place to call XRestackraindows depends on when 
you want to change the stacking order. (Note that the stacking change won't become visible 
until the next time Xt is waiting for an event.) 
You can control the initial stacking order of a group of children by creating them in the de- 
sired order. The most recently created widget appears on the bottom. (This is the opposite of 
what you might expect if you know that newly created X windows appears on top of their 
siblings. The difference is due to the way a composite widget maintains its list of children.) 

410 X Too/k# Intrinsics Programming Manual, Motif Edition 



13 

Menus, Gadgets, and 
Cascaded Popups 

This chapter begins by describing how to use Motif popup and cascaded 
menus. Then it describes how menus actually work, and several ways to 
create menu widgets. One of these ways involves the use of windowless 
widgets, or gadgets. This chapter also describes how to use more advanced 
features of the Xt pop up mechanism, including modal cascades, to imple- 
ment cascading pop up menus and dialog boxes. 

In This Chapter: 

Menu Styles and Implementation ....................................................... 415 
Using Motif Menus ............................................................................. 416 
Popup Menus ................................................................................ 417 
Cascaded Menus ........................................................................... 418 
Basic Xt Popup Support ..................................................................... 419 
A Spring-Loaded Menu: Pointer Grabbing ..................................... 420 
A Pulldown Menu ........................................................................... 428 
Cascaded Menus ........................................................................... 431 
Using the R4 SimpleMenu Widget .................................................. 436 
Delayed Popup Creation ................................................................ 440 
About Dialog Boxes ........................................................................... 441 
Gadgets ............................................................................................. 442 
Inside a Gadget ............................................................................. 445 
Private Header File ........................................................................ 445 
The Gadget Source File ................................................................. 447 
The Public Header File ................................................................... 448 
The Gadget Parent ........................................................................ 448 



while the other two types may have different contents in any particular invocation, showing 
the settings invoked the previous time or all previous times, or a modified list of choices. 

Menus are one of the most important user-interface dements in window-based applications. 
They offer the same feature as push buttons--a way for the user to invoke application func- 
tions or set parameters--but in a more organized and more easily accessible fashion when 
there are more than a few buttons. 

Figure 13-1 compares a menu to a box full of buttons. 

lVieu Nextl[Vieu Previous IDelete 
IUnmork IV-  k--e-e]lReoly lluse 

MAIN MENU 
View Next 
View Previous 
Delete 
Move 
Copy 
Unmark 
View In New 
Reply 
Forward 
Use As Comp 

Figure 13-1. Athena Command widgets in an Athena Box widget, and the same commands as 
a Motif menu 

The menu takes up less space because only its title is visible until it is called up.* As a result, 
you can have more menus than you could have permanent button boxes. Commands can be 
presented in smaller, more closely related groups. The user will spend less time searching for 
the desired command. 

The commands in the menu are also easier to read because they are arranged one per row. 
The commands in the menu may even be easier to invoke because it is more natural to drag 
the mouse up and down than from side to side. And last but not least, menus avoid the worst 
problem with button boxes: when the application is resized, button boxes may place each 
command widget in a different position, making it more difficult for the user to find com- 
mands.T 

*Some menus don't even display a tide--they simply pop up at the pointer position in response to a particular point- 
er button/keypress combination. This is the behavior of the menus provided by xterm and the system menu of mwm. 
However, this is not very desirable behavior from a user-interface point of view, since it gives the user no visual feed- 
back that a menu is available or how to invoke it. The user needs the manual--something graphical user interfaces 
are designed to avoid. 
'To be fair, there is something to be said for the fact that all the available commands are always visible in an applica- 
tion that uses button boxes. You can invoke a button in a box with just a button click, while in a menu it requires a 
press, a drag, and a release. When there are only a small number of commands, putting the command widgets in a 
box is probably better than using a menu. 

414 X Toolkit Intrinsics Programming Manual, Motif Edition 



Some of the applications in the core distribution from MIT use button boxes instead of menus 
because there was no menu widget in the Athena widget set until Release 4. And some of the 
applications that do use menus have implemented them directly with Xlib. 

13.1 

Menu Styles and Implementation 

The conventions for the appearance and user interface of menus (look and feel) in widget sets 
probably varies more than any other aspect of the user interface. 
There are several different styles of menus. As we've pointed out earlier, a button box is 
itself a style of menu. However, in this chapter we will be focusing on popup 
menusmmenus that are not visible until the user presses a pointer button or a key-button 
combination. 
There are several different styles of popup menu. Probably the most familiar is the pulldown 
menu popularized by the Apple Macintosh. A pulldown menu has a label permanently visi- 
ble in the application, usually on a menu bar at the top. When the pointer is clicked on the 
label, and then dragged downwards, the menu is pulled down like a window shade, and 
remains displayed as long as the pointer button is depressed. The currently selected item (as 
indicated by the pointer position within the menu) is highlighted, and is executed when the 
pointer button is released. 
The variation adopted by Motif and OPEN LOOK (possibly to avoid legal entanglements with 
Apple) is a menu in which the pointer need not be dragged down to display the menu. 
Instead, it appears below the menu title as soon as the button is depressed in the menu title. 
The distinction between pulldown and drop-down menus is a subde one. 
In some cases, selecting an item on the menu or moving off the right side of certain menu 
panes causes a second menu to appear next to the first (usually to the right). This is referred 
to as a cascading menu. (Another type of cascading popup is a dialog box that pops up 
another dialog box.) 
Finally, there is the pure spring-loaded popup menu used by many of the standard X clients, 
which displays no menu label, and simply pops up at the pointer position, given the appropri- 
ate key or button press. For example, the menus in xterm pop up when you hold the Control 
key and press the first or second button while the pointer is anywhere in the xterm window. 
Motif calls this type of menu simply a popup menu (as opposed to pulldown or option 
menus). We will refer to these menus using the term spring-loaded since the term popup is 
too generic. 
One can also imagine many other possible menu styles. For example, an effective user 
interface could be constructed using only horizontal menus, emulating the single-line menu 
popularized by Lotus for its character-based 123 spreadsheet. Any given button might either 
execute an action, or pop up a lower-level menu, which would overlay (and thus appear to 
replace) the first menu. 
In this chapter, though, we will focus on the two styles of menu you are most likely to 
encounter in X applications: the pulldown menu and the pure spring-loaded popup menu. 

Menus, Gadgets, and Cascaded Popups 415 



In code, the difference between spring-loaded and pulldown menus is primarily the method 
by which the user invokes the menu and where the menu is placed; one menu widget class 
can usually work in either way. In Modf, both the pulldown and popup menu styles are actu- 
ally RowColumn widgets inside Shell widgets, but they are popped up in slightly different 
ways. 

All the differences described so far concern user-interface conventions. The Xt specification, 
however, classifies popups using a different criteria--while the menu is popped up, how is 
input dispatched to other parts of the application and to other applications? Also, is the menu 
subject to window management? The three styles are called modeless popups, modal popups, 
and spring-loaded popups. 

Modeless popups are windows that, once popped up, are subject to window manager control, 
and for all intents and purposes act like regular applications in themselves. A help window 
that stayed up, and could be moved and resized like a regular window once popped up, is an 
example of this type of popup. It is referred to as "modeless" because it doesn't put the 
application into a special mode, in which only input to the popup is allowed. 

A modal popup may or may not be visible to the window manager, but it always disables 
user-event processing by the application, except in the popup itself. A dialog box that 
requires the user to enter data or click on a button is an example of a modal popup. Input 
may still be possible to other applications. 

As defined by Xt, a spring-loaded popup is invisible to the window manager and disables 
user input to all windows in all applications, except to the popup itself. The most important 
thing about spring-loaded popups is that they are invoked with a key or pointer button press, 
whereas another type of popup might be invoked as a routine part of application processing, 
or just because the pointer entered a particular window. Note that even though the term 
spring-loaded has been used in two different contexts above, both actually refer to the same 
kinds of widgets. The first use referred to a characteristic user-interface style, and the second 
to a characteristic absence of window management and disabling of input to other applica- 
tions. Throughout this chapter, though, we use the term "spring-loaded popup" to refer to 
menus that pop up at the pointer position when a mouse button is pressed, such as that used 
by xterm, as opposed to popup or pulldown menus. 

13.2 

Using Motif Menus 

Chapter 3, More Techniques for Using Widgets, showed how to create and use a Motif pull- 
down menu. This section demonstrates how to use a Motif popup menu, and then shows how 
to implement cascaded menus--menus that pop up other menus. 

The forthcoming Volume Six, X Motif Programming Manual, will describe more thoroughly 
how to use menus, such as how to add mnemonics and accelerators. 

416 X Too&# Intrinsics Programming Manual Motif Edition 



Each of these ways is appropriate for different situations, and they are often used in combina- 
tion. Each is described in the sections below. 
Passive global grabs can be invoked directly using the Xt functions XtGrabButton and 
XtGrabKey. However, Xt takes care of making the appropriate passive global grab if you 
use XtPopupSpringLoaded or the XtMenuPopup action to pop up your shell widget. 
As we will see, the other ways to pop up a widget do not make any global grab, which makes 
them inappropriate for popping up main menus.* However, they are still useful for some 
types of dialog boxes and for cascading submenus, if the main menu has used XtMenu- 
Popup to assert an exclusive grab. We'll return to this subject in Section 13.3.3. 
A popup menu globally grabs the pointer to force the user to make a menu choice before 
leaving the menu, or to pop down the menu if no choice is made. However, this global grab 
is necessary for another reason as well. The X server automatically grabs the pointer begin- 
ning at a button press and ending at the release of the same button. Since the initial button 
press pops up the menu, the next button release would also arrive at the same widgetmthe 
application main window or the menu title--even if the pointer were already in the menu. 
Furthermore, the application main window would get all EnterNotify and Leave- 
Notify events, so the Command widgets in the menu wouldn't get any of them. When the 
menu is popped up with XtMenuPopup action, the passive global grab it makes cancels the 
automatic global grab. (Again, pointer grabs redirect only the events caused directly by the 
pointer; ButtonPress, ButtonRelease, EnterNotify, LeaveNotify, and 
MotionNotify. All other events (most notably Expose events) occur and are delivered 
normally.) 
With that background, let's take a look at an application that provides a spring-loaded menu. 
The xmenul application's permanent appearance is a variation of xbox; it displays a large 
Label widget that we are using to simulate an application's main window and a Command 
widget for quitting. Pressing any button in the Label widget calls up the menu, which oper- 
ates as described at the beginning of this section, xmenul is shown in Figure 13-2. As usual, 
we suggest you compile and run this example now. 
The relevant code in xmenul consists of an action routine to place the popup, code to add the 
action, a callback routine to handle when a menu item has been chosen, and code to create 
the Box populated with Command widgets that will act as the menu. Example 13-3 shows 
the complete code. 

Examp 13-3. xmenul: compcode 
/, 
* xmenul.c - simple spring-loaded menu 
*/ 
#include <stdio.h> 
/* 
* Standard Toolkit include files: 

*With XtPopupSpri ngLoaded you can write callback functions that are the equivalent of XtCal iback*, ex- 
cept that they will pop up a menu with the necessary passive global grab. You can also write your own version of the 
XtMenuPopup action if it doesn't do what you want. You will need XtRegisterGrabAction to do this. 
This function tells Xt to automatically start a passive global grab whenever a certain action is invoked. 

422 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 13. xmenul: compcode ontinue 
) 
/* 
* quit button callback function 
*/ 
/*ARGSUSED*/ 
void Quit(w, client data, call data) 
-- -- 
Widget w; 
XtPointer client_data, call_data; 
( 
exit(0); 
} 
/* 
* menu pane button callback function 
*/ 
/*ARGSUSED*/ 
void PaneChosen(w, client data, call data) 
-- -- 
Widget w; 
XtPointer client_data; /* cast to pane_number */ 
XtPointer call data; 
-- 
( 
int pane_number = (int) client_data; 
printf("Pane %d chosen.\n", pane_number); 
XtPopdown(pshell); 
} 
main(argc, argv) 
int argc; 
char **argv; 
( 
XtAppContext app_context; 
Widget topLevel, box, quit, label, menulabel, menubox, 
menupane|10]; 
int i; 
String buf[50]; 
static XtActionsRec trial actions|] = { 
-- 
{"placeMenu", PlaceMenu}, 
); 
topLevel = XtVaAppInitialize( 

&app_context, 
"XMenul", 
NULL, 0, 
&argc, argv, 
NULL, 
NULL); 

/* Application context */ 
/* application class name */ 
/* command line option list */ 
/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

box = XtCreateManagedWidget( 

"box", 
boxWidgetClass, 
topLevel, 
NULL, 
0 
); 

/* widget name */ 
/* widget class */ 
/* parent widget*/ 
/* argument list*/ 
/* arglist size */ 

label = XtCreateManagedWidget( 
"label", /* widget name */ 

424 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp 13-3. xmenul: compcode (continue 
labelWidgetClass, /* widget class */ 
box, /* parent widget*/ 
NULL, /* argument list*/ 
0 /* arglist size */ 
); 
quit = XtCreateManagedWidget( 
"quit", /* widget name */ 
commandWidgetClass, /* widget class */ 
box, /* parent widget*/ 
NULL, /* argument list*/ 
0 /* arglist size */ 
); 
pshell = XtCreatePopupShell( 
"pshell", 
transientShellWidgetClass, 
topLevel, 
NULL, 
0 
); 
menubox = XtCreateManagedWidget( 
"menubox", /* widget name */ 
boxWidgetClass, /* widget class */ 
pshell, /* parent widget*/ 
NULL, /* argument list*/ 
0 /* arglist size */ 
); 

menulabel = XtCreateManagedWidget( 

"menulabel", 
labelWidgetClass, 
menubox, 
NULL, 
0 
); 

/* widget name */ 
/* widget class */ 
/* parent widget*/ 
/* argument list*/ 
/* arglist size */ 

for (i = 0; i < i0; i++) { 
sprintf(buf, "menupane%d", i); 
menupane[i] = XtCreateManagedWidget(buf, /* widget name */ 
commandWidgetClass, menubox, NULL, 0); 
XtAddCallback(menupane[i], XtNcallback, PaneChosen, i); 
XtAppAddActions(app_context, trial_actions, 
XtNumber(trial actions)); 
-- 
XtAddCallback(quit, XtNcallback, Quit, 0); 

XtRealizeWidget(topLevel); 

XtAppMainLoop(app_context); 

The PlacePopup action just places the popup slightly to the left and above the position 
where the pointer button that popped it up was clicked, using the coordinates reported in the 
button event. The offset of ten pixels from the pointer position simply helps to make sure 

Menus, Gadgets, and Cascaded Popups 425 



that the pointer is inside the menu.* Remember that the window created by a popup shell 
widget is a child of the root window and therefore is placed relative to the root window. The 
ButtonPross event pointer coordinates relative to the root window are used. 
The PanoChoson callback function is a stub function used in this example as the notify 
callback for all the menu panes. In this example, it simply prints the name of the chosen pane 
to stdout and then pops down the menu using XtPopdown. In a real application, a different 
callback function would probably be registered for each pane. 
Instead of calling XtPopdown in each of these separate callback functions, you could write 
a single additional callback function that calls XtPopdown, and then add it to the callback 
list for the Command widget that makes up each menu pane. 
As usual, the popup is created by first creating a popup shell, then a Box widget as its child, 
and then a series of Label and Command widgets as children of Box. The popup shell and 
the box are invisible. As with all menus, what you actually see is the array of children. 
Note that this program does not include any code that would pop up the menu. We've done 
that from the app-defaults file shown in Example 13-4. The translations we have defined for 
the Label widget invoke Xt's built-in XtMonuPopup action. 

Example 13-4. XMenul : the app-defaults file 

! Appearance Resources 
. 
*quit.label: Quit 
*label.label: This is a Pretend Main Window; Press in here. 
*menulabel.label: MAIN MENU 
, 
! make all entries in menu same width 
! (needs adjusting for longest entry) 
*menulabel.width: 135 
*menubox.Command.width: 135 

! 
! Pane Strings 
! 
*menupane0.1abel: View Next 
*menupanel.label: View Previous 
*menupane2.1abel: Delete 
*menupane3.1abel: Move 
*menupane4.1abel: Copy 
*menupane5.1abel: Unmark 
*menupane6.1abel: View In New 
*menupane7.1abel: Reply 
*menupane8.1abel: Forward 
*menupane9.1abel: Use As Comp 
, 
! make Box 

leave no space around Command widgets in menu 

*It is important to provide a consistent user interface, so you should use the same offset in all menus. Menus in com- 
mercial widget sets such as the OPEN LOOK widgets have carefully designed and documented policies about popup 
window placement. This allows the user's "pointer reflexes" to be trained, so that using menus becomes as automatic 
and easy as possible. 

426 X Toolkit Intrinsics Programming Manual, Motif Edition 



13.3.2 A Pulldown Menu 

What are the desired characteristics of a pulldown menu? There is a Command widget or the 
like permanently visible in the application, with a label indicating some common characteris- 
tic of the items in the menu. When a button is pressed in this widget, the menu should pop up 
on or just below the button. Dragging the pointer down through the menu with the button 
still held should highlight the entry that is pointed to. Releasing the button in an entry should 
invoke or set that entry and pop down the menu. Moving out of the menu should not change 
this behavior, except that if the button is released anywhere outside of a menu pane, the menu 
should pop down without executing any entry. 

If you compile and run xmenu2 you can try out this style of menu. The appearance of this 
application is shown in Figure 13-3. 

MIN MENU 
View Next 
View Previous 

Delete 

Move 
Copy 
Unmark 
View In New 
Reply 
Forward 
Use fis Comp 

Figure 13-3. xmenu2: a pulldown menu 

Invoking a menu as a pulldown is a simple enhancement of the spring-loaded invocation 
method just shown. We can do everything exactly the same as in the spring-loaded example, 
except that a pulldown menu should appear just below the pressme widget, not at the posi- 
tion of the pointer. Therefore, all we need to change is the placement code. However, since 
the coordinates in the event are not necessary for placing the popups, we can use a callback 
function instead of an action to place the popup. (In general, it is better to use an existing 
callback than to add an action to do the same thing.) 
Popup shell widgets have XtNpopupCallback and XtNpopdownCallback callback 
resources; the functions on these callback lists are called whenever the popup is popped up or 
down using any of the Xt mechanisms. 
In the last example we created an action called PlaceMenu, that moves the popup shell 
before it was actually popped up. We included it in a translation along with the standard 
action XtMenuPopup, which was actually used to pop up the widget, xmenu2 also uses the 
standard action XtMenuPopup to pop up the widget, but it uses the 

428 X Toolkit Intrinsics Programming Manual Motif Edition 



XtNpopupCallback resource to provide the code to place the widget. Using the call- 
back saves having to reference the placement action in the translation table. This is prefera- 
ble, since the placement code should almost always be hardcoded rather than user-configur- 
able. Another advantage of the popup and popdown callbacks is that you may arrange for a 
popup to be popped up or down in more than one way, and it may be convenient to have cer- 
lain code called automatically in all cases. 
(You can also use the XtNpopupCallback resource to specify a callback function to cre- 
ate a popup widget the first time it is popped up, instead of at application startup. The one 
problem is that the functions on the callback list are invoked every time the widget is popped 
up. To make sure that your function callback creates the popup only once (the first time), the 
callback function should remove itself from the callback list by calling XtRemove- 
Callback.) 
There is not enough difference between xmenul and xmenu2 to merit showing the complete 
code. All we have done is changed the PlaceMenu function from an action into a callback 
and changed its placement logic to place the popup relative to the invoking Command 
widget. We have then modified the app-defaults file accordingly. 
Example 13-5 shows the PlaceMenu routine (now a callback, not an action) and the code 
to register it as a callback. 

Example 13-5. xmenu2: code to place pulldown menu 
void PlaceMenu(w, client_data, call_data) 
XtPointer client data; 
XtPointer call_dta ; 
{ 
Position x, y; 
Dimension height; 
* translate coordinates in application top-level window 
* into coordinates from root window origin. 
XtTranslateCoords(pressme, /* Widget */ 
(Position) 0, /* x */ 
(Position) 0, /* y */ 
&x, &y); /* coords on root window */ 
/* get height of pressme so that menu is positioned below */ 
XtVaGet Va lue s ( pre s sme, 
XtNheight, &height, 
NULL) ; 
/* move popup shell one pixel above and left of this position 
* (it's not visible yet) */ 
main(argc, argv) 
int argc; 

Menus, Gadgets, and Cascaded Popups 429 



The translations for the menu pane Command widgets are also somewhat different from 
xmenul, but only for cosmetic reasons. This iteration of the xmenu example uses the set 
and unset actions instead of highlight and reset or unhighlight to make the 
Command widgets highlight their entire box instead of just an area near the border. 
(Although this modification makes the menu look more like a typical menu, it also seems to 
make it slower.) 
To create several menus you simply need to replicate the code shown here, changing the vari- 
able names for each menu. The passive global grabs invoked by Xt for each menu do not 
interfere with each other even if they specify the same key/button combination, because they 
specify different windows in which the key/button combination will begin the grab. 
It is sometimes useful to be able to get a list of children in a menu, especially if you add and 
subtract menu entries. You can do this by querying the XtNchildren and XtNnumChildren 
resources of the parent. The value of XtNchildren is a list of the widget ID's of the children. 
This technique allows you to diminate maintaining global variables for every pane of every 
menu. 

13.3.3 

Cascaded Menus 

A cascaded menu is a menu in which one or more panes do not invoke functions but instead 
bring up additional menus. 
The techniques used to bring up cascaded menus can also be used to have dialog boxes bring 
up other dialog boxes. However, cascaded menus are more challenging because they rely on 
the passive global pointer grab to receive the ButtonRelease event that occurs outside 
the menu and application. 
You can implement a cascaded menu the same way for both spring-loaded and pulldown 
menus simply by adding to the code we've already written to implement a single menu. 
We'll show you xmenu5, the spring-loaded version, since it is slightly shorter. (xmenu4 is the 
equivalent pulldown version.) Both are included in the example source code. In this 
example, only one menu pane will be used to invoke a submenu. However, this technique 
can be generalized to have additional panes bring up additional submenus. 
First, let's describe exactly how we expect the cascaded menu to work. Figure 13-4 shows 
both menus popped up. (Compile the program and try it.) 
The main menu works as described above. However, one of the panes--the one that brings 
up the submenu--has an arrow pointing to the right after its label. This pane does not high- 
light itself when the pointer moves inside (telling the user that this pane is different). 
Instead, when the user moves the pointer out through the right edge of the pane, the submenu 
pops up. The submenu operates just like the main menu. When the button is released inside 
either menu, the callback function associated with the chosen pane will be invoked. When 
the button is released outside of either menu, both menus pop down. If the pointer is moved 
back out of the submenu into the main menu, only the submenu pops down. 

Menus, Gadgets, and Cascaded Popups 431 



Example 13-8. XMenu5: translation portion of app-defaults file (continued) 
<BtnUp>: XtMenuPopdown(subshell) XtMenuPopdown(pshell) 
! popping up main menu 
*label.translations : \ 
<BtnDown>: placeMenu() XtMenuPopup(pshell) 
o 
' popping down submenu 
*menubox. menupane5, translations : \ 
<LeaveWindow> : checkRightAndPopupSubmenu ( ) 
! 
. 
! Main Menu translations 
*menubox. Command. translations : \ 
<EnterWindow> : highlight ( ) \n\ 
<LeaveWindow> : reset ( ) \n\ 
<BtnUp>: set() notify() unset() 
t Sub Menu translations 
*subbox. translations : \ 
<LeaveWindow> : popdownSubmenu (subbox) 
* subbox. Command. translations : \ 
<EnterWindow> : highlight ( ) \n\ 
<LeaveWindow> : reset ( ) \n\ 
<BtnUp>: set() notify() unset() 
The first three translation tables handle popping up the main menu and making the menu 
Command widgets work as expected. We've seen these in previous examples. 
The translation table for psho].], pops down one or both menus; no error or warning is 
caused if only the main menu is up. This translation table works because the button release is 
sent to psho].], if it occurs outside a menu regardless of whether just the main menu or both 
menus are up. 
In this case, menu pane 5 is the pane that will pop up the submenu. The label for this pane is 
shown at the top of Example 13-8. The translation for this pane replaces all the normal trans- 
lations for highlighting and notifying with a single translation for reaveWindow events. 
These events in this widget trigger the CheckRightAndPopupSubmenu action which 
has already been described. 
The translations for the subbox widget invoke PopdownSubmenu action to check 
whether the pointer left the submenu. In this case, the submenu is popped down, but the orig- 
inal popup remains visible. 
The pane that will pop up the submenu and its event handling characteristics is controlled 
from the app-defaults file. Therefore, it may seem like you can change which menu pane 
invokes the submenu simply by changing the app-defaults file. This is true here, because the 
menu actions are nonfunctional and simply call a common callback. But it would not be pos- 
sible if each pane invoked its own callback. To give the user the freedom to rearrange the 
menu, you would have to use actions instead of callbacks. 
Note that you can define accelerators for any of the menus shown up to this point simply by 
placing settings for the XtNaccelerators resource in the app-defaults file. You would 
set this resource for every Command widget in the menus. This provides keyboard shortcuts 

Menus, Gadgets, and Cascaded Popups 435 



Click here for menu 

io Scrolibr 
Enable Reverse Video 
Enable Bell 

Reply 
Forward 
Print 

Figure 13-5. xmenu7: a menu using the Athena SimpleMenu widget 

Example 13-9. xmenu7: using the SimpleMenu widget and its children (continued) 
"line", 
"item5", 
"item6", 
"item]", 
"blank", 
"menu I", 
"menu2", 
"me nu 3", 
); 
static Boolean status[NUM MENU ITEMS]; 
-- -- 
static Pixmap mark; 
/* ARGSUSED */ 
static void 
MenuSelect (w, client_data, garbage) 
Widget w; 
XtPointer client data; 
-- 
XtPointer garbage; /* call data */ 
-- 
{ 
int pane_hum = (int) client_data; 
printf("Menu item %s has been selected . \n", XtName(w)); 
if (pane_hum == 0) /* quit selected. */ 
exit (0) ; 

if (status [pane_hum] ) 
XtVaSetValues (w, 
XtNleftBitmap, None, 
NULL) ; 
else 
XtVaSetValues (w, 

Menus, Gadgets, and Cascaded Popups 437 



" ..... Example13-9. xmenu7: using the SimpleMenu widget anditschildren (continued) 
ii XtNleftBitmap, mark, 
:: NULL); 
status[pane_hum] = !status[pane_num]; 
} 
mainlargc, argv) 
char **argv; 
int argc; 
{ 
XtAppContext app_context; 
Widget topLevel, menu, button, entry; 
int i; 
Arg arglist[l]; 

topLevel = XtVaAppInitialize( 

&app_context, 
"XMenu 7", 
NULL, 0, 
&argc, argv, 
NULL, 
NULL); 

/* Application context */ 
/* Application class */ 
/* command line option list */ 
/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

button = XtCreateManagedWidget("menuButton", 
menuButtonWidgetClass, topLevel, 
arglist, (Cardinal) 0); 

menu = XtCreatePopupShell("menu", simpleMenuWidgetClass, 
button, NULL, 0) ; 

for (i = 0; i < NUM MENU ITEMS ; i++) { 
-- -- 
String item = menu_entry_names[i]; 

if (i == 4) /* use a line pane */ 
entry = XtCreateManagedWidget(item, 
smeLineObjectClass, menu, 
NULL, 0); 
else if (i == 8) /* blank entry */ 
entry = XtCreateManagedWidget(item, smeObjectClass, menu, 
NULL, 0); 
else { 
entry = XtCreateManagedWidget(item, smeBSBObjectClass, 
menu, NULL, 0); 
XtAddCallback(entry, XtNcallback, MenuSelect, 
(XtPointer) i); 
} 
} 
mark = XCreateBitmapFromData(XtDisplay(topLevel), 
RootWindowOfScreen(XtScreen(topLevel)), 
xlogol6_bits, xlogol6_width, xlogol6_height); 
XtRealizeWidget(topLevel); 
XtAppMainLoop(app_context); 

438 X Toolkit Intrinsics Programming Manual, Motif Edition 



You will notice that each pane has an XtNleftBitmap resource, which is alternately set 
to the X logo or to nothing each time that item is selected. 

The app-defaults file for xmenu7 is shown in Example 13-10. 

Examp 13-10. XMenu app-deults file 
! 
' For Color workstations only. 
XMenu7 
XMenu7 
XMenu7 

XMenu7 

XMenu7 
XMenu7 
XMenu7 
XMenu7 

*SimpleMenu*foreground: SteelBlue 
*SimpleMenu*menuLabel.foreground: Gold 
*SimpleMenu*line.foreground: Grey 
*MenuButton.label: Click here for menu 
*SimpleMenu*menuLabel.vertSpace: i00 
*SimpleMenu*menuLabel.leftMargin: 70 
*SimpleMenu.label: Main Menu 
*SimpleMenu*iteml*label: Show Scrollbar 

XMenu7*SimpleMenu*item2*label: Enable Reverse Video 
XMenu7*SimpleMenu*item3*label: Enable Bell 
XMenu7*SimpleMenu*item4*label: Disable Auto-Repeat 
XMenu7*SimpleMenu*item5*label: Copy 
XMenu7*SimpleMenu*item6*label: Unmark 

XMenu7*SimpleMenu*item7*label 
XMenu7*SimpleMenu*menul*label 
XMenu7*SimpleMenu*menu2*label 
XMenu7*SimpleMenu*menu3*label 
XMenu7*SimpleMenu*quit*label: 
XMenu7*SimpleMenu*RowHeight: 16 
XMenu7*SimpleMenu*item7*sensitive: 
XMenu7*SimpleMenu*HbrizontalMargins: 
' Just for fun: 

: View in New 
: Reply 
: Forward 
: Print 
Quit 

off 
30 

XMenu7*font: *times*medium*18*iso8859-1 
!XMenu7*item7*font: *helv*medium*24*iso8859-1 
!XMenu7*item8*font: *helv*bold*24*iso8859-1 

*quit*accelerators:\ 
<Key>q: notify() 
*iteml*accelerators:\ 
<Key>l: notify() 
*item2*accelerators:\ 
<Key>2: notify() 
*item3*accelerators:\ 
<Key>3: notify() 
*item5*accelerators:\ 
<Key>5: notify() 
*item6*accelerators:\ 
<Key>6: notify() 
*item7*accelerators:\ 
<Key>7: notify() 
*menul*accelerators:\ 
<Key>m: notify() 

Menus, Gadgets, and Cascaded Popups 439 



This file simply sets various cosmetic features of the menu. (See Appendix C, Naming Con- 
ventions, for information on font-naming conventions.) Naturally, you could easily set the 
strings for each menu entry in this file. Note that there are no translation tables in this file 
because MenuButton and SimpleMenu are doing exactly what they were designed to do. 

Accelerators can be defined for menus with gadget children, but not in the usual sense. They 
cannot be defined to invoke the actions of the gadget children, but they can invoke global 
application actions, which for menus is usually good enough. For example, in the R4 xmh, 
one item on one of the menus incorporates new mail. From the widget, the notify action 
of the menu pane gadget calls the DoIncorporateNewMail callback function. The 
XtNaeeelerators resource for the SimpleMenu widget itself (not the gadgets) maps a 
Meta-I key event into a call to the XmhIncorporateNewMail global action. Xmh- 
IncorporateNewMail then calls DoIncorporateNewMail. This use of accelera- 
tors depends on having both a callback and an action form of each function. 

13.3.5 

Delayed Popup Creation 

As we've seen, a popup may consist of a single widget, or it may be a shell widget which 
contains a composite widget which contains a number of children. In the latter case, creating 
all those widgets (or gadgets) takes time. It may be beneficial to create those widgets using 
idle time in the application instead of delaying startup. In either case, it may make sense to 
create the popup only when it is needed, to minimize wasted resources. 
If your goal is to speed startup, and you want all menus created even if some are never used, 
you can register a work procedure to create each popup, as described in Section 8.5. As you 
may recall, a work procedure uses idle time in the application to call a function, which must 
return swiftly. If you use this technique, you add one work procedure for each popup you 
need to create, and you need to add code to make sure that the popup has been created before 
the user is allowed to use it. 
If your goal is to create only the required popups, you can create the popup in a callback 
function or action routine that you have registered to place or pop up the popup. In this case, 
you would have a static variable in the callback or action to make sure that the popup wid- 
gets are only created the first time the popup is popped up. You need to have created the 
popup shell before this can work. 
There is also another way to create only the required popups. Shell widgets have an Xt- 
NcreatePopupChildProc resource which you can set to a function that creates the 
Shell's children. See XtCreatePopupChildProc(2) in Volume Five, X Toolkit 
lntrinsics Reference Manual, for the calling sequence of this function type. The Xt specifica- 
tion does not say whether an XtCreatePopupChildProc is called just once when the 
shell is first popped up or every time it is popped up. But the MIT implementation of Xt calls 
it every time the shell is popped up, so you will again need a static variable to make sure the 
children are only created once. 

440 X Toolkit Intrinsics Programming Manual, Motif Edition 



13.4 About Dialog Boxes 

Although we have been talking so far exclusively about menus, much that has been said is 
also true of dialog boxes. Both menus and dialog boxes that get user input usually need to 
get that input before other application functions can be invoked. Of course, one way to dis- 
able all other application functions is to make all other widgets insensitive with xtset- 
Senaitive (passing it Falae). Seuing the sensitivity of one common ancestor does this 
efficiently, but even this is too slow because all the widgets redraw themselves dimmed or 
grayed. It is much faster to use a global grab. Unlike menus, which require the global grab 
in order to get button release events outside the application so they can pop down properly, 
dialog boxes do not, strictly speaking, need a grab. But they sometimes make the grab any- 
way to disable other application functions. 
Dialog boxes can also invoke other dialog boxes. For example, a dialog box that gets input 
might check the validity of the input before popping down the dialog, and if incorrect, pop up 
a message telling the user the problem with the input. Cascaded dialog boxes are imple- 
mented the same way as cascaded menus. Note that, as a general rule, sub-dialog boxes are 
popped up with grab mode XtGrabExclusive, which means that the user must satisfy 
the most deeply nested dialog first. However, it is often desirable to leave a Help dialog on 
the screen until ter the dialog it provides help for has been removed. 
Some popups do not need to disable other application functions. For example, imagine a dia- 
log box that informed the user of some fact without requiring confirmation. This kind of 
popup would be popped up with grab mode XtGrabNone, allowing the user to continue 
with other application functions. 
We pointed out earlier that the built-in callback functions for popping up a widget are not 
useful for menus because they make no passive global pointer grab. However, they come in 
handy for dialog boxes. The functions XtCallbackNone, XtCallbackExclusive, 
and XtCallbackNonexclusive can be used to pop up dialog boxes, as long as the 
position of the dialog box need not depend on information in an event. 
We haven't shown how to use Xt's standard callback for popping down a widget: Xt- 
CallbackPopdown. Instead of calling XtPopdown in the callback functions for each 
menu entry, we can add XtCallbackPopdown to the callback list ter the existing call- 
back function. XtCallbackPopdown requires an XtPopdownId structure to be passed 
as the c2ient_data argument. This structure must contain the popup shell and the widget 
that invoked the popup (the MenuButton or Command widget). 
All three of the standard popup callbacks set the invoking widget to insensitive mode before 
popping up the widget. XtCallbackPopdown resets the invoking widget to sensitive 
mode. Therefore, if you use XtCallbackNone, XtCallbackNonexclusive, or 
XtCallbackExclusive without also using XtCallbackPopdown, remember to set 
the widget to sensitive mode yourself. This feature is useless but also harmless when the 
popup is spring-loaded, because the invoking widget is often the main application window 
and that widget rarely responds to sensitivity. 
In certain rare cases, you may want to use XtAddGrab and XtRemoveGrab directly to 
append a widget to or remove a widget from the current popup cascade. These functions are 
called internally by the Xt facilities that pop widgets up and down, and should not be 

Menus, Gadgets, and Cascaded Popups 441 



necessary on their own. Note that these functions never make a request to the server to start 
or release a passive global pointer grab--they affect only Xt's internal event dispatching. 
(However, the functions XtGrabKey, XtGrabKeyboard, XtGrabButton, and Xt- 
GrabPointer do initiate global grabs. These functions are described in Chapter 14, Mis- 
cellaneous Toolkit Programming Techniques.) 

13.5 Gadgets 

When an application includes many different menus with many fields each, the overhead of 
having separate widgets for every menu pane becomes significant. Because each widget 
requires structures on the client side and windows on the server side, every widget increases 
the executable size and server memory usage and increases the traffic over the network. It is 
always a good idea to minimize the number of widgets used in your application. 
Writing a single widget that implements an entire menu, including all its panes, solves this 
problem. The widget could define subresources for configuring each pane. (The callback list 
would be one of these subresources. XtCallCallbacks could not be used to invoke 
these callbacks because it cannot distinguish between subparts. However, the callbacks can 
be called directly by looping through the callback list. This is awkward, but not too diffi- 
cult.) This widget would not lack flexibility if the subparts are implemented as completely 
separate code so that the types of menu panes are extensible. However, gadgets turn out to be 
an easier and more elegant solution to the problem. 
As of Release 4, Xt provides gadgets, which are simplified widgets that do not create win- 
dows.* Gadgets require less memory than widgets on the client side (and less disk space for 
the executable file) and consume none at all on the server side. Gadgets can be used for the 
panes of a menu, solving all of the problems just discussed. A gadget is fully configurable 
using the resource database just like a widget, and can have its own callback list. 
However, the reduced consumption of gadgets does have a price. Gadgets have to draw on 
their parent's window, and they share this space with the parent and with all other gadget 
children. The gadgets and the parent must agree to draw in certain areas only. For this rea- 
son, gadgets must be used with a special composite widget parent that is prepared to manage 
them properly. 
The Release 4 SimpleMenu widget is such a parent. It is a composite widget designed to 
manage gadget children. The gadgets provided by Release 4 are Sme, SmeBSB, and Sme- 
Line (where Sme stands for Simple Menu Entry). These provide a blank entry (and generic 
menu entry superclass), an entry which can contain a bitmap, a string, and another bitmap 
(thus BSB), and an entry that draws a horizontal line. We will use and describe this widget 
and these gadgets both to show how menu widgets are built and to demonslrate how the par- 
ent and the gadgets work together. 

*The OSF Motif 1.0 Intrinsics support a different implementation of gadgets than those described here. Motif 1.1, 
however, uses the R4 standard Intrinsics, which includes the gadget implementation described here. 

442 X Too&# Intrinsics Programming Manual, Motif Edition 



Gadgets do not handle events automatically as widgets do, and because they have no win- 
dows, the server does not handle overlapping between them. This places certain demands on 
the parent. All the gadgets that are children of a particular parent share that parent's window. 
The parent is responsible for coordinating the gadget children, telling them about events by 
calling their functions. Therefore, the composite widget that manages a group of gadgets 
must be specially designed for that purpose, not a general-purpose composite or constraint 
widget such as Box or Form. It is possible for a composite widget to manage both gadget and 
widget children, but its code has to be more involved to do this. 
Like normal widgets, gadgets provide their own code to redraw themselves in their expose 
method. However, since gadgets do not receive events, they depend on the parent to directly 
call their expose method. The parent keeps track of the geometry of each child, and when 
the parent's expose method is called, this method calculates whether the area exposed 
overlaps any of the gadget children. If the area exposed does overlap a gadget, the parent's 
expose method calls that gadget's expose method, which redraws the area. 
A gadget's actions also have to work differently from widget actions because of the fact that 
gadgets don't get events. A gadget defines its actions as methodsnas fields in its class part 
structureminstead of in an action list and translation table. It initializes these fields directly 
to pointers to functions during class initialization. The parent widget has corresponding 
actions that are defined and operate like normal actions, except that they determine which 
gadget the event that invoked the action occurred in and call the gadget method correspond- 
ing to that action. In other words, the parent has actions that operate the gadget children. 
One weakness of a menu composed of gadget panes is that gadgets cannot have an accelera- 
tor table. Therefore, accelerators cannot be used to provide a keyboard equivalent that would 
invoke each menu pane. 
The parent of gadgets has to position the gadget children so that they do not overlap, or take 
care of the consequences if they do overlap. Since the gadgets draw on the parent's window, 
if they did overlap they would draw over each other's graphics, with unpredictable results. 
The parent would have to calculate the area of overlap between two gadgets, and clear this 
area before letting one of the gadgets draw itself. (A gadget could clear its own area before 
drawing, but this would be unnecessary in many cases, and would cause flashing.) 
Gadgets are subclasses of RectObj, one of the invisible superclasses of Core that we have so 
far ignored because for widgets it is safe to assume that Core is the top of the widget class 
hierarchy.* The actual class hierarchy leading up to Core is shown in Figure 13-6. 
The "unnamed class" actually has a name (WindowObj) but this class is intentionally undo- 
cumented in the Xt specification so that its characteristics can be changed in later releases 
without compatibility problems. You should never create subclasses directly from the 
unnamed class. 
The superclasses of Core are not real classes in the sense that they do not play by all the rules 
we have described in Chapter 6, Inside a Widget. For one thing, each shares what we call 
the Core class structure instead of adding its own part structure. Applications are never 

*In R3, the header files for these invisible classes are not so invisible. They were all present in lusr/includelXll with 
all the other Xt header files. In R4, only the header files for RectObj are public, so that you can write and compile 
gadgets. 

Menus, Gadgets, and Cascaded Popups 443 



Also, the parent's resource values, such as background_pixel, may be used to provide 
data in common among all instances of a subclass like SmeBSB. 

13.5.4 

The Public Header File 

The only difference in the public header file between widgets and gadgets is that what would 
have been Widget for a widget is Object for a gadget. As mentioned previously, if you 
are writing a gadget you should start by copying the files for an existing gadget and then 
globally change names. Then you will start with the proper conventions already in place. 

13.5.5 The Gadget Parent 

A gadget parent is a composite widget designed to manage gadget children. Gadget parents 
perform all the geometry management tasks that all composite widgets perform, which are 
described in Chapter 12, Geometry Management. Gadgets also follow all the rules of nor- 
mal widget children. However, gadget parents also have the added responsibility of manag- 
ing the overlap of gadgets or making sure they don't overlap, and of handling events for the 
gadgets and calling gadget code. This section describes the gadget-managing role of the gad- 
get parent. 

The Athena SimpleMenu widget is designed to manage the gadget children already 
described, Sme, SmeLine, and SmeBSB (and any other subclass of Sme that is written later). 
It forms a vertical menu with horizontal panes. It is quite a large widget because it contains 
all the geometry management code in addition to code for managing events for the gadgets. 
We'll concentrate just on the code that manages events for the gadgets, since the geometry 
management code is described in Chapter 12, Geometry Management. 

Let's begin with the expose method. SimpleMenu's expose method does no drawing of 
its own. It simply calls the expose methods of the gadget children. However, it compares 
the region passed into its expose method to determine which gadgets need redrawing. 
Example 13-13 shows SimpleMenu's expose method. 

Examp 13-1 SimpMenu: expose meodcallinggadgetchildren3 expose meods 
#define ForAllChildren(smw, childP) \ 
for ( (childP) = (SmeObject *) (smw)->composite.children ; \ 
(childP) < (SmeObject *) ( (smw)->composite.children + \ 
(smw)->composite.num children ); (childP)++) 
-- 

/* ARGSUSED */ 
static void 
Redisplay(w, event, region) 
Widget w; 
XEvent * event; 
Region region; 
{ 
SimpleMenuWidget smw = (SimpleMenuWidget) w; 
SmeObject * entry; 
SmeObjectClass class; 

448 X Toolkit Intrinsics Programming Manual Motif Edition 



The resize method of SimpleMenu must resize the children when it is resized itself. 
(Actually, this is unlikely, since the SimpleMenu widget itself is a subclass of Shell and is 
therefore not managed by any parent.) This method is invoked only when the user resizes the 
menu using the window manager. Since this widget has the authority to determine the geom- 
etry of its children, it can simply resize them. This particular resize method (shown in 
Example 13-14) simply sets their width to be the same as its own. 

Examp 13-14. SimpMenu: resize meod 
static void 
Resize(w) 
Widget w; 
{ 
SimpleMenuWidget smw = (SimpleMenuWidget) w; 
SmeObject * entry; 

if ( !XtIsRealized(w) ) return; 

ForAllChildren(smw, entry) /* reset width of all entries. */ 
if (XtIsManaged( (Widget) *entry)) 
(*entry)->rectangle.width = smw->core.width; 

Redisplay(w, (XEvent *) NULL, (Region) NULL); 
} 
NoOce that this resize method invokes the expose method (Redisplay) because the 
gadgets don't have resize methods, and will not redraw themselves in response to their 
size change.* 
Now let's look at SimpleMenu's actions. Their only purpose is to call the gadgets' actions 
when the appropriate events arrive. These actions are added in the usual way: they are 
declared at the top of the .c file, then registered with an action list that is entered into the 
class structure initialization, and then defined. One of the three actions is shown in Example 
13-15. 

Examp 13-15. SimpMenu: e Notify actbn routine 
/* ARGSUSED */ 
static void 
Notify(w, event, params, num_params) 
Widget w; 
XEvent * event; 
String * params; 
Cardinal * num_params; 
{ 
SimpleMenuWidget smw = (SimpleMenuWidget) w; 
SmeObject entry = smw->simple_menu.entry_set; 
SmeObjectClass class; 

if ( (entry == NULL) II !XtIsSensitive((Widget) entry) ) 
return; 

*The gadget children could have res i ze methods, and this resize method could call the children's res i ze meth- 
ods. The gadget's resi ze methods would simply call their expose method. However, this does exactly the same 
thing as the code shown while being more complicated. 

450 X Toolkit Intrinsics Programming Manual Motif Edition 



14 

Miscellaneous Toolkit 
Programming Techniques 

This chapter describes various Xt functions that have not been treated else- 
where in the book. 

In This Chapter: 

Errors and Warnings .......................................................................... 455 
Objects .............................................................................................. 458 
Macros For Getting Information .......................................................... 459 
The accept_focus Method and the Keyboard Focus ........................... 461 
Keyboard Interpretation ..................................................................... 462 
Memory Allocation ............................................................................. 463 
Action Hooks and Calling Actions Directly .......................................... 464 
Xt Grabbing Functions ....................................................................... 464 
File Finding and Internationalization ................................................... 465 
Application Contexts .......................................................................... 465 
Multiple Application Contexts ......................................................... 466 
Rewriting XtAppMainLoop for Multiple Application Contexts ........... 467 
Functions Used with Multiple Application Contexts ......................... 468 
Multiple Top-level Shells .................................................................... 468 
Connecting to Multiple Servers .......................................................... 468 
Class Extension Structures ................................................................ 469 



14 
Miscellaneous Toolkit 
Programming Techniques 

This chapter discusses various Xt facilities that didn't fit neatly into any other chapter. Many 
of them are functions provided mostly because Xt uses them internally, and they are unlikely 
to be useful in application or widget code. Some of them are quite important for accomplish- 
ing certain tasks. You should scan the contents of this chapter to familiarize yourself with 
these facilities so that you will be aware of them. 

The topics covered are errors and warning messages, objects, a description of all of Xt's mac- 
ros and functions for getting information, the Core accept:_f_ocus method, how to inter- 
pret key events, Xt's facilities for memory management, making global grabs, file finding 
and internationalization, multiple application contexts, multiple top-level shells, and con- 
necting to multiple servers. 

14.1 Errors and Warnings 

There are several broad categories of errors that may occur in Xt applications. One is the X 
server error, which is a form of event that tells the client that some parameter in an earlier 
request was illegal, or that no more server memory is available. A second is the connection 
failure error generated by Xlib when the connection with the server fails (usually due to a 
system crash or network interruption). Xlib provides the XSetErrorHand'le: and 
XSet:IOR]r]ro]rHand'l el: functions to allow the application to provide a routine to handle 
these two types of errors. Xt provides no interface to these routines--Toolkit applications 
must use the Xlib routines to customize these error handlers (Xlib uses default error handlers 
when the application does not use these routines to specify them). For a description of these 
error handlers and the routines for changing them, see Volume One, Xlib Programming 
Manual. 

A third category is made up of error and warning messages that Xt reports when function 
parameters are specified improperly, when a translation is incorrectly specified, and for many 
other reasons. For a complete listing of all errors and warnings that can be generated by Xt, 
see Volume Five, X Toolkit Intrinsics Reference Manual, Appendix D, Standard Errors and 
Warnings. Xt provides separate parallel routines for errors and for warnings. The difference 
between Xt errors and Xt warnings is that errors are fatal and the application exits after print- 

Miscellaneous TooAk# Programming Techniques 455 



As an example, let's look at how the Athena Text wilget handles drawing. The drawing is 
done by the TextSink object, and its subclass AsciiSink. Although an object has no expose 
method, it provides an equivalent function that draws on the parent. This function is either a 
semi-public function (public to its parent but not to the application writer), or it is a class 
method. The Text widget uses both techniques. TextSink provides a semi-public function 
XawTextSinkDisplayText, which is called by Text whenever drawing is needed. 
A object XawTextSinkDisplayText, this function calls one of TextSink's class meth- 
ods called DisplayText. DisplayText is a class method so that subclasses of TextSink can re- 
place it or inherit it. AsciiSink does replace this method with code that draws the text in a 
single constant-width font, in the foreground and background colors. So in order to write a 
Text widget that draws in more than two colors, you would just have to write an object that is 
a new subclass of TextSink. 
When Text calls XawTextSinkDisplayText, this function calls one of TextSink's class 
methods called DisplayText. DisplayText is a class method so that subclasses of TextSink 
can replace it or inherit it. AsciiSink does replace this method with code that draws the text 
in a single constant-width font, in the foreground and background colors. So in order to write 
a Text widget that draws in more than two colors, you would just have to write an object that 
is a new subclass of TextSink. 
An object may assume that it should draw on its parent, but this is not necessarily the case, 
since an object could have an object as its parent. An object also has no idea of its own size, 
since it has no geometry data in its instance structure, and therefore doesn't by itself know 
what size window it is drawing into. To solve both these problems, XawTextSink- 
DisplayText passes the parent's widget ID and the parent's size into the objects drawing 
code. 

Macros For Getting Information 

Xt provides several macros and functions for getting information about widgets. Some of 
these, such as XtIsRealized and XtIsManaged, you have seen before in the context 
of widget methods. 
Some of these are macros and some are functions, and some are macros when used in widget 
code and functions when used in application code. This does not affect how they can be 
used, so we won't bother to specify which can be both functions and macros. We will use the 
term "macro" for all of these informational routines. In Volume Five, X Toolkit lntrinsics 
Reference Manual, they are listed alphabetically, together with all of the Intrinsics functions. 
Xt provides two basic macros for determining the class of a widget: xt I sComposite and 
XtIsSubclass. These are primarily used internally by Xt to implement geometry man- 
agement, but you may find a use for them. For example, you might write a composite widget 
that uses xt I s Compos i te to treat composite children differently than simple children, or 
uses XtrsSubclass to treat constraint children or one of your own classes uniquely. 
There are lots of convenience functions for xt r s Subcl as s that determine if a widget is a 
subclass of a particular class. These are XtIsObject, XtIsRectObj, XtIsWidget, 
XtIsComposite, XtIsConstraint, XtIsShell, XtIsOverrideShell, Xt- 

Miscellaneous Toolkit Programming Techniques 459 



IsWMShell, XtIsVendorShell, XtIsTransientShell, XtIsTopLevel- 
Shell, and XtIsApplicationShell. 

You have already seen XtIsManaged used in composite widgets. See Chapter 12, Geom- 
etry Management. 

You have also already seen XtIsRealized used in various methods to make sure a widget 
has a window before operations are attempted on the window. For example, the expose 
method calls xt a" sReal i zeal before drawing into the window. 

XtIsSensitive checks the value of the XmNsensltive resource for a widget and its 
ancestors. If any of them is False, it returns False. Remember that sensitivity controls 
whether a widget responds to user events. 

XtHasCallbacks lets you tell whether a widget class has a callback of a certain resource 
name, and whether any callback functions have actually been added to it. It returns the 
enum value XtCallbackNoList if there is no callback list, XtCallbackHasNone if 
there is a callback list with no functions on it, and XtCallbackHasSome if there is a call- 
back list containing functions pointers. 

XtNameToWidget searches a hierarchy for the widget ID of the specified widget instance 
name. Its primary use from the application is to get the IDs of the child widgets of a com- 
pound widget such as Dialog, so that their resources can be set directly. This is a violation of 
the rules of data hiding, however, and is not recommended. In widget code, XtName- 
ToWidget is used to provide a layer of abstraction so that widgets can be identified using 
string names. For example, it is used by the converter defined by Form that allows widget 
names to be specified in resource files. The opposite function, which returns a widget in- 
stance name given the widget ID, is XtName (which perhaps should have been called "Xt- 
WidgetToName"). 

XtWindowToWidget gives you the Widget which corresponds to the specified X win- 
dow ID. This is used mainly by Xt, but you may find a use for it. 

XtDisplayOfObject, XtScreenOfObject, and xtWindowOfObject search the 
parental hierarchy of an object to discover the closest windowed ancestor and then return a 
pointer to a Display structure, a pointer to a Screen structure, or a Window ID. These 
macros are useful for making Xlib calls from within code that implements a subclass of Ob- 
ject. 

XtGetApplicationNameAndClass returns the name and class st6ngs of an applica- 
tion. The name is usually a rgv [ 0 ] stripped of any directories, while the class is the string 
passed as the second argument of XtApprnitialize. These are the name and class used 
by Xt to look up resources for the application and its widgets. You are not likely to need this 
function. 

460 X Too&# Intrinsics Programming Manual, Motif Edition 



may have a different symbol over / and put ? somewhere else. Also, some keyboards have 
two or more symbols on a single key, some of which are not represented at all by standard 
keysyms. The case converter handles these situations. The case converter is usually called 
from the key translator described above. To call the case converter, use xtConvertCase, 
and to change the case converter, call XtRegisterCaseConverter. See xtCase- 
Proc in Volume Five, X Toolkit Intrinsics Reference Manual, for details on writing a case 
converter procedure. 
Note that the translation manager uses these same key translation and case converter routines 
to interpret translation tables. Therefore, make sure that you add features only to them, keep- 
ing existing features. 
Xt also provides two routines that may help in interpreting key events: XtGetKeysym- 
Table and XtKeysymToKeycodeList. The former returns e entire mappg of key- 
codes to keysyms for the server, while the latter tells you what keycodes are listed for the 
specified keysym. Neither function is necessary for routine keyboard handling. 
From within an action routine, you can call XtGetActionKeysym tO get the keysym that 
resulted in the action being called. This can be very useful, since the event passed to the ac- 
tion contains only the keycode of the key that was pressed. However, there is another way to 
acheive a similar result. You can use string parameters of actions to pass in the keysym that 
you specified in the translation table. For example, if you provide the translation : <Key>q 
: Quit (q), the Quit action will be passed the string "q" in its params argument. How- 
ever, XtGetActionKeysym is very useful if you translate a wide range of key events to 
one action, and then want to distinguish between them in the action. 

14.6 

Memory Allocation 

Xt provides routines for performing routine memory allocation and deallocation. The rou- 
tines XtMalloc, XtCalloc, XtRealloc, and XtFree are equivalents of the standard 
C routines malloc, calloc, realloc, and free but they add error checking and re- 
porting. The allocation routines make sure the allocation succeeded, and if it did not, they 
print a (fatal) error message. XtFree makes sure the passed pointer is not NULL before cal- 
ling free. 
XtNew is a macro which allocates storage for one instance of the passed type and returns a 
pointer. For example, XtNew (XtCallbackList) allocates storage for one callback list 
structure. XtNewString is a macro that allocates storage for a string, copies the string 
into the new storage, and returns the pointer. For example, a string can be copied into new 
storage using the following: 
static String buf[] = "How do you do?"; 
String p; 

p = XtNewString (buf) ; 
After this sequence, p points to a separate string that contains "How do you do?" Then buf 
can be changed without affecting p. 

Miscellaneous Toolkit Programming Techniques 463 



14.7 Action Hooks and Calling Actions Directly 

Xt allows you to register any number of functions to be called whenever any action in an ap- 
plication context is invoked. This is done with XtAppAddAetionHook. Note that there 
is just one "action hook" in the application context, so that all the action hook functions reg- 
istered for that application context are called whenever any of the actions in that application 
context are invoked. The registration does not specify any particular action or any particular 
widget. 
The main reason for registering an action hook is to record all the actions that were invoked 
in an application, so that they can be played back later using XtCallActionProc. An 
action hook function is called with all the same arguments that are passed to an action, plus 
the siring name of the action. The action hook function would store this information as a unit 
each time it was called. When it comes time to play back the recorded actions, it would pass 
all the information in each unit to XtCallActionProc. 
An action hook can be removed with XtRemoveActionHook. 

14.8 Xt Grabbing Functions 

Grabs are used mostly for popup menus and dialog boxes. As described in 
Chapter 13, Menus, Gadgets, and Cascaded Popups, Xt has its own grab mode that controls 
the distribution of events within one application, which can be used to restrict events to one 
popup in a cascade or allow events to go to any popup in a cascade. As also described there, 
popup menus in particular need a passive global grab of the pointer in order to detect button 
releases that occur completely outside the application so that menus can be popped down 
properly. A passive global grab actually instructs the server to redirect events to a certain 
window. All the grabbing needs of popups are satisfied by the built-in action XtMenu- 
Popup, or by the function XtPopupSpringLoaded, which can be used in a callback 
function. If necessary, you can write your own version of XtMenuPopup and register it 
with XtRegisterGrabAetion SO that the appropriate passive global grab is in effect. 
The above facilities should be quite sufficient for your needs in the area of popups. However, 
it is possible that you may need an global grab for some other purpose. Perhaps you need all 
keyboard events in one window for a short time and don't want to change existing transla- 
tions or accelerators for keyboard events in other widgets. This is only one plausible scenar- 
io. 
The Xlib functions for grabbing are XGrabKey, XGrabButton, XGrabKeyboard, and 
XGrabPointer. Each of these functions has an analogue for ungrabbing. But Xt provides 
its own version of all eight of these functions. You should use the Xt versions because they 
are integrated into Xt and take care of things like making sure the widget that is to get the 
grab has been realized. In other words, if you do need the server to redirect events for you 
using a grab, use the following functions: XtGrabKey, XtGrabButton, XtGrab- 
Keyboard, XtUngrabKeyboard, and XtUngrabPointer. For more on global 
grabs, see Chapter 8 in Volume One, Xlib Programming Manual. 

464 X Toolkit Intrinsics Programming Manual, Motif Edition 



14.9 File Finding and Internationalization 

Xt's facilities for allowing an application to run in different languages are mostly built into 
the resource database mechanism. Where Xt searches for resource files depends on a lan- 
guage string, which can be set within resources at run time or with an environment variable 
to affect one user's environment. This is described in Chapter 10, Resource Management 
and Type Conversion. 
The functions that Xt uses to implement its search for resource files are also available to you 
for searching for application files. This allows you to provide separate data files for each lan- 
guage for a help system, for example. The primary function you would use to do this is Xt- 
ResolvePathname, since it searches directories in a standard order based on X/Open 
Portability Guide conventions. 
If you want to find a file but are not interested in internationalization, you can use XtFind- 
File. This function can simplify code that reads files, since it helps handle differences in 
file systems. 

14.10 Application Contexts 

The introduction to application contexts in Section 3.9 described their use in 99 percent of 
applications. As you may recall, their purpose is chiefly to attain portability to certain sys- 
tems that do not provide a separate address space for each process. 
Xt provides parallel versions of many routines--one set that uses the default application con- 
text, and one set that has an explicit application context argument. The routines that use the 
default application context are remnants of an earlier release when application contexts did 
not work properly. To acheive the desired portability, you must now use the versions with the 
explicit argument. We have done this throughout this book. In Volume Five, X Toolkit ln- 
trinsics Reference Manual, the reference pages for all the functions that use the default appli- 
cation context note the fact that they should no longer be used. 
Table 14-2 shows the complete list of routines that have two versions. 

Table 14-2. Xt Routines That Use Default and Explicit Application Contexts 

Default 

(registering functions) 
XtAddActions 
XtAddConverter 
XtAddInput 
XtTimeOut 
XtWorkProc 
(creating shells) 
XtCreateApplicationShell 
(em dispatching) 

Explicit 

XtAppAddActions 
XtAppAddConverter 
XtAppAddInput 
XtAppTimeOut 
XtAppWorkProc 

XtAppCreateShell 

Miscellaneous Toolkit Programming Techniques 465 



Having two application contexts makes each sub-application more separate than if they were 
just under different top-level Shell widgets. Each widget class has an action list, and each 
application context has a separate context-wide action list. When the translation manager 
looks for an action, it looks in the widget class action list first, and then the application con- 
text action list. Therefore, each sub-application could add an action to its application context 
without conflict with another sub-application adding a different action of the same name. 

On parallel processing machines, each separate application context could run in parallel. 
However, it is difficult to write portable code to take advantage of this, since each architec- 
ture has different conventions for indicating parallelisms in C code. 

14.10.2 

Rewriting XtAppMainLoop for Multiple Application Contexts 

To use multiple application contexts, you need to write your own equivalent of XtApp- 
MainLoop tO dispatch events to your multiple application contexts. This is necessary 
cause XtAppMainLoop dispatches events only from one application context, and it never 
returns so you can't call it again for the other. 
The available tools are XtAppNextEvent, XtAppPeekEvent, XtAppPending, Xt- 
AppProcessEvent, and the Xlib functions XFlush and xSync. Rewriting XtApp- 
MainLoop for two or more application contexts is tricky, because you don't want to let the 
dispatching of any one application context get behind. It is not as simple as dispatching 
events from each application context alternately, since the events might not occur alternately. 
It is easy to get stuck waiting for events in one application context while events queue up at 
the other. There is little experience in how this should be done properly, and no examples in 
the distribution from MIT. However, hypothetically, the following describes how it could 
work. 
To do this properly, you have to understand how Xlib's network optimization works. Xlib 
buffers up many types of requests and sends (flushes) them to the server as a group.* A flush 
is most commonly caused by a routine such as XtAppNextEvent that waits for an event if 
none are available. It is because XtAppNextEvent waits forever for an event that the 
routine could get locked waiting for events in one application context while the user types 
frantically in the other. 
The answer is to use XtAppPending to determine whether an event is available on a par- 
ticular application context, and then call XtAppProceaaEvent if there is an event to pro- 
cess. Then continue to do the same on each other application context. However, this alone is 
not enough. Neither XtAppPending nor XtAppProceaaEvent called in this manner 
cause Xlib's buffer of requests to be sent to the server. Therefore, periodic calls to xSync or 
XFlush are necessary to flush the output buffer. The difficult part is to call these enough to 
flush the buffer when necessary, but not so much as to eliminate the advantages of the buffer- 
ing. There is no ideal solution to this problem. 

uses 450K of disk space on this system. Therefore, the various libraries account for about two-thirds of the disk 
space used, even for a large program. 
*For a detailed discussion of Xlib's network optimization and its effects, see the introduction to Volume Zero, X 
Protocol Reference Manual. 

Miscellaneous Toolkit Programming Techniques 467 



On multi-tasking systems it is perhaps possible to fork so that each application context runs 
in a separate process. 

14.10.3 

Functions Used with Multiple Application Contexts 

XtWi dget ToAppl i c a t i onCont ext and XtDi spl ayToAppl i c a t i onCont ext 
could be useful if you use more than one application context in an application. XtWidget- 
ToApplicationContext is also useful in widget code, to call error-issuing routines 
that require an application context argument, such as XtAppWarning and XtApp- 
Wa rningMsg. 

14.11 Multiple Top-level Shells 

A single application can have more than one top-level window. In other words, you are not 
restricted to containing your application's entire user interface in a single rectangle. If you 
have one section of the application that is most appropriate as a long, thin vertical window 
that looks like a long, permanent menu, and another section that is a long, horizontal bar such 
as a ruler, each of these could be a separate top-level window. That way, not only is less 
screen space wasted than if these two windows were placed within a single rectangle, but the 
user can move the two windows around separately using the window manager. The user can 
also iconify them separately when not needed. 
To create additional top-level application shell widgets, you call XtAppCreateShell or 
XtVaAppCreateShell. (XtCreateApplicationShell is now superceded.) The 
class specified in the call should be topLevelShellWidgetClass. 
As you may know, a single server may have several screens attached. At present, all shells 
created will appear on the default screen. There is no way for the application to specify that 
a shell be created on a particular screen, but then again, doing this is usually unwise anyway 
because not many users actually have more than one screen. The user can specify which 
screen is considered the default screen using the -display command-line option. 

14.12 Connecting to Multiple Servers 

One of the great features of the server-client model is that a single program can connect to 
several servers to display on the screens of several users. For example, this would allow you 
to create an X-based version of the UNIX utility wall in which one user can make a message 
appear on all user's screens throughout a network. You could also create a conferencing pro- 
gram in which each user has a window on their screen in which they can type and view typ- 
ing by others in real time, and their typing will appear on all the other user's screens. 

The Xt application opens a connection with a server using XtOpenDisplay (this routine 
requires an explicit application context argument). Once you have opened the connection, 
you will want to create a shell widget on the server's default screen using xtCreate- 

468 X Toolkit Intrinsics Programming Manual, Motif Edition 



ApplicationShell or XtAppCreateShell. Then, you create widgets for each 
server simply by using the appropriate Shell widget as parent Thereafter, XtAppMain- 
Loop dispatches events from all the connections to the appropriate widget 

14.13 Class Extension Structures 

X Consortium standards, once adopted, can only be changed in ways that are binary and 
source compatible with the original standard specification. Xt became an X consortium stan- 
dard in Release 3. Therefore, Release 4 and later releases are required to be source and bi- 
nary compatible with Release 3. Source compatibility means that properly coded applica- 
tions and widgets written to the R3 specification should compile and work under R4 and later 
releases. Source compatibility is maintained by keeping all programming interfaces intact 
while adding features with new interfaces. Binary compatibility means that widgets written 
and compiled with R3 must be able to be linked with R4 Xt and Xlib libraries and still run. 
Source compatibility is necessary but not sufficient for binary compatibility. The major addi- 
tion requirement of binary compatibility is that fields added to structures must be added to 
the end of the structure. 
In Chapter 6, Inside a Widget, you saw how a class structure for a widget class is built by 
nesting the class part structures of all its superclasses into one big structure, the class record. 
The X consortium could not simply add fields to the class part structures of the basic Xt 
classes without breaking binary compatibility with existing subclasses because the class parts 
of basic Xt classes appear in the middle of the class record of subclasses. Therefore, they 
used extension structures to add these fields. 
Class extension structures allowed the X consortium to add to the class structures of basic Xt 
classes. The last field of each basic Xt class is called extension. This field can be set to a 
pointer to the class's extension structure, which contains its added fields. New features that 
required additional class structure fields were added to the Composite and Constraint classes 
in R4. Therefore, these two classes now have extension structures. 
Some classes, such as Core, do not have an extension structure because no additional class 
fields have yet been necessary. They still have the extension field, but it is not used. 
A class extension structure is defined in the private header file of a widget class. The exten- 
sion structure for Composite is called CompositeClassExtensionRec as shown in 
Example 14-2. 

Examp 14-2. Common fields  a css exnsn record 
typedef struct { 
XtPointer next extension;/* Ist 4 mandated for all ext rec */ 
XrmQuark record type; /* NULLQUARK; on CompositeClassPart */ 
long version; -- /* must be XtCompositeExtensionVersion */ 
Cardinal record size; /* sizeof(CompositeClassExtensionRec) */ 
-- 
Boolean accepts_objects; 
} CompositeClassExtensionRec, *CompositeClassExtension; 
All extension structures sta with the same four fields. The only field in this structure actu- 
ally used by Composi is accepts_objects, the use of which is described in Section 

Miscellaneous Toolkit Programming Techniques 469 



A 

Athena, OPEN LOOK, and Motif 

This appendix gives an overview of the widgets available in the AT& T widget 
set (also known as Xt+) and OSF Motif widget set. It gives a sense of the 
look and feel of applications developed with each set, and provides the inher- 
itance hierarchy and overview of the available widgets. 

In This Appendix: 

The AT&T OPEN LOOK Widgets ......................................................... 477 
Application Controls ....................................................................... 478 
Command Buttons ....................................................................... 478 
Exclusive and Nonexclusive Settings ........................................... 480 
Analog Controls ........................................................................... 482 
Composite Widgets ........................................................................ 482 
Menus and Control Areas ............................................................ 482 
General Purpose Composite Widgets .......................................... 483 
Scrollbars and Scrollable Windows .............................................. 483 
Popups .......................................................................................... 485 
Text Widgets .................................................................................. 487 
Drawing Areas ............................................................................... 487 
The OSF/Motif Widgets ...................................................................... 487 
Application Controls ....................................................................... 490 
Command Buttons ....................................................................... 490 
Analog Controls ........................................................................... 490 
Composite Widgets ........................................................................ 491 
Menus and Control Areas ............................................................ 491 
General Purpose Composite Widgets .......................................... 494 
Scrollable Windows ...................................................................... 495 
Popups .......................................................................................... 496 
Text Widgets .................................................................................. 497 
Drawing Areas ............................................................................... 497 



AT&T UNIX System V Release 4 licensees. In our discussions, we are referring specifically 
to AT&T's OPEN LOOK toolkit, which does not necessarily include every OPEN LOOK fea- 
ture. Nor should its implementation be considered the only way to provide features called for 
by OPEN LOOK. 
The Open Software Foundation's Motif toolkit is based on a combination of widget sets orig- 
inally developed by two OSF sponsors, Digital and Hewlett Packard. The look and feel of 
the widget set was proposed by HP/Microsoft. It is designed to emulate the look and feel of 
the IBM/Microsoft Presentation Manager standard widely expected to be adopted in the 
microcomputer world. Motif 1.1, released in August 1990, is described here. 
Table A- 1 compares the widgets available in Athena, AT&T OPEN LOOK set, and Motif. 

Table A-1. Comparison of Athena, OPEN LOOK, and Motif Widgets 

Command 
Toggle 
-- 

MenuButton 

Simple widgets (mostly controls): 
Athena OPEN LOOK 
OblongButton 
RectButton 
CheckBox* 
ButtonStack 
AbbrevStack 
-- 
ScrollingList* 

Scrollbar 

Grip 
Text 

Motif 

PushButton 
DrawnButton 
ToggleButton 
CheckBox, RadioBox 

CascadeButton 

OptionMenu 

ArrowButton 

List 

Scrollbar 

Slider 

StaticText 
Text 
TextField 

ScrollBar 

Scale* 

Label 
Text 
TextFieid 

Separator 

Description 

Invokes a command 
Invokes a command 
Chooses a setting 
Alternate way of 
choosing a setting 
Invokes a menu, dis- 
plays label 
Invokes a menu, dis- 
plays default 
Reverses direction of 
movement 
Displays a list of select- 
able strings 
Scrolls through an 
associated window 
Sets (or displays) an 
analog value 
Resize point for panes 
in VPaned 
Displays a fixed string 
Displays editable text 
Displays a single line 
of editable text 
Displays a line or other 
separator 

*CheckBox, ScrollingList, and Scale are technically composite widgets. 

474 X Toolkit Intrinsics Programming Manual Motif Edition 



Table A-1. Comparison of Athena, OPEN LOOK, and Motif Widget (continued) 
Popups (subclasses of shell): 

Athena 

SimpleMenu 

OPEN LOOK 

Menu 
Nodce 

PopupWindow 

Help 

Motif 

MenuShell 
DialogShell 

MessageBox 

MessageBox 

Description 

Parents a Ix)pup menu 
Displays a dialog 
requiring input 
Displays a more com- 
plex dialog 
Displays a help win- 
dow 

Composite and Constraint Widgets: 
Athena OPEN LOOK 

Box 

Viewlx)rt 

VPancd 

BulletinBoard 

ControlArea 

Motif 

BulletinBoard 

Exclusives 
Nonexclusives 

FooterPanel 

ScrollingList* 

Caption 
ScrollingWindow 

DrawingArea 
-- 

RowColumn 

FralTle 

SelectionBox 

Command 

FileSelectionBox 

ScrolledWindow 

MainWindow 

PanedWindow 

Description 

Free-form placement 
area 
Free-form drawing area 
Displays children in 
order added 
Arranges children in 
rows or columns 
Manages children rela- 
tive to each other 
Makes RectButton chil- 
dren exclusive 
Makes RectButton chil- 
dren nonexclusive 
Provides a consistently- 
sized message area 
Gives consistent border 
to enclosed widgets 
Provides a selectable 
list of slrings, plus a 
text area for entering a 
new value 
Provides a selectable 
list of commands 
Provides a selectable 
list of filenames 
Displays a label and 
one child widget 
Displays a scrollable 
child window 
ScrolledWindow with 
special appearance 
Displays panes resiz- 
able in one direction 

*Checkbox, ScrollingList, and Scale are technically composite widgets. 

Appendix A: Athena, OPEN LOOK, and Motif 475 



Search String 
Ignore case 
() 

Whole word only j 

A.1.1.3 

Figure A-5. An OPEN LOOK CheckBox widget 

Analog Controls 

In addition to the various kinds of buttons outlined above, OPEN LOOK provides an analog 
control called a Slider. A Slider widget is used analogously to a Scrollbar but is used for set- 
ting a numeric value. Figure A-6 shows a Slider widget. 

o El El ,l-] ,oo 

Figure A-6. An OPEN LOOK Slider widget 

A.1.2 Composite Widgets 

Composite widgets are in many ways the most important widgets in any widget set. They 
define the way that widgets work together, and they give consistency to an application. 

A.1.2.1 Menus and Control Areas 

As we've already discussed, command buttons of any kind are usually displayed as part of a 
menu or control area. 
Menus can either pop up below a ButtonStack or an AbbrevStack, or if the button is itself 
displayed on a menu, to the right, in a menu cascade. Figure A-4 showed examples of menus. 
The Menu widget is a popup widget created with Xt.Creat.ePopupShe].].. It has a single 
child, which is a ControlArea widget. 
The ControlArea widget places its children in rows or columns. Resources allow the applica- 
tion to specify a fixed width and/or height, or a fixed number of rows or columns. Control- 
Area widgets are usually used as the parent of OblongButton, ButtonStack, Exclusives, or 
Nonexclusives widgets (which in turn manage RectButton widgets, as described in the next 
section). 

482 X Toolkit Intrinsics Programming Manual, Motif Edition 



A.1.2.2 General Purpose Composite Widgets 

A.1.2.3 

We've already discussed the Composite widgets relating to control areas and menus. How- 
ever, there are several general-purpose composite widgets in the OPEN LOOK set as well. 
The BulletinBoard widget provides a free-form area for placing subwindows. Widgets can 
be placed on a BulletinBoard at arbitrary x and y coordinates; if no coordinates are specified, 
they appear in the upper left corner. The BulletinBoard provides no management of its chil- 
dren, and is often used to estabish the base frame for an application, since it allows the appli- 
cation programmer to place the major components of the application, rather than having to go 
by some Composite widget's arbitrary placement decisions. 
A BulletinBoard is often used as the main window of an application. 
The Form widget is a constraint widget similar to the Athena Form widget. It allows the 
placement of widgets to be specified relative to each other, and with rules governing their 
separation or relative position. 
The Caption widget is like an Athena Label widget turned inside out. Like the Label widget, 
it prints a string. However, while the label widget's string is printed inside a visible widget 
border, a Caption string appears outside a bordered area. Caption is a composite widget 
class, and its label typically refers to a child widget of any size, which the Caption widget 
manages. The label can be aligned on either the right, left, top or bottom of the child widget. 
The FooterPanel widget provides a consistent method for placing a footer along the bottom 
of another window. The footer panel takes two children. The top child is typically the main 
composite widget of the application; the bottom widget may contain a control or message 
area. The basic feature-of the FooterPanel widget is that when the widget is resized, it 
applies all the change in the vertical direction to the top child, maintaining the bottom child 
at a constant height. 

Scrollbars and Scrollable Windows 

OPEN LOOK scrollbars use the visual metaphor of an elevator on a cable, but functionally 
they are similar to the Athena Scrollbar widget. The drag area (the thumb in an Athena 
Scrollbar widget) doesn't change size; instead, as shown in Figure A-7, there is a separate 
area that indicates the proportion of the data that is currently being displayed. 
Scrollbars may be oriented either horizontally or vertically. 
Scrollbars are used as a component of a ScrolledWindow widget, which, like the Athena 
Viewport widget, provides a scrollable view of a data area in a child widget. The child 
widget is typically larger than the view area, but only the area in the parent's view area can 
be seen at any one time. Figure A-1 showed a ScrolledWindow widget as the main applica- 
tion pane. The ScrollingList widget displays a scrollable list of editable text fields, and pro- 
vides facilities for choosing and displaying one of the fields as "currently selected." Items 
can be selected from the list, changed, copied, and so on. This widget is useful for providing 
an interface to select a file for reading or writing. 

Appendix A: Athena, OPEN LOOK, and Motif 483 



elevator -- - 
"l 

top cable anchor 
up arrow 
drag area 
down arrow 
proportion indicator 

cable 

bottom cable anchor 

Figure A-7. An OPEN LOOK Scrollbar 
Figure A-8 shows a ScrollingList widget. 

Current Item border 
surrounding Current Item 1 
! 
Appendix A 
Chapter 1 
Chapter 2 
Chapter 3 

scrollbar 

Figure A-8. An OPEN LOOK ScrollingList widget 

484 X Toolkit Intrinsics Programming Manual, Motif Edition 



A.1.3 Popups 

In addition to Menu widgets, the OPEN LOOK widget set contains three other special types of 
popup widgets: Notices, PopupWindows, and Help windows. A Notice is used to request 
confirmation or other information from the user. The widget contains a text area, where the 
message to the user is displayed, and a control area containing one or more buttons, one of 
which must be the default button. 

Figure A-9 shows an OPEN LOOK Notice widgeL 

File Exists. Overwrite it? 

Figure A-9. An OPEN LOOK Notice 

A Notice grabs the pointer. The only input allowed is to the Notice. Once the user has 
clicked a button, the Notice disappears. 
The second special popup type is a PopupWindow, which can be used for more complex pop- 
ups. Unlike a Notice, which is a subclass of OverrideShell, a PopupWindowShell is a sub- 
class of WMShelI, and so is decorated by the window manager. It has all the visual attributes 
of a top-level window, including resize corners, etc. In addition, it displays a pushpin in the 
upper left corner. If the user clicks on the pushpin with the pointer, the menu doesn't go 
away when its action has been performed, but stays on the screen. This allows the user to 
keep menus (and other frequently-referenced popups, such as help screens) "pinned" on the 
display, where they can be moved like regular windows. (Menus can also display a pushpin; 
its presence or absence is controlled by a widget resource.) 
A PopupWindow typically contains an upper control area that may include menus, and a 
lower control area that may be used for buttons invoking widget actions. Resources allow for 
automatic creation of several buttons, including a "reset to factory" button, a "set defaults" 
button, and several other ways of setting standard properties for an application. 

Appendix A: Athena, OPEN LOOK, and Motif 485 



Figure A-10 shows a PopupWindow. 

Edit: Search and Replace 

Search For: 
Replace Wth: 

I Ignore Case I IForward 1 
Iild Card Searches I Backward 

I raparound Searches [ 

Figure A-I O. An OPEN LOOK PopupWindow 

A Help window is not instantiated in the usual way. Instead, an application uses the Oi- 
legLstez:He]_p function to register help text with the toolkit. Text can be associated with 
a widget class, a widget instance, or a window. When the user clicks the second pointer but- 
ton on an object, the Help widget is automatically displayed by the toolkit. The Help widget 
includes a Magnifier subwidget, which displays a magnifying glass containing an image of 
the part of the screen on which the user clicked the pointer. Figure A-11 shows a Help win- 
dow. 

[dit Help: Pushpin 

Use the pushpin to keep a pop-up window 
or a menu pinned to the workspace for 
continued access. 

Move the pointer to an unpinned pushpin and 
click SELECT to push the pin into the hole, 
pinning the window or menu to the workspace. 
Click SELECT on a pinned pushpin to pop the 
pin out of the hole and dismiss the pop-up 
window or the menu. 

Figure A-11. An OPEN LOOK Help window 

486 X Toolkit Intrinsics Programming Manual, Motif Edition 



A.2.1 Application Controls 

Like OPEN LOOK, Motif has a much richer set of application controls than Athena. 

A.2.1.1 

Command Buttons 

Motif's PushButton is equivalent to Athena's Command widget and OPEN LOOK's Rect- 
Button. It has a 3-D appearance and seems to be depressed when clicked on. It invokes sep- 
arate callbacks for button up, button down, and button click, much like the equivalent widg- 
ets in other sets. 
The DrawnButton works similarly, but allows the programmer to provide a pixmap for the 
appearance of the button. 
Figure A-14 shows a DrawnButton and a PushButton. 

Cancel 

Figure A-14. Motif DrawnButton and PushButton widgets 

The CascadeButton is similar in effect to OPEN LOOK's ButtonStackmit can have a particu- 
lar appearance that indicates that a menu is invoked, rather than a single callback. Typically, 
this is simply an arrow pointing in the direction where the menu will appear. 
A ToggleButton is used for option setting, much like OPEN LOOK's RectButton or Check- 
Box. Figure A-16 shows a box containing a set of ToggleButtons. 
The Separator widget can be used to draw a line or other separator between a group of widg- 
ets in a menu or other box. It is typically used in menus. 
The List widget displays a list of strings set by the application and allows the user to select 
one or more of the strings. The selected data is passed to a callback function. (We'll talk 
more about this widget in the section on scrolling.) 

A.2.1.2 

Analog Controls 
Motif's Scale widget is similar to OPEN LOOK's Slider but is more powerful since it can be 
used to display as well as to control analog values. 

490 X Toolkit Intrinsics Programming Manual, Motif Edition 



A.2.2 Composite Widgets 

A.2.2.1 

As with OPEN LOOK, we've divided the discussion of Composite widgets into three areas: 
Menus and Control Areas, General-Purpose Composite Widgets, and Scrollable Windows. 
These distinctions are somewhat arbitrary and with menus the sections overlap with the one 
on popups, which appears later. 

Menus and Control Areas 

Motif provides a special Shell widget class called MenuShell for managing popup menus. 
However, most actual menu displays are managed by the RowColumn composite widget, 
which, like OPEN LOOK's ControlArea, displays buttons in rows or columns. 
Through resources, the RowColumn widget can be configured to create such specialized, 
predefined elements as a MenuBar (which can only accept CascadeButton widgets as chil- 
dren), several different styles of pulldown or popup menu panes, and several preconfigured 
control areas, such as a "Radio Box" containing multiple exclusive ToggleButton gadgets. 
Here you can begin to see the wide divergence in programming style made possible by the Xt 
Inlrinsics. It is possible to create a hierarchy of relatively simple widgets to perform separate 
parts of a task, or a single, very complex widget which is highly configurable. In one of its 
incarnations, the RowColumn widget is equivalent to an OPEN LOOK ControlArea plus an 
Exclusives widget; in another, a ControlArea plus a Nonexclusives. 
In general, Motif widgets are more complex and have many more resources than widgets pro- 
vided in other widget sets. To simplify their use, though, Motif provides numerous conve- 
nience functions. For ekample, XmCx:oat:oRadi oBox will create a RowColumn widget 
with one specialized set of resources, while XrnCx:oat:oHonuBax: will create one that is 
entirely different in appearance and function. 
Figure A-15 shows a RowColumn widget configured as a MenuBar and Figure A-16 shows 
one configured as a RadioBox (each with appropriate children). 

Appendix A: Athena, OPEN LOOK, and Motif 491 



menu bar- 

Figure A-15. A Motif RowColumn widget configured as a MenuBar 

V Don't care 
V Normal 
V Oblique 
Italic 
Reverse 
V Italic 

V Don't care V Don't care V 10 point 
V Normal ). Times V 12point 
Bold V Helvetica 14 point 
V Demi V Avant Garde V 18 point 
V Book 

Figure A-16. A Motif RowColumn widget configured with four RadioBoxes 

492 X Toolkit Intrinsics Programming Manual, Motif Edition 



Figure A-17 shows a RowColumn widget implementing a pulldown menu. 
Items on Motif menus can be selected by dragging the pointer down the menu and releasing 
it when the chosen item is highlighted. Alternately, the pointer can simply be clicked on the 
menu title to drop down the menu. Clicking on an item in the menu selects it; clicking any- 
where other than in the menu pops the menu down without executing any item. 
Note also that as a general feature, Motif menus support accelerators. That is, there are key- 
board equivalents for every menu item. These keyboard accelerators are listed after the 
menu label, as shown above. In addition, typing the underlined letter in any menu item label 
when the pointer is in the menu will select that menu item. These underlined letters are 
called "mnemonics." 
The items on a menubar or menu pane simply appear as labels but when selected take on the 
3-D appearance of a PushBuuon. 

N_,ew ....... ^N 
en ...... 
ave ...... 
Save A...s .... ^A -i 
Exit ....... ^E 

Figure A- 17. A Motif RowColumn widget configured as a pulldown menu 

Appendix A: Athena, OPEN LOOK, and Motif 493 



A.2.2.3 Scrollable Windows 

A Motif ScrollBar is illustrated in Figure A-19. 

Figure A-19. A Motif ScrollBar 

Like the Athena Scrollbar widget, the scrollbar has a "thumb" or slider that can be dragged 
up and down to scroll the associated window. You can also click above or below the thumb 
to move it a screenful at a time. Unlike the Athena widget, it also displays arrows at either 
end that can be used to scroll line by line. The associated window scrolls in the indicated 
direction as long as the pointer button is held down in one of the arrows. 
There are several different types of scrolling windows. The ScrolledWindow widget, like 
Athena's Viewport, provides a general mechanism for attaching scrollbars to some other win- 
dow. 
The MainWindow widget is a subclass of ScrolledWindow with a special appearance 
reserved for application main windows. Figure A-14 showed a MainWindow widget. 
Using the XmCreateScrolledList function, a List widget can be created as a child of 
a ScrolledWindow, giving the effect of a simple scrolled list. In addition, there are several 
flavors of more complex scrolling lists. These include the SelectionBox widget, and its two 
subclasses, Command and FileSelectionBox. 
A general-purpose SelectionBox is akin to a ScrolledWindow/List combination, but adds a 
Text widget for entering additional data not on the list. The SelectionBox also adds at least 
three buttons labeled by default OK, Cancel, and ttelp. 

Figure A-20 shows a SelectionBox. 

Appendix A: Athena, OPEN LOOK, and Motif 495 



Items 

*Foreground ......................... black 
*activeForeground .................... black 
*activeBackground .................... gray 
*topShadowColor ..................... white 
*bottomShadowColor .................. black 

Selection 
............... ,,,,,,,,,, ................... 

list box 

scroll bars 

selection box 

push buon 

Figure A-20. A Motif SelectionBox 

A FileSelectionBox is a SelectionBox specially designed to present a list of filenames for 
selections. A Command widget is a special kind of SelectionBox whose list consists of the 
history of commands entered in the Text widget. Each time a new command is entered, it is 
added to the history list. 

A.2.3 Popups 

Motif defines two classes of Shell widgets: DialogShell, which is used for parenting Dialog 
boxes, and MenuShell, which is used for menus. These classes are rarely instantiated 
directly, but are instead created by convenience functions that also create their composite 
children. 

For example, functions exist to create a DialogShell with a variety of pre-configured 
MessageBox widgets as the visible child. 

As we've already discussed, a specially configured RowColumn widget is used to create a 
menu pane as the visible child of a MenuShell widget. 

496 X Toolkit Intrinsics Programming Manual, Motif Edition 



A.2.4 Text Widgets 

Like Athena and the AT&T OPEN LOOK widgets, Motif provides a Text widget that supports 
a complete editing command set. Like Athena, and unlike AT&T's OPEN LOOK widget set, 
both single- and multiline editing is supported by a single widget. But arranging for single- 
line editing is easier with Motif than with Athena. 

A.2.5 

Drawing Areas 

As you may recall, to do drawing in the Athena widgets we either created a custom widget or 
instantiated a Core widget in order to obtain a window for drawing. The Motif DrawingArea 
widget class answers this need in Motif. It provides a window for drawing and provides very 
simple, bulletin-board like composite management of children. 

Though the name of this widget class sounds promising, you should be aware that Motif 
really provides no more sophisticated drawing capabilities than Athena or the AT&T OPEN 
LOOK widget set. In each case, once you have selected the widget to draw on, you simply 
draw in its window using Xlib calls. 

Appendix A: Athena, OPEN LOOK, and Motif 497 



B 

Specifying Fonts and Colors 

This appendix describes the possible values for color, font, and geometry 
resource specifications. 

In This Appendix: 

Color Specification ............................................................................. 501 
Color Names ................................................................................. 501 
Hexadecimal Color Specification .................................................... 502 
The RGB Color Model .................................................................. 503 
How Many Colors are Available? ................................................. 504 
Font Specification .............................................................................. 506 
Font Naming Conventions .............................................................. 507 
Font Name Wildcarding .................................................................. 508 
Font Name Aliasing ....................................................................... 510 
Making the Server Aware of Aliases ............................................... 511 
The fonts.dir Files .......................................................................... 511 
Window Geometry ............................................................................. 512 



B 
Specifying Fonts and Colors 

B.1 

This appendix describes the possible values for color, font, and geometry resource specifica- 
tions. 

Color Specification 

Many clients have resources and command-line options that allow you to specify the color of 
the window background, foreground (the color that text or graphic elements will be drawn 
in), or window border. For example, the following resources might be set for a Label widget: 
*background : orange set the background color to orange 
* foreground : black set the foreground color to black 
*borderColor : black This must be Halloween! 
The corresponding command-line options have the form: 
-bg col or sets the background color 
-fg col or sets the foreground color 
-bd col or sets the border color 
Some clients allow additional options to specify color for other elements, such as the cursor, 
highlighting, and so on. 
By default, the background is usually white and the foreground black, even on color worksta- 
tions. You can specify a new color using either the names in the X Window System's color 
name database or hexadecimal values. 

B.1.1 Color Names 

The rgb.txt file, usually located in lusrlliblX11 on UNIX systems, is supplied with X and con- 
sists of predefined colors assigned to specific (but not necessarily intuitive) names.* 

*A corresponding compiled file called rgb.pag contains the definitions used by the server;, the rgb.txt file is the 
human-readable equivalent. 

Appendix B: Specifying Fonts and Colors 501 



The following are some of the default color names that come with the X Window System. 
(See Appendix A, System Management, in Volume Three, X Window System User's Guide, 
Motif Edition, for information on customizing color name definitions.) This file is not part of 
the X standard, so vendors are free to modify it. However, most will just add to it, or redefine 
the values associated with each color name for better effects on their display hardware. 

aquamarine medlumaquamarlne black blue 
cadetblue cornflowerblue darkslateblue llghtblue 
lightsteelblue mediumblue mediumslateblue midnightblue 
navyblue navy skyblue slateblue 
steelblue coral cyan firebrick 
gold goldenrod mediumgoldenrod green 
darkgreen darkolivegreen forestgreen limegreen 
mediumforestgreen medlumseagreen mediumsprlnggreen palegreen 
seagreen sprlnggreen yellowgreen darkslategray 
darkslategray dimgray dimgray lightgray 
lightgray khaki magenta maroon 
orange orchid darkorchid mediumorchid 
pink plum red indianred 
mediumvioletred orangered violetred salmon 
sienna tan thistle turquoise 
darkturquoise mediumturquoise violet blueviolet 
wheat white yellow greenyellow 

As of R4, a number zero through three can be appended to each of these names in order to get 
various intensities of each color. In addition, a complete range of grays are provided by 
using the name gray or gray followed by a number from zero through 100. There are also a 
few colors not provided in the R3 database, such as snow and misty rose. These names can be 
used directly when the specific color is wanted. 
For example, the command line: 
% xterm -bg lightblue -fg darkslategray -bd plum & 
creates an xterm window with a background of light blue, foreground of dark slate gray, and 
border of plum. Note that the RGB values in the color database provided by MIT are correct 
for only one type of display; you may find that the color you get is not exactly what you 
expect given the name. To combat this, vendors may have corrected the RGB values to give 
colors closer to what the name implies. 
At the command line, a color name should be typed as a single word (for example, da rk- 
slategray). However, you can type the words comprising a color name separately if you 
enclose them in quotes, as in the following command line: 
% xterm -bg "light blue" -fg "dark slate gray" -bd plum & 

B.1.2 

Hexadecimal Color Specification 

You can also specify colors more exactly using a hexadecimal color string. You probably 
won't use this method unless you require a color not available by using a color name. More- 
over, you shouldn't use this method unless necessary because it tends to discourage the shar- 

502 X Toolkit Intrinsics Programming Manual, Motif Edition 



B.1.2.1 

ing of colors between applications. In order to understand how this works, you may need a 
little background on how color is implemented on most workstations. 

The RGB Color Model 

Most color displays on the market today are based on the RGB color model. Each pixel on 
the screen is actually made up of three phosphors: one red, one green, and one blue. Each of 
these three phosphors is excited by a separate electron beam. When all three phosphors are 
fully illuminated, the pixel appears white to the human eye. When all three are dark, the 
pixel appears black. When the illumination of each primary color varies, the three phosphors 
generate a subtractive color. For example, equal portions of red and green, with no admix- 
ture of blue, makes yellow. 
As you might guess, the intensity of each primary color is controlled by a three-part digital 
value--and it is the exact makeup of this value that the hexadecimal specification allows you 
to seL 
Depending on the underlying hardware, different servers may use a larger or smaller number 
of bits (from 4 to 16 bits) to describe the intensity of each primary. To insulate you from this 
variation, clients are designed to take color values containing anywhere from 4 to 16 bits (1 
to 4 hex digits), and the server then scales them to the hardware. As a result, you can specify 
hexadecimal values in any one of the following formats: 
#RGB 
#RRGGBB 
#RRRGGGBBB 
#RRRRGGGGBBBB 
where R, G, and B represent single hexadecimal digits and determine the intensity of the red, 
green, and blue primaries that make up each color. 
When fewer than four digits are used, they represent the most significant bits of the value. 
For example, #3a6 is the same as #3000a0006000. 
What this means concretely is perhaps best illustrated by looking at the values that corre- 
spond to some colors in the color name database. We'll use 8-bit values (two hexadecimal 
digits for each primary) because that is the way they are defined in the rgb.txt file: 

#000000 black 
#FCFCFC white 
#FF0000 red 
#00FF00 green 
#0000FF blue 
#FFFF00 yellow 
#00FFFF cyan 
#FF00FF magenta 
#SF9F9F cadet blue 
#42426F cornflower blue 
#BFD8D8 light blue 
#8F8FBC light steel blue 
#3232CC medium blue 
#23238E navy blue 
#3299CC sky blue 

Appendix B: Specifying Fonts and Colors 503 



B.1.2.2 

#007FFF slate blue 
#236B8E steel blue 

As you can see from the colors given above, pure red, green, and blue result from the corre- 
sponding bits being turned full on. All primaries off yields black, while all nearly full on 
gives white. Yellow, cyan, and magenta can be created by pairing two of the other primaries 
at full intensity. The various shades of blue shown above are created by varying the intensity 
of each primary msometimes in unexpected ways. 

The bottom line here is that if you don't intimately know the physics of color, the best you 
can do is to look up existing colors from the color name database and experiment with them 
by varying one or more of the primaries till you find a color you like. Unless you need pre- 
cise colors, you are probably better off using color names. 

If you do specify a color using a hexadecimal value, try to use the same value for several 
applications so that they will share a color call. 

In any event, using hexadecimal values for colors is not generally recommended, since it dis- 
courages sharing of color cells. 

How Many Colors are Available? 

The number of distinct colors available on the screen at any one time depends on the amount 
of memory available for color specification. 
A color display uses multiple bits per pixel (also referred to as multiple planes or the depth of 
the display) to select colors. Programs that draw in color use the value of these bits as a 
pointer to a lookup table called a colormap, in which each entry (or colorcell) contains the 
RGB values for a particular color.* As shown in Figure B-l, any given pixel value is used as 
an index into this table--for example, a pixel value of 16 will select the sixteenth colorcell. 
This implementation explains several issues that you might encounter in working with color 
displays. 
First, the range of colors possible on the display is a function of the number of bits available 
in the colormap for RGB specification. If 8 bits are available for each primary, then the 
range of possible colors is 256 3 (somewhere over 16 million colors). This means that you 
can create incredibly precise differences between colors. 
However, the number of different colors that can be displayed on the screen at any one time 
is a function of the number of planes. A four-plane system can index 2 4 colorcells (16 dis- 
tinct colors); an eight-plane system can index 2 8 colorcells (256 distinct colors); and a 
24-plane system can index 2 24 colorcells (over 16 million distinct colors). 
If you are using a four-plane workstation, the fact that you can precisely define hundreds of 
different shades of blue is far less significant than the fact that you can't use them all at the 
same time. There isn't space for all of them to be stored in the colormap at one time. 
*There is a type of high-performance display in which pixel values are used directly to control the illumination of the 
red, green, and blue phosphors, but far more commonly, the bits per pixel are used indirectly, with the actual color 
values specified independently, as described here. 

504 X Toolkit Intrinsics Programming Manual, Motif Edition 



In order to minimize such conflicts, you should request precise colors only when necessary. 
By preference, use color names or hexadecimal specifications that you specified for other 
applications. 

For more information on color, see Chapter 7, Color, in Volume One, Xlib Programming 
Manual. 

B.2 Font Specification 

Most widgets that display text allow you to specify the font to be used in displaying text in 
the widget, via either the xt:Nfont: resource, or the -fn and -font command-line options. 
The X Window System supports many different display fonts, with different sizes and type 
styles. (These are screen fonts and are not to be confused with printer fonts.) 
For Release 3 and subsequent releases, Adobe Systems, Inc., and Digital Equipment Corpora- 
tion joindy contributed five families of screen fonts (Courier, Helvetica, New Century 
Schoolbook, Symbol and Times) in a variety of sizes, styles, and weights for 75 dots per inch 
monitors. Bitstream, Inc. contributed its Charter font family in the same sizes, styles, and 
weights for both 75 and 100 dots per inch monitors. 
Most Release 2 fonts have been moved to the user-contributed distribution 
(lusr/XI I r3/contriblfonts). 
In Release 3 and later, fonts are stored in three directories: 

Directory 

/usr/lib/X11/fonts/misc 
/usr/lib/X111fonts/75dpi 
/usr/lib/X111fonts1100dpi 

Contents 

Six fixed-width fonts (also available in Release 2), 
the cursor font. 
Fixed- and variable-width fonts, 75 dots per inch. 
Fixed- and variable-width fonts, 100 dots per inch. 

These three directories (in this order) comprise X's default font path. The font path can be 
changed with the fp option to the xset client, as described in Volume Three, X Window Sys- 
tem User's Guide, Motif Edition. (The font path, together with a great deal of other informa- 
tion about the server defaults, can be listed with xset query.) All fonts in the font path can be 
listed with xlsfonts, and the characters in a font can be displayed on the screen with xfd. 

The names of each font file in the font directories has a filename extension of .snf, which 
stands for server natural format. Fonts are distributed in binary distribution format (bdf), 
and may need to be adapted for a given server. 

506 X Toolkit Intrinsics Programming Manual, Motif Edition 



B.2.1 Font Naming Conventions 

In Release 2, font names were determined by the names of the files in which they are stored, 
without the .snfextension. For example, the fllefg-16.snfcontains the font named fg-16. 
If you do a listing of any of the current font directories, you'll notice that the filenames also 
have .snf extensions. However, font names are not determined by the names of the flies in 
which they are stored. 
Now, a font's name is determined by the contents of the font property named FONT* rather 
than the name of the file in which the font is stored. 
If you run xlsfonts, you'll get an intimidating list of names similar to the one shown in Figure 
B-2, which upon closer examination contains a great deal of useful information: 

vertical resolution in dpi 

points (in tenths average width (in 
foundry weight set width of a point) tenths of a pixel) 
-adobe-courier-bold-o-normal--lO-lOO-75-75-m-60-iso8859-1 
font family " slant pixels spacing character set 

horizontal resolution in dpi 

Figure B-2. A font name 

This rather verbose line is actually the name of the font stored in the file courB010 (in the 
75dpi directory). This font name specifies the foundry (Adobe), the font family (Courier), 
weight (bold), slant (Oblique), set width (normal), size of the font in pixels (10), size of the 
font in tenths of a point (100--measured in tenths of a point, thus equals 10 points), horizon- 
tal resolution (75dpi), vertical resolution (75dpi), spacing (m, for monospace), average width 
in tenths of a pixel (60--measured in tenths of a pixel, thus equals 6 pixels) and character set 
(iso8859-1). 

The meaning of many of these statistics is obvious. Some of the less obvious information is 
explained below. 

Foundry 

The type foundry (in this case, Adobe) that digitized and supplied the 
fonL 

*A property is a piece of information associated with a window or a font. See Volume One, Xlib Programming 
Manual, for more information about properties. 

Appendix B: Specifying Fonts and Colors 507 



Set width A value describing a font's proportionate width, according to the foun- 
dry. Typical set widths include: normal, condensed, narrow, double 
width. All of the newer fonts have the set width normal. 
Pixels and points Type is normally measured in points, a printer's unit equal to 1/72 of an 
inch. The size of a font in pixels depends on the resolution of the display 
font in pixels. For example, if the display font has 100 dots per inch (dpi) 
resolution, a 12 point font will have a pixel size of 17, while with 75 dpi 
resolution, a 12 point font will have a pixel size of 12. 
Spacing Either m (monospace, i.e., fixed-width) or p (proportional, i.e., variable- 
width). 
Horizontal and vertical resolution 
The resolution in dots per inch that a font is designed for. Horizontal and 
vertical figures are required because a screen may have different capaci- 
ties for horizontal and vertical resolution. 
Average width Mean width of all characters in the font, measured in tenths of a pixel, in 
this case 6 pixels. 
Character set ISO, the International Standards Organization, has defined character set 
standards for various languages. The iso8859-1 in Figure B-2 represents 
the ISO Latin 1 character set, which is used by all of the fonts in the 
75dpi and lOOdpi directories. The ISO Latin 1 character set is a superset 
of the standard ASCI/character set, which includes various special char- 
acters used in European languages other than English. See Appendix H 
of Volume Two, Xlib Reference Manual, for a complete listing of the 
characters in the ISO Latin 1 character set. 
This font-naming convention is intended to allow for the unique naming of fonts of any style, 
resolution and size. It is powerful, but unwieldy. 
To create a label widget that displays text in the font stored in the file courBOlO, you could 
use the resource setting: 
*label : -adobe-courier-bold-o-normal--10-100-75-75-m- 60-i so8859-1 
Since typing a font name of this length is neither desirable nor practical, the X Window Sys- 
tem developers have provided two alternatives: wildcarding and aliasing. 

B.2.2 

Font Name Wildcarding 

Any unnecessary part of a font name can be "wildcarded" by specifying a question mark (?) 
for any single character and an asterisk (*) for any group of characters. 
For example, using a wildcarded font name, the resource specification above could be writ- 
ten" 
*label : *courier-bold-o-*-100* 
(Note that when using wildcards with the -fn command line option, you must take care to 
quote the font names, since the UNIX shell has special meanings for the wildcard characters * 

508 X Toolkit Intrinsics Programming Manual, Motif Edition 



example, say you use the following name to specify a 24 point (size), medium (weight), Italic 
(slant) Charter (family) font: 
*charter-medlum-i-* -240-* 
This will match either of the following two font names (the first for 75 dpi monitors and the 
second for 100 dpi monitors): 
-bit st ream-cha r t e r-medium-i -normal - -25-24 O- 75- 75-p- 13 6-i so885 9-1 
-bit st ream-charter-medium-i-normal--33-240-i 00-i O0-p-i 3 6-iso885 9-i 
depending on which directory comes first in your font path. Specifying font size explicitly in 
pixels (25 for the first or 33 for the second) rather than in points would limit you to matching 
only one of these fonts. 
Given the complexity of font names and the rules of precedence used by the server, you 
should use wildcards carefully. 

B.2.3 

Font Name Aliasing 

Another way to abbreviate font names is by aliasing--that is, by associating them with alter- 
native names. You can create a file (or files) called fonts.alias, in any directory in the font 
search path, to set aliases for the fonts in that directory. The X server uses bothfonts.dir files 
(see Section B.2.5) and fonts.alias files to locate fonts in the font path. 
Be aware that when you create or edit a fonts.alias file, the server does not automatically 
recognize the aliases in question. You must make the server aware of newly created or edited 
alias files by resetting the font path with xset as described in Section B.2.4. 
The fonts.alias file has a two-column format similar to the fonts.dir file (described in a 
moment): the first column contains aliases, the second contains the actual font names. If you 
want to specify an alias that contains spaces, enclose the alias in double quotes. If you want 
to include double quotes or other special characters as part of an alias, precede each special 
symbol with a backslash. 
When you use an alias to specify a font in a command line, the server searches for the font 
associated with that alias in every directory in the font path. Therefore, a fonts.alias file in 
one directory can set aliases for fonts in other directories as well. You might choose to create 
a single alias file in one directory of the font path to set aliases for the most commonly used 
fonts in all the directories. Example B-1 shows a sample fonts.alias file. 
Example B-1. Sample fonts.alias file 
xterml2 -adobe-courl er-med lum-r-norma I--I 2-I 20-75-75-m-70- Iso8859-I 
xterml4 -adobe-courier-medium-r-norma I--I 4-I 40-75-75-m- 90- I so8859-I 
xterml8 -adobe-courl er-medium-r-norma I--I 8-I 80-75-75-m-I I0-I so8859-I 
As the names of the aliases suggest, this sample file contains aliases for three fonts (of differ- 
ent point sizes) that are easily readable in xterm windows. 
You can also use wildcards within the font names in the right hand column of an alias file. 
For instance, the alias file above might also be written: 

510 X Toolkit Intrinsics Programming Manual, Motif Edition 



Some clients may allow you to specify geometry strings for the size and position of the icon 
or an alternate window, usually through resources (in an .Xdefaults or other resource file). 
See the appropriate client reference pages in Part Three of Volume Three, X Window System 
User's Guide, Motif Edition, for a complete list of available resources. 

You should be aware that, as with all user preferences, you may not always get exactly what 
you ask for. Clients are designed to work with a window manager, which may have its own 
rules for window or icon size and placement. However, priority is always given to specific 
user requests, so you won't often be surprised. 

514 X Toolkit Intrinsics Programming Manual, Motif Edition 



C 

Naming Conventions 

This appendix describes a suggested set of conventions for naming widgets, 
and elements within widget code. 



Truncated include file names 

Macro names for preprocessor 
in include files 

Strip the lowercase letters a word at a time until the 
basename is nine characters or fewer (but strip as few 
letters as possible from the initial word). Thus: 
<Xm/Ve ryLongWidgetName, h> 
becomes: 
<Xm/Ve ryLWN, h> 
but: 
<Xm/Ve ryl ongwidget name. h> 
becomes: 
<Xm/Ve ryl ongw. h> 
(Note difference in VeryLong (two words) and very- 
1 ong (one word).) 
#ifndef XM LABEL H 

This is to prevent header files from being included more 
than once. 
If a widget has a corresponding gadget, then Gadget is 
appended to the widget name, so XmLabelGadget is 
the gadget class name. 
Widget class pointer xmLabe iWidgetCl a s s 
Gadget class pointer xmLabelGadgetClass 
Create function for widgets Widget XmCreateLabel (parent, name, 
or gadgets a rgl i s t, a rgc ount) 
This is a shorut to using XtCreateWidget. How- 
ever, in the case of top-level widgets (menus, dialogs, 
MainWindow), it also creates the shell widget and creates 
the requested widget within it. 
The special Create functions can also be used as conve- 
nience routines for specialized widget instances. For 
example, XmCreateWorkingDialog and Xm- 
CreateWarningDialog actually create a Message- 
Box whose XmDialogType resources are respectively 
XmDIALOG WARNING and XmDIALOG WORKING. 
OPEN LOOK uses conventions similar to Motif, but leaves the prefixes off the widget class 
name. We recommend that you supply a prefix for any widgets you write, especially if there 
is any chance that some other widget set may use the same class name. In other words, if we 
wrote a new Label widget, we might call it OraLabel, not just Label, so that we could still use 
the Athena Label widget in the same application. 

518 X Too&# Intrinsics Programming Manual, Motif Edition 



D 

Release Notes 

This appendix summarizes changes between Release 3 and Release 4 of 
the X Toolkit, as it applies to writing or converting widgets and applications. 

In This Appendix: 

Summary of New Functions and Procedure Types ............................. 521 
Application Writing ............................................................................. 524 
New Function for Initializing an Application ..................................... 524 
Varargs Interfaces ......................................................................... 524 
Special Types for Varargs List Members ...................................... 525 
Loading the Resource Database .................................................... 525 
The Language String ................................................................... 525 
New Built-in Application Resources .............................................. 526 
Fallback Resources ..................................................................... 526 
Parsing the Command Line ............................................................ 526 
Changes Affecting Both Application and Widget Writing ..................... 527 
Actions .......................................................................................... 527 
Directly Invoking Actions .............................................................. 527 
Action Hook Registration ............................................................. 527 
Obtaining Event Information in an Action Procedure .................... 527 
Registering Button and Key Grabs For Actions ............................ 528 
Action Functions and Unrealized Widgets .................................... 528 
Reserved Names for Resources and Actions ................................. 528 
Resource String Identifier Convention ............................................ 528 
Resource File Format .................................................................... 528 
Modifier Names ............................................................................. 529 
Determining Specification Revision Level ....................................... 529 
Implementation-specific Datatype Definitions ................................. 529 
Event Handlers .............................................................................. 530 
Error and Warning Handlers ........................................................... 530 
Changes Affecting Widget Writing ...................................................... 530 



New Name for Core Class ............................................................. 530 
File Content Changes .................................................................... 531 
Changes to Private .h Files .......................................................... 531 
Changes to .c Files ...................................................................... 531 
Class Extension Structures ............................................................ 531 
Composite Class Extension Structure .......................................... 533 
Constraint Class Extension Structure ........................................... 533 
New Constraint get_values_hook method .................................... 533 
Shell Class Extension Structure ................................................... 534 
New XtNvisual Resource ............................................................... 534 
Methods ........................................................................................ 535 
Mapping Order of Realized Child Widgets ...................................... 536 
Callback Lists ................................................................................ 536 
XtNu nrealizeCallback ................................................................... 536 
Internal Format of Callback Lists .................................................. 536 
New Routine to Call Callback List ................................................ 536 
Resource Lists ............................................................................... 536 
Base Offsets in Resource List ...................................................... 537 
XtProcedureArg ........................................................................... 537 
Default Resource Values ............................................................. 537 
Getting a Constraint Resource List ............................................... 537 
Converters ..................................................................................... 537 
New Xt Resource Representations .............................................. 537 
New Xt Resource Converters ....................................................... 538 
New Fn for Issuing Conversion Warnings ..................................... 538 
New Resource Converters Interface ............................................ 538 
Keyboard Handling ........................................................................ 540 
KeyCode-to-KeySym Conversions ............................................... 540 
KeySym-to-KeyCode Conversions ............................................... 540 
Selections ...................................................................................... 541 
Objects .......................................................................................... 541 
The Gadget Parent ...................................................................... 542 
Xt Functions That Take Any Object .............................................. 542 
Xt Functions That Take Any RectObj ............................................ 543 
Xt Functions That Take Any Core ................................................. 544 
Xt Functions That Take Any Composite ....................................... 544 
Xt Functions That Take Any Shell or a Subclass .......................... 544 
Macros for Getting Object Information .......................................... 545 
Miscellaneous ................................................................................ 545 
XtNameToWidget ......................................................................... 545 
New Exposure Compression Controls .......................................... 545 
Requesting Key and Button Grabs ............................................... 547 
New Macros for Widget Superclass Determination ....................... 547 
Macros and Procedure Equivalents .............................................. 547 
Finding File Names ...................................................................... 548 
Improved Multi-Display Support in Xmu ....................................... 548 



D 
Release Notes 

The Xt specification is the definition of the X Consortium standard for Xt. This appendix 
describes the changes to the Xt Intdnsics specification between Release 3 and Release 4. 
This appendix separates them according to whether they affect just application writers, just 
widget writers, or both, so that you can read the sections appropriate to your needs. 
In the majority of cases, Xt applications correctly written for Release 3 will be source com- 
patible with Release 4. However, there have been many additions to Xt that you may wish to 
use when converting an application or widget to R4 or writing one from scratch. This is a 
fairly complete summary of the additions and changes that have been made to the Intdnsics 
since Release 3. 
Some of the information provided below describes behavior that is not new but that is newly 
documented in R4--behavior that was in the R3 implementation of Xt (and still present in 
R4) but was not in the R3 Xt specification. These places are noted. 

D.1 

Summary of New Functions and Procedure Types 

XtApprnitiali ze is the new function to be used for initializing Xt applications. 

XtAppSetFallbackResources allows you to provide a set of backup resources that 
will be used in case the app-defaults file is not installed. An argument in XtApp- 
Initialize is provided for this purpose, so XtAppSetFallbackResources is 
rarely needed. 

The llowing Unctions are the new varargs vsions ofexisting Unctions: XtVaSet- 
Values, XtVaGetValues, XtVaCreateWidget, XtVaCreateManaged- 
Widget, XtVaAppCreateShell, XtVaGetSubresources, XtVaGet- 
ApplicationResources, XtVaCreatePopupShell, XtVaSetSubvalues, 
XtVaGetSubvalues, andXtVaAppInitialize. 

Xt Initiali zeWidgetClas s initializes a widget or object class without creating any 
widget or object. This is normally done in order to make available the type converters regis- 
tered by that class before the first instance of that class is created, so that resources for the 
first instance can be set while creating it using XtVaTypedArg, a new feature of Xt- 
VaSetValues and XtVaCreateWidget. 

Appendix D: Release Notes 521 



XtGetActionKeysym is used within an action routine to get the keysym that invoked the 
action. This is useful because the event passed to the action contains only the keycode. 
XtGetKeysymTable and XtKeysymToKeycodeList are two more functions for 
controlling the mapping of keycodes to keysyms. These functions are rarely needed. 
XtRegisterGrabAction allows you to write an action that when invoked will automat- 
ically result in a global grab of the pointer or key that invoked the action. Internally in Xt 
this is used to register XtMenuPopup, so it is rarely needed. 
XtLastTimestampProcessed is useful in selection processing, since some events that 
trigger selections do not include a timestamp. XtGetSelectionRequest is used in the 
convert__proc in selections to get the time from the selection request event 
XtDisplayOfObject, XtScreenOfObject, and XtWindowOfObject are the 
equivalents of XtDisplay, XtScreen, and XtWindow that work for objects, which are 
the windowless and sometimes geometryless forms of widgets. XtIsObject is a macro 
that lets you distinguish an object from a widget 
XtDisplayToApplicationContext is sometimes useful in applications that open 
connections to more than one display. 
XtName converts a widget ID to a widget name, the opposite of XtNameToWidget. 
XtSetWMColormapWindows sets the value of the WM_COLORMAP_WINIX)WS prop- 
erty on a widget's window. This is done in order to tell the window manager that windows in 
this application other than the top-level window need special colormaps installed. 
Release 4 introduces a set of new selection interfaces which allow the owner and requestor to 
handle the selection in arbitrary chunks. This is called an incremental transfer, to differenti- 
ate it from the existing interfaces that implement an atomic transfer. The protocols for both 
are very similar, but the procedures written by the owner and requestor to convert and receive 
data may be called multiple times in an incremental transfer, instead of just once as in the 
atomic transfer. The new functions and procedure types are: xtCancelConvert- 
SelectionProc, XtCancelSelectionCallbackP roc, XtConvert- 
SelectionIncrProc, XtLoseSelectionIncrP roc, XtSelectionDone- 
IncrProc, Xt SelectionIncrCallbackProc, XtGetSelectionValue- 
Incremental, XtGet SelectionValues Increment al, and XtOwn- 
SelectionIncremental. See Chapter 11, lnterclient Communications, for a descrip- 
tion of how these functions and procedure types are used. 
XtGetApplicationNameAndClass allows an application to get its own resource 
name and class. This function is rarely needed. 
Xt implements its handling of the language string using XtResolvePathname, which 
calls XtFindFile. These two functions are provided for applications that need to search 
the file system for files. XtResolvePathname searches using X/Open language localiza- 
tion conventions, while XtFindFile searches arbitrary paths. 

Appendix D: Release Notes 523 



D.3.1.4 Registering Button and Key Grabs For Actions 

D.3.1.5 

XtRegisterGrabAction registers a grab that will be initiated when the given action is 
invoked in response to KeyPress or ButtonPress events. This function is used inter- 
nally by Xt to register the grab for the XtMenuPopup action. 

Action Functions and Unrealized Widgets 

Action procedures may not assume that the widget in which they are invoked is realized; an 
accelerator specification can cause an action procedure to be called for a widget which does 
not yet have a window. Widget writers should note which of a widget's callback lists are 
invoked from action procedures and warn clients not to assume the widget is realized in those 
callbacks. (This is newly documented but also true of R3.) 

D.3.2 Reserved Names for Resources and Actions 

Resource names beginning with the two-character sequence "xt" and resource classes begin- 
ning with the two-character sequence "Xt" are reserved to the Intfinsics for implementation- 
dependent uses. Consequently, all symbols beginning with XtNxt and xtcxt are reserved. 
The Intrinsics reserve all action names and parameters starting with the characters "Xt" for 
future standard enhancements. Users, application and widgets should not declare action 
names or pass parameters starting with these characters except to invoke specified built-in 
functions. 
In general, applications should not declare or define anything beginning with Xt in any case, 
since these are generally associated with the Xt standard and could conflict or be confusing. 

D.3.3 

Resource String Identifier Convention 

Definitions of XtN, XtC, and XtR constants should have just a single space between the 
symbol and the value, and no comment. This prevents preprocessor warnings from multiple, 
slightly different definitions for the same symbol. 

D.3.4 

Resource File Format 

As of R4, the resource file format is defined in the Xlib specification instead of by Xt, and the 
following was added: To include arbitrary octets in a string, use the 4-character sequence 
"knnn" where nnn is the numeric value of the octet specified as an octal constant. For 
example, a value containing a NULL byte may be stored by including "\000" in the string. 
This is one way to specify ISO-Latinl strings that are above the 128 ASC1/characters--these 
strings are needed for Western languages other than English. 

528 X Toolkit Intrinsics Programming Manual, Motif Edition 



If extension fields exist, as is the case with the Composite, Constraint, and Shell classes, sub- 
classes can provide values for these fields by setting the extension pointer in their class struc- 
ture to point to a statically declared extension record containing the values. Setting the 
extension field is never mandatory; code that uses fields in the extension record must always 
check the extension field and do some appropriate default action if it is NULL. 
In order to permit multiple subclasses and libraries to chain extension records from a single 
extension field, extension records should be declared as a linked list and each extension 
record definition should contain the following four fields at the beginning of the structure 
declaration: 
struct { 
XtPointer next extension; 
-- 
XrmQuark record_type; 
long version; 
Cardinal record size; 
-- 
1; 

next extension 
-- 

record_type 

version 

record size 

Specifies the next record in the list, or NULL. 
Specifies the particular structure declaration to which each 
extension record instance conforms. The record_type 
field identifies the contents of the extension record and is used 
by the allocator of the record to locate its particular extension 
record in the list. record_type is normally assigned the 
result of XrmStringToQuark for a registered string con- 
stant. The Intrinsics reserve all record type string names 
beginning with the two characters "XT" for future uses. The 
value NULLQUARK may also be used by the class part owner in 
extension records attached to the class part extension field to 
idendfy the extension record unique to that particular class. 
Specifies a symbolic constant supplied by the person who 
defined the structure. The version field is an owner- 
assigned constant which may be used to identify binary files 
which have been compiled with alternate definitions of the 
extension record data structure. The private header file for a 
widget class should provide a symbolic constant for sub- 
classes to use to initialize this field. 
Specifies the total number of bytes allocated for the extension 
record. The record size field includes the four common 
-- 
header fields and should normally be initialized with 
sizeof (). 

532 X Toolkit Intrinsics Programming Manual, Motif Edition 



D.4.3.1 Composite Class Extension Structure 

D .4.3.2 

A Composite class extension record has been defined. The first four fields in this structure 
are described above. 
typedef struct { 
XtPointer next extension; 
-- 
XrmQuark record_type; 
long version; 
Cardinal record size; 
-- 
Boolean accepts_objects; 
} CompositeClassExtensionRec, *CompositeClassExtension; 
The version field can be initialized using the XtCompositeExtensionVersion 
symbolic constant. 
The accepts_objects field allows Xt to check to make sure that the composite parent is 
capable of managing the type of child being created. If not, a fatal error occurs. Note that a 
fatal error also occurs if no composite extension record is defined. 

Constraint Class Extension Structure 

The extension record defined for Consu'aint is as follows: 

typedef struct { 
XtPointer next extension; 
-- 
XrmQuark record_type; 
long version; 
Cardinal Kecord size; 
-- 
XtArgsProc get_values_hook; 
} ConstraintClassExtensionRec, *ConstraintClassExtension; 

The record_type should be initialized to NULLQUARK. The version field should be 
initlized to xtConst raintExtensionVe rsion. 

D.4.3.3 

New Constraint get_values_hook method 

If the Consu'aint widget or any of its superclasses have declared a ConstraintClass- 
Extension record in the constraint class part extension fields with a record type of 
NULLQUARK and the get_values_hook field in the extension record is nOn-NULL, Xt- 
GetValues calls this get_values_hook method to allow the parent to return derived 
constraint fields. The Consu'aint get_values_hook method is for processing the 
resources of subparts. 

The Consla'aint extension get_.values_hook 
get_values_ hook methods are called. 

method is called after the Core 

Appendix D: Release Notes 533 



D.4.8.1 Base Offsets In Resource List 

D.4.8.2 

XtWidgetBaseOffset has been added as an address mode which can be used in re- 
source lists. XtWidgetBaseOffset is similar to XtBaseOffset except that it 
searches for the closest windowed ancestor if the object is not a subclass of Core. 

XtProcedureArg 

In the field usually specified as XtBaseOffset, you can specify XtProcedureArg in- 
stead. This instructs Xt to call a procedure of type XtConvertArgProc tO get the re- 
source value. 

D .4.8.3 

D.4.8.4 

Default Resource Values 

The default_address field in each resource list element specifies the address of the de- 
fault resource value. As a special case, if the default_type is XtRString, then the 
value in the default_addr field is the pointer to the string rather than a pointer to the 
pointer. 

Getting a Constraint Resource List 

XtGetConstraintResourceList gets the constraint resource list structure for a wid- 
get class. 

D.4.9 

D.4.9.1 

Converters 

New Xt Resource Representations 
The following resource representation types are now defined by the Intrinsics. 
Table D-3. New Representation Types 

Resource Type 

XtRBitmap 
XtRGeometry 
XtRInitialState 
XtRLongBoolean 
XtRObject 
XtRStringTable 
XtRVisual 

Structure or Field Type 

Pixmap, depth=l 
char*,rmatas definedby XParseGeometry 
int 
long 
Object 
char** 
Visual* 

<X111StringDefs.h> now defines the following resource types as a convenience for widgets, 
although they do not have any corresponding datatype assigned: XtREditMode, Xt- 
RJustify and XtROrientation. 

Appendix D: Release Notes 537 



XtConvertAndStore looks up and calls a resource converter, copying the resulting val- 
ue, and freeing a cached resource when a widget is destroyed. XtConvertAndStore 
adds XtCallbackReleaseCacheRef to the XtNdestroyCallback list of the 
specified widget if the conversion returns an XtCacheRef value. 
By default, XtCreateWidget performs processing equivalent to XtConvertAnd- 
Store when initializing a widget instance. Because there is extra memory overhead re- 
quired to implement reference counting, clients may distinguish those widgets which are nev- 
er destroyed before the application exits from those which may be destroyed and whose re- 
sources should be deallocated. To specify whether or not reference counting is to be enabled 
for the resources of a particular widget when the widget is created, the client can specify a 
value for the Boolean resource XtNinitialResourcesPersistent, class Xt- 
CInitialResourcesPersistent. 
%Vhen XtCreateWidget is called, XtNinitialResourcesPersistent must be 
set to False in either the arg list or the resource database for the resources referenced by 
this widget to be reference counted, regardless of how the type converter may have been reg- 
istered. The effective default value is True. Only clients which expect to destroy one or 
more widgets and want resources deallocated should specify False for XtNinitial- 
ResourcesPersistent. 
Even if XtNinitialResourcesPersistent is True, resources are still freed and 
desuctors called when XtCloseDisplay is called if the conversion was regisred as 
XtCacheByDi splay. 

D.4.10 

D.4.10.1 

D.4.10.2 

Keyboard Handling 

KeyCode-to-KeySym Conversions 

The Intrinsics maintain tables internally to map keycodes to keysyms for each open display. 
Translator procedures and any other client may share a single copy of this table to perform 
the same mapping. 

XtGetKeysymTable returns a pointer to the keycode to keysym mapping table for a par- 
ticular display. 

KeySym-to-KeyCode Conversions 

XtKeysymToKeycodeList returns the list of keycodes that map to a particular keysym 
in the keyboard mapping table maintained by the Intrinsics. 

540 X Toolkit Intrinsics Programming Manual, Motif Edition 



D.4.12.4 

Xt Functions That Take Any Core 
The Widget arguments to the following procedures must bc of class Core or any subclass: 

XtAddEventHandler 
XtAddGrab 

XtAddRawEventHandler 
XtAugmentTranslations 
XtBuildEventMask 
XtCallAcceptFocus 
XtCallActionProc 
XtCreatePopupShell 
XtCreateWindow 
XtDisownSelection 
XtDisplay 
XtGetSelectionRequest 
XtGetSelectionValue 
XtGetSelectionValueIncremental 
XtGetSelectionValues 
XtGetSelectionValuesIncremental 
XtGrabButton 
XtGrabKey 
XtGrabKeyboard 
XtGrabPointer 
XtInsertEventHandler 
XtInsertRawEventHandler 
XtWindow 

XtInstallAccelerators 
XtInstallAllAccelerators (bo 
destination and source) 
XtMapWidget 
XtOverrideTranslations 
XtOwnSelection 
XtRealizeWidget 
XtRemoveEventHandler 
XtRemoveGrab 
XtRemoveRawEventHandler 
XtResizeWindow 
XtScreen 
XtSetKeyboardFocus (subtree) 
XtSetMappedWhenManaged 
XtSetWMColormapWindows 
XtUngrabButton 
XtUngrabKey 
XtUngrabKeyboard 
XtUngrabPointer 
XtUninstallTranslations 
XtUnmapWidget 
XtUnrealizeWidget 
XtVaCreatePopupShell 

The retum vMue ofthe llowg procedure will beofclass Core or a subclass: Xt- 
WindowToWidget. 

D.4.12.5 Xt Functions That Take Any Composite 
The Widget arguments to the following procedures must bc of class Composite or any sub- 
class: XtCreateManagedWidget, XtVaCreateManagedWidget. 

D.4.12.6 

Xt Functions That Take Any Shell or a Subclass 

The WidgetClass arguments D the llowing procedures must be of class Shell or a sub- 
class: XtCreatePopupShell, XtVaCreatePopupShell, XtAppCreateShell. 
The Widget arguments D the llowing procedures must be of a subclass of Shell: 
XtCallbackExclusiv XtPopdown 
XtllbackNone XtPopup 
XCallbackNonexclusive XtPopupSpringLoaded 
XtCallbackPopdown 

544 X Toolkit Intrinsics Programming Manual, Motif Edition 



D.4.13.3 Requesting Key and Button Grabs 

Xt now provides a set of key and button grab interfaces that are parallel to those provided by 
Xlib. Toolkit applications and widgets that need to passively grab keys or buttons should use 
the following Intrinsics routines rather than the corresponding Xlib routines. 
The new Xt routines arc: XtGrabKey, XtUngrabKey, XtGrabKeyboard, Xt- 
UngrabKeyboard, XtGrabButton, XtUngrabButton, XtGrabPointer, and 
XtUngrabPointer. 
Remember that these routines are interfaces to Xlib grab routines: they are not the same as 
the Xt grab mode which affects only the dispatching of events within your application. 
To affect dispatching of events outside of your application, in R3 you needed to make a Xlib 
call to grab the pointer, or use MenuPopup, the standard action that made the grab for you 
(which is now also called XtHenuPopup). Given the new R4 grab routines, you can pop 
up a menu using any of the popup mechanisms (xtPopup, XtPopupSpringLoaded, 
XtCallbackExclusive, XtCallbackNonexclusive, or XtCallbackNone) 
and still get the desired grab by calling XtGrabButton, or by using XtRegister- 
GrabAction. 

D.4.13.4 

D.4.13.5 

New Macros for Widget Superclass Determination 

To test if a given widget is a subclass of an Intrinsics-defined class, the Intdnsics define mac- 
ros or functions equivalent to XtIsSubclass (which existed in R3) for each of the built- 
in classes. These procedures are: XtIsObject, XtIsRectObj, XtIsWidget, Xt- 
IsComposite, XtIsConstraint, XtIsShell, XtIsOverrideShell, Xt- 
IsWMShell, XtIsVendorShell, XtIsTransientShell, XtIsTopLevel- 
Shell, and xt IsApplicationShell. 

All of these macros and functions have just one argument, the object. These procedures may 
be faster than calling xtI sSubclaaa directly for the built-in classes. 

Macros and Procedure Equivalents 

Any Xt function may be implemented as both a macro and a procedure. Any such macro will 
expand to code that evaluates each of its arguments exactly once, fully protected by paren- 
theses, so that arbitrary expressions may be used as arguments. Applications may use #un- 
de f to remove a macro definition and ensure that the actual function is referenced. 

XtNew, XtNumber, XtOffsetOf, XtOffset, and XtSetArg are macros which do 
not have function equivalents, and may expand their arguments in a manner other than that 
described above. Therefore, their arguments cannot contain arbitrary expressions. Argu- 
ments for these macros should not include expressions that increment a variable, because an 
argument might be referenced twice. 

Appendix D: Release Notes 547 



D.4.13.6 Finding File Names 

D.4.13.7 

The Intrinsics provide procedures to look for a file by name using string substitutions in a list 
of file specifications. There are two routines provided; X:'ind'i:te and X:Reao:tve- 
Pathname. XtFindFile uses an arbitrary set of client-specified substitutions and Xt- 
ResolvePathname uses a set of standard substitutions corresponding to the X/Open Por- 
tability Guide language localization conventions, and is used by Xt's language localization 
support. 

Improved Multi-display Support in Xmu 

Multi-display programs should now be able to use the Xmu type converters. Xmu also pro- 
vides utilities for managing the multiple display data structures. 

548 X Toolkit Intrinsics Programming Manual, Motif Edition 



E 

The xbitmap Application 

This appendix shows the complete code for the BitmapEdit widget and a rel- 
atively complex version of xbitmap, which is described in Chapter 4, An 
Example Application. 

In This Appendix: 

The BitmapEdit Widget ...................................................................... 551 
The BitmapEdiP.h Private Header File ............................................... 564 
The BitmapEdit.h Public Header File .................................................. 566 
xbitmap5 ............................................................................................ 567 



Example E- 1. BitmapEdit: complete widget code (continued) 

#define offset(field) XtOffsetOf(BitmapEditRec, field) 

static XtResource resources[] = { 
/* not needed in Motif - already defined by Primitive. 
* { 
* XtNforeground, 
* XtCForeground, 
* XtRPixel, 
* sizeof(Pixel), 
* offset(bitmapEdit.foreground), 
* XtRString, 
* XtDefaultForeground 
* }, 
*/ 

{ 
XtNtoggleCallback, 
XtCToggleCallback, 
XtRCallback, 
sizeof(XtPointer), 
offset(bitmapEdit.callback), 
XtRCallback, 
NULL 
}, 
{ 
XtNcellSizeInPixels, 
XtCCellSizeInPixels, 
XtRInt, sizeof(int), 
offset(bitmapEdit.cell size in pixels), 
-- 
XtRImmediate, 
(XtPointer)DEFAULT CELL SIZE 
_ _ 
}, 
{ 
XtNpixmapWidthInCells, 
XtCPixmapWidthInCells, 
XtRDimension, 
sizeof(Dimension), 
offset(bitmapEdit.pixmap_width in cells), 
XtRImmediate, 
(XtPointer)DEFAULT PIXMAP WIDTH 
-- -- 
}, 
{ 
XtNpixmapHeightInCells, 
XtCPixmapHeightInCells, 
XtRDimension, 
sizeof(Dimension), 
offset(bitmapEdit.pixmap_height in cells), 
XtRImmediate, 
(XtPointer)DEFAULT PIXMAP HEIGHT 
_ -- 
}, 
{ 
XtNcurX, 
XtCCurX, 
XtRInt, 
sizeof(int), 
offset(bitmapEdit.cur x), 
-- 
XtRImmediate, 

552 X Toolkit Intrinsics Programming Manual, Motif Edition 



:" Examp E- 1. BitmapEdit: compte widget code (continued) 
-!:: (XtPointer) 0 
XtNcur7, 
XtCCur, 
XtRInt, 
iiii sizeof (int) , 
offset(bitmapEdit.cur_y), 
:::::::: i 
!!!iiii! X t ms t r i ng, 
"'iiiiii 
(XtPointer) NULL 
}, 
{ 
 XtNcellArray, 
iiiii! XtCCel iArray, 
XtRSt ring, 
sizeof (St ring) , 
offset (bitmapEdit. cell) , 
XtRImmediate, 
(XtPointer) 0 
}, 
{ 
XtNshowEntireBitmap, 
XtCShowEntireBitmap, 
XtRBoolean, 
sizeof(Boolean), 
offset(bitmapEdit.show all), 
XtRImmediate, 
(XtPointer) True 
}, 
}; 
/* Declaration of methods */ 
: static void Initialize(); 
: static void Redisplay(); 
static void Destroy(); 
static void Resize(); 
static Boolean SetValues(); 
static XtGeometryResult QueryGeometry(); 
/* these Core methods not needed by BitmapEdit: 
* 
* static void ClassInitialize(); 
* static void Realize(); 
*/ 
/* the following are private functions unique to BitmapEdit */ 
static void DrawPixmaps(), DoCell(), ChangeCellSize(); 
/* the following are actions of BitmapEdit */ 
static void DrawCell(), UndrawCell(), ToggleCell(); 
/* The following are public functions of BitmapEdit, declared extern 
* in the public include file: */ 
char *BitmapEditGetArray(); 
static char defaultTranslations[] = 
"<BtnlDown>: DrawCell() \n\ 
<Btn2Down>: UndrawCell() \n\ 

Appendix E: The xbitmap Application 553 



 Example E-1. BitmapEdit: complete widget code (continued) 

<Btn3Down> : ToggleCell () \n\ 
--<. <BtnlMotion> : DrawCell () \n\ 
<Btn2Motion> : UndrawCell () \n\ 
<Btn3Motion> : ToggleCell () "; 

static XtActionsRec actions[] = { 
{"DrawCell", DrawCell}, 
{"UndrawCell", UndrawCell}, 
{"ToggleCell", ToggleCell}, 
}; 

/* definition in BitmapEdit.h */ 
static BitmapEditPointInfo info; 

BitmapEditClassRec bitmapEditClassRec = { 

{ 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
/* 
}, 
{ 
/* 
/* 
/* 
/* 
/* 
/* 

class inited 
initialize 
initialize hook 
realize 
actions 
num actions 
resources 
hum resources 
xrm class 
compress_motion 
compress_exposure 

core class fields */ 
-- 
superclass */ (WidgetClass) &xmPrimitiveClassRec, 
class name */ "BitmapEdit", 
-- 
widget_size */ sizeof(BitmapEditRec), 
class initialize */ NULL, 
-- 
class_part_initialize */ NULL, 
*/ False, 
*/ Initialize, 
*/ NULL, 
*/ XtInheritRealize, 
*/ actions, 
*/ XtNumber(actions), 
*/ resources, 
*/ XtNumber(resources), 
*/ NULLQUARK, 
*/ True, 
*/ XtExposeCompressMultiple, 
compress_enterleave */ True, 

visible interest */ False, 
-- 
destroy */ Destroy, 
resize */ Resize, 
expose */ Redisplay, 
set values */ SetValues, 
-- 
set values hook */ NULL, 
-- _ 
set_values_almost */ XtInheritSetValuesAlmost, 
get_values_hook */ NULL, 
accept_focus */ NULL, 
version */ XtVersion, 
callback_prlvate */ NULL, 
tm_table */ defaultTranslations, 
query_geometry */ QueryGeometry, 
display_accelerator */ XtInheritDisplayAccelerator, 
extension */ NULL 

/* Primitive class fields */ 
border_highlight */ XtInherit, 
border_unhighlight */ XtInherit, 
translations */ XtInheritTranslations, 
arm_and_activate */ NULL, 
syn resources */ NULL, 
num_syn_resources */ 0, 

554 X Toolkit Intrinsics Programming Manual, Motif Edition 



::i:-..-%i Example E-1. BitmapEdit: complete widget code (continued) 
....... 
::. /* ARCSUSED */ 
 static void 
ii Initialize(treq, tnew, args, num_args) 
"::::::::i'-:".: 
i::i::::::iiiiiii Hidget Lreq, Lnew; 
 ArqList arqs; 
:::.::::-...-. 
.!i:::.-ii BitmapF..ditHidget new = (BitmapF.ditHidget) Lnew; 
new->bitmapdit.cur x = O; 
new->bitmap..dit, cur_y = O; 
/* 

::::::::: 
..:.:.:.: 

XtGCMask mask = GCForeground I GCBackground; 
values.foreground = cw->primitive.foreground; 
values.background = cw->core.background_pixel; 
cw->bitmapEdit.copy_gc = XtGetGC(cw, mask, &values); 

* Check instance values set by resources that may be invalid. 
*/ 
if ((new->bitmapEdit.pixmap_width in cells < I) 
(new->bitmapEdit.pixmap_height_in_cells < I)) { 
XtWarning("BitmapEdit: pixmapWidth and/or pixmapHeight is took 
small (using I0 x I0)."); 
new->bitmapEdit.pixmap_width in cells = I0; 
new->bltmapEdit.pixmap_height in cells = I0; 
} 
if (new->bitmapEdit.cell size in pixels < 5) { 
-- 
XtWarning("BitmapEdit: cellSize is too small (using 5)."); 
new->bitmapEdit.cell size in pixels = 5; 
-- 
} 
if ((new->bitmapEdit.cur_x < 0) I I (new->bitmapEdit.cur_y < 0)) 
XtWarning("BitmapEdit: cur_x and cur_y must be non-negative\ 
(using 0, 0)."); 
new->bitmapEdit.cur x = 0; 
new->bitmapEdit.cur_y = 0; 
} 
if (new->bitmapEdit.cell == NULL) 
new->bitmapEdit.cell = XtCalloc( 
new->bitmapEdit.pixmap_width in cells * 
new->bitmapEdit.pixmap_height in cells, sizeof(char)); 
else 
new->bitmapEdit.user_allocated = True;/* user supplied cell array */ 
new->bitmapEdit.pixmap_width_in_pixels = 
new->bitmapEdit.pixmap_width in cells * 
new->bitmapEdit.cell_size in pixels; 
new->bitmapEdit.pixmap_height_in_pixels = 
new->bitmapEdit.pixmap_height in cells * 
new->bitmapEdit.cell_size_in_pixels; 
/* 
* Motif Primitive sets width and height to provide enough room for 

556 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example E- 1. BitmapEdit: complete widget code (continued) 
else { /* called because complete redraw */ 
x = 0; 
y = 0; 
width = cw->bltmapEdit.pixmap_width in pixels; 
height = cw->bitmapEdit.pixmap_height in pixels; 
} 

:::-;::::::::: 
....... 
.............. 
::::%:::::::: 

i ) 

if (DefaultDepthOfScreen(XtScreen(cw)) == I) 
XCopyArea(XtDisplay(cw), cw->bitmapEdit.blg_picture, 
XtWindow(cw), cw->bitmapEdit.copy_gc, x + 
cw->bitmapEdit.cur_x, y + cw->bitmapEdit.cur_y, 
width, height, x, y); 
else 
XCopyPlane(XtDisplay(cw), cw->bitmapEdit.big_picture, 
XtWindow(cw), cw->bitmapEdit.copy_gc, x + 
cw->bitmapEdit.cur x, y + cw->bitmapEdit.cur_y, 
-- 
width, height, x, y, I); 

/* ARGSUSED */ 
::::::::: .... static Boolean 
:.:::.::::::::i:: SetValues (current, request, new, args, num_args) 
Widget current, request, new; 
ArgList args; 
Cardinal *num_args; 
{ 
BitmapEditWidget curcw = (BitmapEditWidget) current; 
BitmapEditWidget newcw = (BitmapEditWidget) new; 
Boolean do_redisplay = False; 
if (curcw->primitive.foreground != newcw->primitive.foreground) { 
XtReleaseGC(curcw, curcw->bitmapEdit.copy_gc) ; 
GetCopyGC (newcw) ; 
do_redisplay = True; 
} 
if ((curcw->bitmapEdit.cur x != newcw->bitmapEdit.cur x) 
(curcw->bitmapEdit.cur_y != newcw->bitmapEdit.cur_y)) 
do_redisplay = True; 
if (curcw->bitmapEdit.cell size in pixels != 
newcw->bitmapEdit.cell size in pixels) { 
ChangeCellSize(curcw, newcw->bitmapEdit.cell size in pixels) ; 
do_redisplay = True; 
} 
if (curcw->bitmapEdit.pixmap_width in cells != 
newcw->bit mapEdit, pixmap_wdt_in cells) 
newcw->bitmapEdit.pixmap_width in cels = 
-::: .... cu rcw->bit mapEdit, pixmap_width_in_cel i s; 
iiiiiiiiiiiiii XtWarning("BitmapEdit: pixmap_width in cells cannot be set\ 
by XtSetValues. \n") ; 
.:.:.:.:. 
::::::::::-: __ -  
::i!-iil if (curcw->bitmapEdit.pixmap height in cells 
iiiiiiiiill newcw->bitmapEdit.pixmap_height in cells) 
:.iiiiiii:.:.i newcw->bitmapEdit.pixmap_height in cells = 
curcw->bitmapEdit.pixmap_height in cells; 

558 X Toolkit Intrinsics Programming Manual Motif Edition 



Example E- 1. BitmapEdit: complete widget code (continued) 

/* This is strictly correct, but doesn't 
* seem to be necessary */ 
if (event->type == ButtonPress) { 
newx = (cw->bitmapEdit.cur x + ((XButtonEvent *)event)->x) / 
cw->bitmapEdit.cell size in plxels; 
newy = (cw->bitmapEdit.cur_y + ((XButtonEvent *)event)->y) / 
cw->bitmapEdit.cell size in pixels; 
} 
else { 
newx = (cw->bitmapEdit.cur x + ((XMotionEvent *)event)->x) / 
cw->bitmapEdit.cell size in pixels; 
newy = (cw->bitmapEdit.cur_y + ((XMotionEvent *)event)->y) / 
cw->bitmapEdit.cell size in pixels; 
} 

if ((mode = cw->bitmapEdit.cell[newx + newy * 
cw->bitmapEdit.pixmap_width in cells]) == DRAWN) { 
gc = cw->bitmapEdit.undraw_gc; 
mode = UNDRAW; 
} 
else { 
gc = cw->bitmapEdit.draw_gc; 
mode = DRAW; 
} 

if (oldx != newx II oldy != newy) { 
oldx = newx; 
oldy = newy; 
DrawPixmaps(gc, mode, cw, event); 
} 

static void 
DrawPixmaps(gc, mode, w, event) 
GC gc; 
int mode; 
Widget w; 
XButtonEvent *event; 
{ 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int newx = (cw->bitmapEdit.cur x + event->x) / 
cw->bitmapEdit.cell size in pixels; 
int newy = (cw->bitmapEdit.cur_y + event->y) / 
cw->bitmapEdit.cell size in pixels; 
XExposeEvent fake event; 
/* if already done, return */ 
if (cw->bitmapEdit.cell[newx + newy * 
cw->bitmapEdit.pixmap_width in cells] == mode) 
return; 

/* otherwise, draw or undraw */ 
XFillRectangle(XtDisplay(cw), cw->bitmapEdit.big_picture, gc, 
cw->bitmapEdit.cell_size in pixels*newx + 2, 
cw->bitmapEdit.cell_size in pixels*newy + 2, 
(unsigned int)cw->bitmapEdit.cell size in pixels - 3, 
-- 
(unsigned int)cw->bitmapEdit.cell size in pixels - 3); 

560 X Toolkit Intrinsics Programming Manual, Motif Edition 



Example E- 1. BitmapEdit: complete widget code (continued) 

cw->bitmapEdit.cell[newx + newy * 
cw->bitmapEdit.pixmap_width in cells] = mode; 
info.mode = mode; 
info.newx = newx; 
info.newy = newy; 
fake_event.x = cw->bitmapEdit.cell_size_in_pixels * newx - 
cw->bitmapEdit.cur_x; 
fake_event.y = cw->bitmapEdit.cell_size_in_pixels * newy - 
cw->bitmapEdit.cur_y; 
fake_event.width = cw->bitmapEdit.cell_size_in_pixels; 
fake_event.height = cw->bitmapEdit.cell size in pixels; 
Redisplay(cw, &fake_event); 
XtCallCallbacks(cw, XtNtoggleCallback, &info); 
) 
CreateBigPixmap(w) 
Widget w; 
( 
BitmapEditWidget cw = (BitmapEditWidget) w; 
/* always a 1 bit deep pixmap, regardless of screen depth */ 
cw->bitmapEdit.big_picture = XCreatePixmap(XtDisplay(cw), 
RootWindow(XtDisplay(cw), DefaultScreen(XtDisplay(cw))), 
cw->bitmapEdit.pixmap_width_in_pixels + 2, 
cw->bitmapEdit.pixmap_height in pixels + 2, 1); 
} 
DrawIntoBigPixmap(w) 
Widget w; 
( 
BitmapEditWidget cw = (BitmapEditWidget) w; 
int n_horiz_segments, n_vert_segments; 
XSegment segment[MAXLINES]; 
register int x, y; 
XFillRectangle(XtDisplay(cw), cw->bitmapEdit.big_picture, 
cw->bitmapEdit.undraw_gc, 0, 0, 
cw->bitmapEdit.pixmap_width in pixels 
+ 2, cw->bitmapEdit.pixmap_height in .pixels + 2); 
n_horiz_segments = cw->bitmapEdit.pixmap_height in cells + 1; 
n_vert_segments = cw->bitmapEdit.pixmap_width_in_cells + 1; 
for (x = 0; x < n_horiz_segments; x++) [ 
segment[x].xl = 0; 
segment[x].x2 = (short) cw->bitmapEdit.pixmap_width_in_pixels; 
segment[x].yl = (short) cw->bitmapEdit.cell size in pixels * x; 
segment[x].y2 = (short) cw->bitmapEdit.cell_size_in_pixels * x; 
XDrawSegments(XtDisplay(cw), cw->bitmapEdit.big_picture, 
cw->bitmapEdit.draw_gc, segment, n_horiz_segments); 
for [y = 0; y < n_vert_segments; y++) [ 
segment[y].xl = (short) y * cw->bitmapEdit.cell size in pixels; 
segment[y].x2 = (short) y * cw->bitmapEdit.cell size in pixels; 
-- 
segment[y].yl = 0; 
segment[y].y2 = (short) cw->bitmapEdit.pixmap_height in pixels; 

Appendix E: The xbitmap Application 561 



:::::::::: 
iili ....... Widget w; 
'iiiil XtWidgetGeometry *proposed, *answer; 
iiiiiiiiii!i!i BitmapEditWidget cw = (BitmapEditWidget)w; 
iiiiii /* set fields we care about */ 
iii!i!iii!ii:i answer->request_mode = CWWidth I CWHeight; 
.............. 
:.:.:.:.:.:.:. 
:::::::::::::: 
!i::::i!!! :: /* initial width and height */ 
if (cw->bitmapEdit.show all == True) 
::.:.: answer->width = cw->bitmapEdit.pixmap_width in pixels; 
answer->width = (cw->bitmapEdit.pixmap_width in pixels > 
: DEFAULTWIDTH) ? DEFAULTWIDTH : 
cw->bitmapEdit.pixmap_width in pixels; 
if (cw->bitmapEdit.show all == True) 
answer->height = cw->bitmapEdit.pixmap_height in pixels; 
else 
answer->height = (cw->bitmapEdit.pixmap_height in pixels > 
DEFAULTWIDTH) ? DEFAULTWIDTH : 
cw->bitmapEdit.pixmap_height in pixels; 
if ( ((proposed->request_mode & (CWWidth  CWHeight)) 
-- (CWWidth I CWHeight)) && 
proposed->width == answer->width && 
proposed->height == answer->height) 
return XtGeometryYes; 
else if (answer->width == cw->core.width && 
answer->height == cw->core.height) 
return XtGeometryNo; 
else 
return XtGeometryAlmost; 

E.2 The BitmapEdiP.h Private Header File 

Examp E-2. BitmapEdiP.h: comppriva headerfile 
/, 
* BitmapEditP.h - Private definitions for BitmapEdit widget 
*/ 

#ifndef _ORABitmapEditP_h 
#define _ORABitmapEditP_h 
/* 
* Include private header file of superclass. 
* In this case, however, Primitive's header file is 
* thrown into XmP.h. 

564 X Toolkit Intrinsics Programming Manual, Motif Edition 



Examp E-2. BitmapEdiP.h: comp pfiva header file (continued) 
./ 
#include <Xm/XmP.h> 
/* 
* Include public header file for this widget. 
*/ 
#include "BitmapEdit.h" 
/* New fields for the BitmapEdit widget class record */ 
typedef struct { 
int make_compiler_happy; /* keep compiler happy */ 
} BitmapEditClassPart; 
/* Full class record declaration */ 
typedef struct _BitmapEditClassRec { 
CoreClassPart core_class; 
XmPrimitiveClassPart primitive_class; 
BitmapEditClassPart bitmapEdit_class; 
} BitmapEditClassRec; 
extern BitmapEditClassRec bitmapEditClassRec; 
/* New fields for the BitmapEdit widget record */ 
typedef struct { 
/* resources */ 
Pixel foreground; 
XtCallbackList callback;/* application installed callback function(s) */ 
Dimension pixmap_width in cells; 
Dimension pixmap_height in cells; 
int cell_size in pixels; 
int cur_x, cur_y; /* position of visible corner in big pixmap */ 
char *cell; /* array for keeping track of array of bits */ 
Boolean show_all; /* whether bitmap should display entire bitmap */ 
/* private state */ 
Dimension pixmap_width in pixels; 
Dimension pixmap_height_in_pixels; 
Pixmap big_picture; 
GC draw_gc; /* one plane, for drawing into pixmap */ 
GC undraw_gc; /* one plane, for drawing into pixmap */ 
GC copy_gc; /* defaultdepthofscreen, for copy'g pixmap into window */ 
Boolean user_allocated; /* whether user allocated cell array */ 
} BitmapEditPart; 
/* 
* Full instance record declaration 
*/ 
typedef struct _BitmapEditRec { 
CorePart core; 
XmPrimitivePart primitive; 
BitmapEditPart bitmapEdit; 
} BitmapEditRec; 
#endif /* _ORABitmapEditP_h */ 

Appendix E: The xbitmap Application 565 



E.4 xbitmap5 

Examp E-4. xb#map5: comp applation code 
/. 
* xbitmap5.c 
*/ 
#include <Xm/Xm.h> 

#include <Xm/PanedW.h> 
#include <Xm/RowColumn.h> 
#include <Xm/PushB.h> 
#include <Xm/DrawingA.h> 
#include <Xm/ScrolledW.h> 

#include "BitmapEdit.h" 

#include <stdio. h> 
#define DRAWN 1 
#define UNDRAWN 0 

/* 
* Data structure for private data. 
* (This avoids lots of global variables.) 
*/ 
typedef struct { 
GC draw_gc, undraw_gc, invert_gc; 
Pixmap normal_bitmap; 
Widget showNormalBitmap, showReverseBitmap; 
Dimension pixmap_width in cells, pixmap_height_in_cells; 
} PrivateAppData; 

static void CellToggled(), SetUpThings(); 

PrivateAppData private_data; 
String filename; /* filename to read and write */ 
static Boolean file_contained_good_data = False; 

/* ARGSUSED */ 
static void 
PrintOut(widget, client_data, call_data) 
Widget widget; 
XtPointer client_data, call_data; /* unused */ 
{ 
XWriteBitmapFile(XtDisplay(widget), filename, 
private_data.normal_bitmap, 
private_data.pixmap_width in cells, 
private_data.pixmap_height in cells, 0, 0); 
} 

/*ARGSUSED*/ 
static void 
!iiiiiii RedrawSmallPicture(w, event, params, num_params) 
Widget w; 
XEvent *event; 
String *params; 
.. 
Cardinal *num_params; 
{ 
... GC gc; 

Appendix E: The xbitmap App/ication 567 



Example E-4. xbitmap5: complete application code (continued) 
{"-cellsize", "*cellSizeInPixels", 
}; 

XrmoptionSepArg, NULL}, 

topLevel = XtVaAppInitialize( 
&app_context, /* Application context */ 
"XBitmap5", /* Application class */ 
table, XtNumber(table), /* command line option list */ 
&argc, argv, 
NULL, 
NULL); 

/* command line args */ 
/* for missing app-defaults file */ 
/* terminate varargs list */ 

if (argv[l] != NULL) 
filename = argv[l]; 
else { 
fprintf(stderr, Wxbitmap: must specify filename on command line.\n"); 
exit (i) ; 
} 

form = XtCreateManagedWidget("form", xmPanedWindowWidgetClass, topLevel, 
NULL, 0); 

buttonbox = XtCreateManagedWidget("buttonbox", xmRowColumnWidgetClass, 
form, NULL, 0); 

output = XtCreateManagedWidget("output", xmPushButtonWidgetClass, 
buttonbox, NULL, 0); 

XtAddCallback(output, XmNactivateCallback, PrintOut, NULL); 

quit = XtCreateManagedWidget("quit", xmPushButtonWidgetClass, 
buttonbox, NULL, 0); 

XtAddCallback(quit, XmNactivateCallback, exit, NULL); 

switch (XReadBitmapFile(XtDisplay(quit), 
RootWindowOfScreen(XtScreen(quit)), filename, 
&width, &height, &private_data.normal_bitmap, &junk, &junk)) { 
case BitmapSuccess: 
file_contained_good_data = True; 
if ((private_data.pixmap_width in cells != width)  I 
(private_data.pixmap_height in cells != height)) { 
i = 0; 
XtSetArg(args[i], XtNpixmapWidthInCells, width); i++; 
XtSetArg(args[i], XtNpixmapHeightInCells, height); i++; 
private_data.pixmap_width in cells = width; 
private_data.pixmap_height in cells = height; 
cell = FillCell(quit); 
XtSetArg(args[i], XtNcellArray, cell); i++; 
} 
break; 
case BitmapOpenFailed: 
fprintf(stderr, "xbitmap: could not open bitmap\ 
file, using fresh bitmap.\n"); 
break; 
case BitmapFileInvalid: 
fprintf(stderr, "xbitmap: bitmap file invalid.\n"); 
exit(l); 
case BitmapNoMemory: 
fprintf(stderr, "xbitmap: insufficient server memory\ 

Appendix E: The xbitmap Application 569 



Example -4. xbitm5 complete oplioation code (continued) 

to create bitmap.\n"); 
exit (I) ; 
default : 
fprintf(stderr, "xbitmap: programming error.\n"); 
exit (I) ; 

scrolledW = XtVaCreateManagedWidget("scrolledW", 
xmScrolledWindowWidgetClass, form, NULL, 0); 
/* args are set above if file was read */ 
bigBitmap = XtCreateManagedWidget("bigBitmap", 
bitmapEditWidgetClass, scrolledW, args, i); 
XtAddCallback(bigBitmap, XtNtoggleCallback, CellToggled, NULL); 
if (!file_contained_good_data) { 
XtVaGetValues(bigBitmap, 
XtNpixmapHeightInCells, &private_data.pixmap_height in cells, 
XtNpixmapWidthInCells, &private_data.pixmap_width in cells, 
NULL); 
private_data.normal_bitmap = XCreatePixmap(XtDisplay(quit), 
RootWindowOfScreen(XtScreen(quit)), 
private_data.pixmap width in_cells, 
private_data.pixmapheigh in cells, I); 
} 
SetUpThings(topLevel); 
private_data.showNormalBitmap = XtVaCreateManagedWidget( 
"showNormalBitmap", xmDrawingAreaWidgetClass, 
buttonbox, XmNwidth, private_data.pixmap_width in cells, 
XmNheight, private_data.pixmap_height in cells, 
NULL); 
private_data.showReverseBitmap = XtVaCreateManagedWidget( 
"showReverseBitmap", xmDrawingAreaWidgetClass, 
buttonbox, XmNwidth, private_data.pixmap_width in cells, 
XmNheight, private_data.pixmap_height in cells, 
NULL); 
XtAddCallback(private_data.showReverseBitmap, 
XmNexposeCallback, CellToggled, NULL); 
XtAddCallback(private_data.showNormalBitmap, 
XmNexposeCallback, CellToggled, NULL); 
XtRealizeWidget(topLevel); 
XtAppMainLoop(app_context); 
} 
static void 
SetUpThings(w) 
Widget w; 
{ 
XGCValues values; 
values.foreground = I; 
values.background = 0; 
/* note that normal_bitmap is used as the drawable because it 

570 X Toolkit Intrinsics Programming Manual, Motif Edition 



F 

Sources of Additional Information 

This appendix describes where you can get more information about the X 
Toolkit and about X in general including other books on the subject and the 
various ways to get the source code for X. 

In This Appendix: 

Getting the X Software ....................................................................... 575 
Bug Fixes ...................................................................................... 576 
Notes ........................................................................................... 578 
Fairness ...................................................................................... 578 
Netnews ............................................................................................ 579 
Training and Consulting ..................................................................... 579 
Phone Support ............................................................................... 580 
The X Consortium .............................................................................. 580 
Finding Out for Yourself ..................................................................... 581 



F 
Sources of Additional Information 

This appendix lists a few of the official and unofficial sources for information about the X 
Window System and associated software. 
Note that some of this detailed information may become dated rather quickly. The best 
source of current information is the comp.windows.x network news group, described later in 
this appendix. 
This book documents Release 4, the current public release level of the X software as of June 
1990. Even so, many people continue to use R3 since there is a considerable delay between 
the date that MIT distributes a new release and the date by which vendors integrate that 
release into their own products and issue updates. An R3 version of this manual is available 
while demand is sufficient to continue reprinting. (All changes to Xt in R4 are backwards 
compatible so that any software that runs under R3 will also run under R4. But the converse 
is not true.) 

F.1 

Getting the X Software 

You can get the X software directly from MIT on three 9-track 1600 BPI magtapes written in 
UNIX tar format or on one 9-track 6250 BPI magtape, along with printed copies of MIT's 
manuals, by sending a check in U.S. currency for U.S. $400 to: 
MIT Software Distribution Center 
Technology Licensing Office 
MIT E32-300 
77 Massachusetts Avenue 
Cambridge, MA 02139 
Their telephone number is (617) 253-6966, and the "X Ordering Hotline" is (617) 258-8330. 
If you want the tapes and manuals shipped overseas, the price is $500. The manual set alone 
is $125 including U.S. shipping or $175 including overseas shipping. 
Other distribution media or formats are not available from the MIT Software Distribution 
Center, but are from other independent vendors such as ICS, mentioned later. The Release 
tape comes with source code for sample servers for Sun, HP, IBM, Apollo, Sony, DEC and 
several other workstations, source code for clients written by MIT, sources for the toolkits 

Appendix F: Sources of Additional Information 575 



Xt, XView (in R4), Interviews, and Andrew, contributed software written outside MIT 
(including the examples in this book), and sources and postscript files for all MIT's documen- 
tation. Note that the servers supplied are sample servers only; commercial vendors typically 
release optimized (faster) servers for the same machines. 

Sites that have access to the Internet can retrieve the distribution from the following 

machines using anonynousftp. Here are the current sites: 

Location 

Western USA 
Central USA 
Central USA 
Southeast USA 
Northeast USA 
UK Janet 
UK niftp 
Australia 

Hostname 

gatekeeper.dec.corn 
mordred.cs.purdue.edu 
giza.cis.ohio-state.edu 
uunet.uu.net 
crl.dec.com 
src.doc.ic.ac.uk 
uk.ac.ic.doc.src 
munnari.oz.au 

Address 

16.1.0.2 
128.10.2.2 
128.146.8.61 
192.48.96.2 
192.58.206.2 
129.31.81.36 

128.250.1.21 

Directory 

pubIXlllR4 or R3 
pubIXlllR4 or R3 
pubIXlllR4 or R3 
XIR4 
publX111R4 
X.V11R4 
<XV11R4>* 
X.V111R4 

DO NOT do anonymous ftp during normal business hours, and please use the machine 
nearest you. 
The distribution is also available by UUCP from UUNET, for sites without Internet access. 
The files are split up to be small enough for UUCP distribution. See the preface for instruc- 
tions on getting files from UUNET if you are not a UUNET subscriber. 

F.1.1 

Bug Fixes 

Critical bug fixes as well as a limited number of important new features are available from 
the archive server xstuff@expo.lcs.mit.edu. Electronic mail sent to this address is forwarded 
to a program which responds with the requested information. The rest of this section and the 
two that follow it (entitled Notes and Fairness) explain how to use xstuff. 
The xstuff server is a mail-response program. This means that you mail it a request, and it 
mails back the response. 
The xstuffserver is a very dumb program. It does not have much error checking. If you don't 
send it commands that it understands, it will just answer "I don't understand you." 
The xstuff server reads your entire message before it does anything, so you can have several 
different commands in a single message. It treats the "Subject:" header line just like any 
other line of the message. You can use any combination of upper and lower case letters in 
the commands. 
The archives are organized into a series of directories and subdirectories. Each directory has 
an index, and each subdirectory has an index. The top-level index gives you an overview of 
what is in the subdirectories, and the index for each subdirectory tells you what it contains. 

576 X Toolkit Intrinsics Programming Manual, Motif Edition 



If you are bored with reading documentation and just want to try something, then send the 
server a message containing the line: 
send index fixes 
When you get the index back, it will contain the numbers of all of the fixes and batches of 
fixes in the archive. Then you can send the server another message asking it to send you the 
fixes that you want: 
send fixes 1 5 9 11-20 
If you are using a mailer that understands "@" notation, send to xstuff@expo.lcs.rnit.edu. If 
your mailer deals in "!" notation, try sending to {someplace}!mit- 
eddie!expo.lcs.mit.edu!xstuff. For other mailers, you're on your own. 
The server has four commands. Each command must be the first word on a line. 
help The command help or send help causes the server to send you the help file. No 
other commands are honored in a message that asks for help (the server figures that 
you had better read the hdp message before you do anything else). 
index If your message contains a line whose first word is index, then the server will send 
you the top-level index of the contents of the archive. If there are other words on 
that line that match the name of subdirectories, then the indexes for those subdirec- 
tories are sent instead of the top-level index. For example, you can say: 

index 

or: 
index .fixes 

send 

You can then send back another message to the xstuff server, using a send command 
(see below) to ask it to send you the files whose name you learned from that list. 
index ftres and send index ftres mean the same thing: you can use send instead of 
index for getting an index. 
If your message has an index or a send index command, then all other send com- 
mands will be ignored. This means that you cannot get an index and data in the 
same request. This is so that index requests can be given high priority. 
If your message contains a line whose first word is send, then the xstuff server will 
send you the item(s) named on the rest of the line. To name an item, you give its 
directory and its name. For example: 

send fixes i-i0 

Once you have named a category, you can put as many names as you like on the 
rest of the line. They will all be taken from that category. For example: 

send fixes i-i0 11-20 21-30 

Each send command can reference only one directory. If you would like to get one 
fix and one of something else, you must use two send commands. 

Appendix F: Sources of Additional Information 5ZZ 



F.1.1.1 

path 

You may put as many send commands as you like into one message to the server, 
but the more you ask for, the longer it will take to receive. See the Fairness Section 
below, for an explanation. Actually, it's not strictly true that you can put as many 
send commands as you want into one message. If the server must use UUCP mail to 
send your files, then it cannot send more than 100K bytes in one message. If you 
ask for more than it can send, then it will send as much as it can and ignore the rest. 
The path command exists to help in case you do not get responses from the server 
when you mail to it. 
Sometimes the server is unable to return mail over the incoming path. There are 
dozens of reasons why this might happen, and if you are a true wizard, you already 
know what those reasons are. If you are an apprentice wizard, you might not know 
all the reasons, but you might know a way to circumvent them. 
If you put in a path command, then everything that the server mails to you will be 
mailed to that address, rather than to the return address on your mail. The server 
host expo.lcs.mit.edu does not have a direct UUCP connection to anywhere; you 
must go through mit-eddie (the UUCP name of eddie.mit.edu) or somewhere else. 

Notes 

The xstuff server acknowledges every request by return mail. If you don't get a message 
back in a day or two you should assume that something is going wrong, and perhaps try a 
path command. 

The xstuff server does not respond to requests from users named root, system, daemon, or 
mailer. This is to prevent mail loops. If your name is "Bruce Root" or "Jane Daemon", and 
you can document this, I will happily rewrite the server to remove this restriction. Yes, I 
know about Norman Mailer and Waverley Root. Norman doesn't use netmail and Waverley 
is dead. 

F.1.1.2 

Fairness 

The xstuff server contains many safeguards to ensure that it is not monopolized by people 
asking for large amounts of data. The mailer is set up so that it will send no more than a fixed 
amount of data each day. If the work queue contains more requests than the day's quota, then 
the unsent files will not be processed until the next day. Whenever the mailer is run to send 
its day's quota, it sends the requests out shortest-first. 

If you have a request waiting in the work queue and you send in another request, the new 
request is added to the old one (thereby increasing its size) rather than being filed anew. This 
prevents you from being able to send in a large number of small requests as a way of beating 
the system. 

The reason for all of these quotas and limitations is that the delivery resources are finite, and 
there are many people who would like to make use of the archive. 

578 X Toolkit Intrinsics Programming Manual, Motif Edition 



Interactive Development Environments 
Interactive Systems Corp. 
Jupiter Systems 
Key Systems Engineering Corp. 
Landmark Graphics Corp. 
Locus Computing Corp. 
MIPS Computer Systems 
MITRE Corp. 

Tektronix, Inc. 
Texas Instruments 
UNICAD, Inc. 
Unisys Corp. 
University of Lowell 
Visual Technology, Inc. 
Wang Laboratories 
X/Open Company Ltd. 

Most of these companies are preparing products based on X. 

F.5 

Finding Out for Yourself 

If, heaven forbid, you don't find an answer to your problem in one of the books in our X Win- 
dow System Series, and you can't get anyone to help you, what do you try next? 
X is unusual in that the source code is freely available. It should be possible for most X pro- 
grammers to get a copy of the X source code from the sources listed above. There you can 
look at some examples of how others have used X to write applications. In "Star Wars," the 
saying was "Use the Force, Luke." In X, it is "Use the Source, Luke." However, you may 
find that many of the applications on the release tape use out-of-date techniques, because 
they were written before the release. 
Whenever looking at the code for the server or any of the programming libraries such as Xlib 
or Xt, however, remember that the X standards are defined by documents, not by code. In 
other words, don't depend on any of the undocumented details of the code you happen to 
have access to, since some other vendor may not implement the standard in the same way. 
Nevertheless, it can sometimes be useful to see how things are actually being done. Once 
you understand how the code is organized, you can look up certain details about how X 
works as long as you have a good knowledge of C and a little persistence. 
Xlib and the server are two distinct chunks of code. Each contains code for sending and 
receiving information to and from the other over the network using protocol requests, replies, 
events, and errors. The source tree as supplied on the X distribution tape places the Xlib 
source in the directory base/lib/X, where base is the top of the entire source tree. Their server 
source is placed in base/server. 
The procedure for finding out something about an Xlib routine is normally to search for the 
routine in the Xlib code, and then figure out what it does. Sometimes the answer can be 
found there. Many of the routines, however, simply place their arguments in a protocol 
request and send it to the server. Then you will have to look in the server code for the 
answer. To find the correct place in the server code, you will need the symbol for the proto- 
col request, which is the first argument in the Get:leq call. 
The server code is much more involved than Xlib itself. The device-dependent portions are 
in base/serverlddx and the device-independent portions are in base/server/dix. The device- 
independent code should be your first stop, because it is here that protocol requests from Xlib 
arrive and are dispatched to the appropriate code. Search for the protocol request symbol 

Appendix F: Sources of Additional Information 581 



you found in Xlib. It will appear in several source files. Start with the occurrence in 
dispatch.c, and try to figure out what the code does. This will require following leads to 
other routines. 

If you don't find a routine in baselserver/dix, then it must be in the device-dependent code. 
baselserverlddx has one directory in it for each brand of hardware to which a sample server 
has been ported. It also contains the directories/mi,/cfb,/mfb, and/snf, which contain rou- 
tines used in writing the sample server device-dependent code. Note that servers may 
include code ostensibly for other machines. 

582 X Too&# Intrinsics Programming Manual, Motif Edition 



Glossary 

X uses many common terms in unique ways. A good example is "children." 
While most, if not all, of these terms are defined where they are first used in 
this manual, you will undoubtedly find it easier to refresh your memory by 
looking for them here. 



Glossary 

This glossary is an expanded version of the glossary from Volume One, Xlib Programming 
Manual (which in turn is based on the glossary in the Xlib-C Language X Interface, by Jim 
Gettys, Ron Newman, and Bob Scheifler). As such, it contains definitions of many Xlib terms 
not actually used in this book, but which you might come across in other reading, or in com- 
ments in code. In some cases, these Xlib terms may be used in the definitions of the Xt terms 
given in this glossary. Any term used in a definition, for which another entry exists in the 
glossary, is generally shown in italics. 
accelerator 
An accelerator is a translation that maps events in one widget to actions in an- 
other. The name is based on the most frequent use for this feature, namely to pro- 
vide keyboard shortcuts to invoke application or widget functions that would other- 
wise have only a pointer-driven interface. 
accept_focus method 
The accept_focus method of a child is invoked when a parent offers the keyboard 
focus to a child by calling xt:cal.l.Accept:'ocus. This method is part of the 
Core widget class. 
access control list 
X maintains lists of hosts that are allowed access to each server controlling a dis- 
play. By default, only the local host may use the display, plus any hosts specified 
in the access control list for that display. This access control list can be changed 
by clients on the local hosL Some server implementations may implement other 
authorization mechanisms in addition to or instead of this one. The list can cur- 
rently be found in letclX#.hosts where # is the number of the display, usually 0 
(zero). The access control list is also known as the host access list. 
action An action is a function bound by a translation, to be invoked in response to a user 
event. 
actions table 
An actions table is an array of function pointers and corresponding strings by 
which actions can be referenced in a translation table. The use of actions requires 
a widget to define both an actions table and a translation table. 

Glossary 585 



active grab 
A grab is active when the pointer or keyboard is actually owned by a single grab- 
bing client. See also grab. 

ancestor 

If window W is an inferior of window A, then A is an ancestor of W. The parent 
window, the parent's parent window, and so on are all ancestors of the given win- 
dow. The root window is the ancestor of all windows on a given screen. 
application context 
An application context specifies a connection to a server. When an application 
program has connections to multiple servers, the application context coordinates 
events and their dispatching, so all connections get processed. 
argument list 
An argument list is used in a call to create a widget in order to "hardcode" the val- 
ue of widget resources, and also in calls to XtSetValues or XtGetValues. It 
consists of an array of Arg structures, each consisting of a resource name and the 
value to which it should be set. 
Athena widget 
MIT distributes a set of widgets developed by MIT's Project Athena in the Athena 
Widget library, Xaw. The include files for Athena widgets reside in 
lusrlincludelXll under Release 3 and usrlincludelXlllXaw under Release 4. 
atom An atom is a unique numeric ID corresponding to a string name. Atoms are used to 
identify properties, types, and selections in order to avoid the overhead of passing 
arbitrary-length strings over the network. See also property. 
background 
Windows may have a background, consisting of either a solid color or a tile pat- 
tern. If a window has a background, it will be repainted automatically by the 
server whenever there is an v.xpose event on the window. If a window does not 
have a background, it will be transparent. By default, a window has a background. 
See also foreground. 
backing store 
When a server maintains the contents of a window, the off-screen saved pixels are 
known as a backing store. This feature is not available on all servers. Even when 
available, the server will not maintain a backing store, unless told to do so with a 
window attribute. Use the DoesBackingStores Xlib macro to determine if 
this feature is supported. 

586 X Too&# Intrinsics Programming Manual, Motif Edition 



Composite widget 
A Composite widget is designed to manage the geometry of children; that is, a 
Composite widget instance can be passed in the parent argument to XtCreate- 
Widget. 
connection 
The communication path between the server and the client is known as a 
connection. A client usually (but not necessarily) has only one connection to the 
server over which requests and events are sent. 
Constraint widget 
The Constraint widget is a subclass of Composite. A Constraint widget has more 
information about each child than a Composite widget. 
constraints 
A Constraint widget provides a list of resources, or constraints, for its children. 
The constraints give the Constraint widget information about how each child 
should be layed out. 
containment 
A window contains the pointer if the window is viewable and if the hotspot of the 
cursor is within a visible region of the window or a visible region of one of its infe- 
riors. The border of the window is included as part of the window for containment. 
The pointer is in a window if the window contains the pointer but no inferior con- 
tains the pointer. 
coordinate system 
The coordinate system has x horizontal and y vertical, with the origin (0, 0) at the 
upper-left. Coordinates are discrete, and in terms of pixels. Each window and pix- 
map has its own coordinate system. For a window, the origin is inside the border, if 
there is one. The position of a child window is measured from the origin of the par- 
ent to the outside comer of the child (not the child's origin). 
Core widget 
The Core widget is the basic class in the Toolkit. All widgets that can be displayed 
are subclasses of Core. 
cursor A cursor is the visible shape of the pointer on a screen. It consists of a hotspot, a 
shape bitmap, a mask bitmap, and a pair of pixel values. The cursor defined for a 
window controls the visible appearance of the pointer when the pointer is in that 
window. 
delete child method 
The delete_child method is invoked on a parent after its child is deleted. This 
method is part of the Composite widget and is usually inherited. 
depth The depth of a window or pixmap is the number of bits per pixel. 
dereference 
To access the contents of a pointer, you must dereference it. 

Glossary 589 



quark A quark is an integer ID that identifies a string. In the context of Xt, this string is 
usually a name, class, or type string for the resource manager. Like atoms and re- 
source IDs, quarks eliminate the need to pass strings of arbitrary length over the 
network. The quark type is XrmQuark, and the types XrmName, XrmClass, 
and XrmRepresentation are also defined to be XrmQuark. 
query geometry method 
Parents call XtQueryGeomet ry to invoke the child's query geometry method to 
f'md out a child's preferred geometry. This method is pan of the Core widget class. 
raise Changing the stacking order of a window so as to occlude all sibling windows is to 
raise that window. 
real estate 
The window management style characterized by the input being sent to whichever 
window the pointer is in is called real-estate-driven. This is the most common 
style of input management used in X. 
realize method 
The realize method creates a window on the display and is pan of the Core widget 
class. 
rectangle 
A rectangle specified by [x,y,w,h] has an (infinitely thin) outline path with cor- 
ners at Ix,y], [x+w,y], [x+w,y+h], and [x,y+h]. When a rectangle is filled, 
the lower-right edges are not drawn. For example, if w=h=0, nothing would be 
drawn when drawing the rectangle, but a single pixel when filling it. For w=h=l, a 
single pixel would be drawn when drawing the rectangle, four pixels when filling 
it. 
redirect Window managers (or other clients) may wish to enforce window layout policy in 
various ways. When a client attempts to change the size or position of a window, 
or to map one, the operation may be redirected to the window manager, rather than 
actually being performed. Then the window manager (or other client that redirect- 
ed the input) is expected to decide whether to allow, modify, or deny the requested 
operation before making the call itself. See also window manager. 
reparenting 
The window manager often reparents the top-level windows of each application in 
order to add a title bar and perhaps resize boxes. In other words, a window with a 
title bar is inserted between the root window and each top-level window. See also 
save-set. 

598 X Toolkit Intrinsics Programming Manual, Motif Edition 



XYPixmap 
The data for an image is said to be in XYPixmap format if it is organized as a set of 
bitmaps representing individual bit planes. This applies only to the server's inter- 
nal data format for images. It does not affect normal programming with pixmaps. 

ZPixmap 
The data for an image is said to be in ZPixmap format if it is organized as a set of 
pixel values in scan line order. This applies only to the server's internal data for- 
mat for images. It does not affect normal programming with pixmaps. 

zoomed window 
Some applications have not only a normal size for their top-level window and an 
icon, but also a zoomed window size. This could be used in a painting program 
(similar to the MacPaint fat bits). The zoomed window size preferences can be 
specified in the window manager hints. 

604 X Toolkit Intrinsics Programming Manual Motif Edition 



Master Index 

The master index provides a thorough, combined index to Volume Four 
(Motif Edition) and Volume Five, making it easy to look up all appropriate ref- 
erences to a topic in either volume. Note, however, that Volume Five's mas- 
ter index is based on the Athena version of Volume Four (the generic edition) 
instead of the Motif edition of Volume Four (this book). As a result, you 
should use the master index in this volume when you want to look up Motif- 
specific information. 

You will find main entries in boldface type. Page numbers are marked with a 
volume number.to indicate which book the pages refer to. Page numbers 
preceded by a "IV" refer to Volume Four, X Toolkit Intrinsics Programming 
Manual, Motif Edition. Those that are preceded by a "V" refer to Volume 
Five, X Toolkit Intrinsics Reference Manual. 



Master Index 

!, (see modifiers) 
# directive, (see translations) 

accelerators, about, IV:56, 199, 239, 257-264, 
311,585 
adding, IV:258 
and mnemonics, IV:263-264 
and translations; conflicts with, IV:261; 
translation table limitations, IV:259 
compiling accelerator table, V:274 
defining default table in code, IV:262 
event propagation, IV:259 
for gadgets, IV:440 
for menus, IV:435,440 
installing, IV:257; V:222-224; 
in multiple widgets, IV:261 
not usable in gadgets, IV:443 
(see also XtInstaIIAccelerators.) 
accept_focus method, IV:461; V:387 
accepts_objects field, IV:451 
access control list, IV:585 
action hooks, IV:464 
actions, IV:129, 133,421,426, 451,466 
about, IV:31, 34, 44-45, 44, 585; V:637 
action proc format, IV: 132 
actions table; about, IV:585; 
XtActionProc, V:374-375 
adding to widget, IV:131 
contrasted with callbacks, IV:133 
def'med in widget implementation file, 
IV:194-196 
gadget parent example, IV:450-451 
in gadgets, IV:443 
naming conventions, IV:48 

new functions for, IV:527-528 
registering with Translation Manager, V:63-64 
using event data, IV:276 
vs. methods, IV:33 
widget instance pointer, IV:236 
widget/application conflicts, IV: 195 
(see also XtAddActions; XtAppAddActions; 
XtMenuPopdown; XtMenuPopup.) 
actions table, adding, IV: 131; V:63-64, 81-82 
declaring/registering with Resource Manager, 
V:81-82 
example, IV:131 
format, IV:131 
(see also actions.) 
active grab, IV:420 
address mode, XtAddress constant, IV:320 
XtBaseOffset constant, IV:320 
Xtlmmediate constant, IV:320 
XtProcedureArg constant, IV:321 
XtResourceQuark constant, IV:321 
XtResourceString constant, IV:321 
XtWidgetBaseOffset constant, IV:321 
alia_sing font names, IV:511 
AlmostProc, V:439 
Air key, IV:248 
(see also modifiers.) 
ancestor, IV:586 
anonymous ftp, IV:39 
app-defaults file, about, IV:37, 39, 300 
directory, IV:41 
naming conventions, IV:37, 41 
application contexts, IV:109-110 
about, IV:109, 465-469, 586 
adding display, V: 168-169 
applicationShellWidgetClass, IV:332; 
V:452-460 
creating, IV:109; V:148 

Master Index 607 



caching, old size, IV:230 
resource, IV:318 
standard atoms, IV:365 
Xmu; initializing, IV:365 
XtCacheAtl constant, V:638 
XtCacheByDisplay constant, V:638 
XtCacheNone constant, V:638 
XtCacheRefCount constant, V:638 
callbacks, V:376-377, 413 
about, IV:30, 34, 44-45, 587; V:638 
adding, IV:46-48; 
more than one, IV:91; 
to callback list, V:67-68; 
to callback resource, V:65-66 
arguments to, IV:48, 89 
as resources, IV:44 
callback list, IV:90; 
deleting method, V:296-297; 
determining status, V:213; 
executive methods, V: 133; 
popping down widget, V:128-129; 
popping up widget, V:124-127; 
XtCallbackExclusive, V: 124-125; 
XtCallbackNone, V: 126; 
XtCallbackNonexclusive, V: 127; 
XtCallbackPopdown, V: 128-129; 
XtCallCallbacks, V: 133; 
XtHasCallbacks, V:213; 
XtRemoveCallback, V:296; 
XtRemoveCallbacks, V:297 
contrasted with actions, IV: 133 
format, IV:48 
naming conventions, IV:48 
passing data, IV:87-89 
procedure, V:376-377 
reasons, IV:30-31 
structure, IV:89 
XtAddCallback, V:65-66 
(see also XtCallbackProc; XtTimerCallback- 
Proc.) 
Caption widget, IV:483 
cascading popups, about, IV:413, 415, 431-436 
example, IV:432-433 
case converter, IV:251 
XtRegisterCaseConverter, V:290 
chained methods, (see inheritance) 
change_managed method, IV:374-376, 
388-389 
in constraint widgets, IV:407 

CheckBox widget, IV: 155 
CirculateNotify event, V:654 
CirculateRequest event, V:655 
class, about, IV:22, 587 
class_initialize method, IV:203, 317, 396, 451, 
470 
class_part_initialize method, IV:203, 396, 399, 
451 
extension stucture, IV:469 
hierarchy, IV: 185; 
Athena widgets, IV:203; 
gadgets, IV:443-445; 
(see also widgets.) 
name; def'med in Core class part, IV:199; 
matching widgets, IV:66 
part, IV:186; 
combining into class record, IV: 186 
record, IV: 185; 
allocating storage, IV: 189; 
BitmapEdit widget, IV: 186-187; 
contents, IV: 185 
structure, IV:185-211; 
adding resource list to, IV:194 
client, about, IV:7, 588 
client-server model, IV:7 
ClientMessage event, V:656-657 
clipboard functions, IV:369-370 
clipping region, IV:588 
color, IV:56, 125, 206-207, 312-313, 338 
determining available, IV:504 
displaying, IV:504 
false, IV:339 
hexadecimal specification, IV:502 
names, IV:501 
RGB model, IV:503 
specifying, IV:501 
colorcell, IV:504 
about, IV:588 
read-only, IV:505 
read/write, IV:505 
shared, IV:505 
(see also colormap.) 
colormap, about, IV:55, 504, 588 
installing, IV:339 
virtual, IV:338 
window attribute, IV:206, 340 
ColormapNotify event, V:658 
command, command buttons, IV:478, 480, 490; 
V:524-527 
command line; compiling, IV:39; 
options (see options) 

Master Index 609 



Command widget, IV:75, 258, 260-262, 
422-428, 431,435; V:524-527; 
creating, V:527; 
destroying, V:527; 
resources, V:524-526 
command widgets; Motif, IV:490; 
OPEN LOOK, IV:478-480 
compiling Xt, IV:39 
composite widgets, IV:475 
about, IV:lS, 373,588 
as parent and child, IV:389 
class, IV:lS, 185; 
about, IV:63; 
XtNinsertPosition resource, IV:392 
Composite widget, IV:25 
general purpose, IV:483, 494 
importance, IV:482 
initial size, IV:377 
inserting children, IV:391 
management, IV:374 
menus and control areas, IV:491 
reasons for writing, IV:373 
resources, IV:xxxiii; 
(see also resources.) 
subclass; XtIsComposite, V:226 
using within other widgets, IV:374 
writing, IV:382 
compound strings, IV: 162-169 
converting to text, IV: 169 
rendering, IV: 169 
setting, IV:104 
compound widgets, IV:409-410 
compression filters, (see events, event f'flters) 
ConfigureNotify event, V:659-660 
ConfigureRequest event, V:661-662 
connection, IV:589 
constraint widgets, IV:xxxiii, 25, 475; 
V:434-437 
about, IV:71,373, 589; V:434-437 
class, IV:185; 
part, IV:397; 
refiguring child locations, IV:401,403-404 
management, IV:392-409 
part structure, IV:395 
resources, IV:71, 73, 392, 396; V:434-437; 
example, IV:71, 73, 392 
vs. composite widgets, IV:73 
writing, IV:392 
XtIsConstraint, V:227 
(see also methods; resources.) 
consulting, IV:579 

containment, IV:589 
conventions, action function names, IV:48 
app-defaults file, IV:37, 41 
callback function names, IV:48 
font naming, IV:507 
for XtInherit constants, IV:205 
gadget internals, IV:445 
instance variables order, IV:188 
keysym naming, IV:245 
resource; class, IV:193; 
names, IV:193, 295; 
representation types, IV: 193 
widget; internals, IV: 184; 
source file names, IV: 184; 
structure declarations, IV: 189, 211 
conversion caching, IV:318 
converters, IV:311-325, 466 
color name to pixel value, IV:126, 312, 339 
Convert.h, IV:320 
explicitly invoking, IV:322 
fonmame to font, IV:312 
from int, IV:313 
from string, IV:311-316 
function pointer to callback list, IV:317 
new in R4, IV:537-540 
Pixel to XColor, IV:313 
registering, IV:293; V:69, 83-85; 
case converter, V:290 
widget name to widget ID, IV:316 
XColor to Pixel, IV:313 
(see also XtAppAddConverter; XtSetTypeCon- 
verter.) 
coordinate system, IV:5, 589 
Core widget, IV:19, 120, 185, 199, 243; 
V:438-442 
about, IV:19, 25, 54, 589 
class part; initializing, IV:197-200 
class structure; in gadgets, IV:445 
CoreClassPart structure, IV: 187 
CorePart structure, IV: 187 
drawing into from application, IV:121 
fields, IV: 199; 
compress_enterleave, IV: 199, 289; 
compress_exposure, IV: 199, 223, 289; 
compress_motion, IV:199, 289; 
display_accelerator, IV: 199; 
extension, IV:200; 
superclass, IV: 198; 
tm_table, IV: 199; 
version, IV:200; 
visible_interest, IV:199, 284; 

610 X Too&# Intrinsics Programming Manual Motif Edition 



XtGetErrorDatabase, V: 185; 
XtGetErrorDatabaseText, V:186 
levels, IV:456 
method, V:394 
procedure, V:395-396 
redefining handlers, IV:457 
string conversion warnings, IV:458 
XtAppError, V:92 
XtAppErrorMsg, V:93-94 
XtAppGetErrorDatabase, V:95 
XtAppGetErrorDatabaseText, V:96-98 
X tApplnitialize, IV: 103 
XtAppSetErrorHandler, V: 109 
XtAppSetERrorMsgHandler, V: 110 
XtError, V: 173 
XtErrorMsg, V: 174-175 
XtGetErrorDatabase, V: 185 
XtGetErrorDatabaseText, V: 186 
XtSetErrorHandler, V:314 
XtSetErrorMsgHandler. V:316 
(see also XtAppErrorMsg; XtAppSetEr- 
rorHandler; XtAppSetErrorMsgHandler; 
XtAppSetWamingHandler ; XtAppSetWar- 
ningMsgHandler; XtError; XtErrorHandler; 
XtErrorMsg; XtErrorMsgHandler; XtSetEr- 
rorHand; XtSetErrorMsgHand; XtSetWar- 
ningHandler ; XtSetWamingMsgHandler.) 
errors, fatal error procedure; calling high-level, 
V:93-94, 174-175; 
calling low-level, V:92; 
registering, V:109-110, 314 
list of, V:703 
nonfatal error procedure; calling, V: 116; 
registering, V:114-115, 331, 333 
swing conversion error message, V:335 
(see also XtAppError; XtAppErrorMsg; 
XtAppSetErrorHandler; XtAppSetEr- 
rorMsgHandler; XtAppSetWar- 
ningMsgHandler; XtAppWaming; XtError; 
XtErrorHandler; XtErrorMsg; XtEr- 
rorMsgHandler; XtSetErrorHand; XtSetEr- 
rorMsgHand; XtSetWamingMsgHandler.) 
event handlers, IV:34, 268-274 
about, IV:32, 267, 590 
adding, IV:269, 271-273; V:398 
dispatching, V: 166 
for nonmaskable events, IV:272-273 
procedure, V:397-398, 400-401 
raw, IV:274; 
registering, V:76-77; 
removing, V:302-303 

reasons to use, IV:268 
registering, V:70-71 
removing, V:298-299 
XtAddEventHandler, V:70-71 
XtAddRawEventHandler, V:76-77 
XtRemoveEventHandler, V:298-299 
XtRemoveRawEventHandler, V:302-303 
(see also XtDispatchEvent; XtEventHandler; 
XtlnputCallbackProc.) 
events, about, IV:12, 241 
accessing specific data, V:649 
as argument of action, IV: 133 
ButtonPress, IV:247, 422; V:651-653 
ButtonRelease, IV:247, 422; V:651-653 
cancelling source, V:301 
CirculateNotify, V:654 
CirculateRequest, V:655 
ClientMessage, V:656-657 
ColormapNotify, V:658 
ConfigureNotify, V:659-660 
ConfigureRequest, V:661-662 
CreateNotify, V:663-664 
DestroyNotify, V:665 
dispatching handlers, V: 166 
EnterNotify, IV:246-247, 289, 422; V:666-671 
EnterWindow, IV:269 
event compression, IV:590 
event data; example of using in an action, 
IV:275 
event filters, IV:199, 223, 289 
event loop (see main loop) 
event masks; about, IV:269, 590-591; V:632; 
window attribute, IV:206; 
XtBuildEventMask, V:120-121 
event members, V:650 
event processing, V: 107; 
XtAppProcessEvent, V: 107 
event propagation, IV:591 
event queue, IV:288 
event sequences, IV:256 
event source, IV:591 
event structure, IV:274 
event-driven programming, IV: 11-12 
Expose, IV:12, 27, 127, 138, 200, 203,284, 
289, 422; V:672-673 
Focusln, IV:246, 269, 461,591; V:674-679 
FocusOut, IV:246, 269, 461; V:674-679 
frozen, IV:592 
GraphicsExpose, IV:243, 273; V:680-681 
GravityNotify, V:682 
in action routines, IV: 138 

612 X Toolkit Intrinsics Programming Manual, Motif Edition 



functions, list of, V:617 
new in R4, IV:521-523 
widget creation, IV: 160-162 

G 

gadgets, V:424 
about, IV:66, 204, 413 
accelerators, 1V:440; 
not usable, IV:443 
actions in, IV:443 
class hierarchy, IV:443-444 
class structure, IV:445 
composite parent, IV:442, 448-451 
Core class structure, IV:445 
drawbacks of, IV:442 
event handling in, IV:443 
expose method, IV:447 
implementation file, IV:447 
instance structure, IV:446 
internals, IV:445-448 
private header file, IV:445-446 
public header file, IV:448 
query_geomelxy method, IV:447 
reason for, IV:442 
set_values_almost method, IV:447 
Sme, IV:436-448 
SmeBSB, IV:436-448 
SmeLine, IV:436-448 
superclass, IV:447 
unused Core fields in, IV:447 
(see also objects.) 
games, IV:281 
GCs, (see graphics contexts) 
geometry management, IV:67-68, 335, 374, 
379, 381,392; V:431-433 
about, IV:38, 227, 230-233,373-410, 592; 
V:641 
border width, IV:374 
changes, V:244-246 
changing (XtMakeGeomelxyRequest), IV:377; 
V:244-246 
composite resource, IV:392 
compound widgets, IV:409-410 
consaints, IV:392, 397; V:531-534 
delaying recalculation, IV:408 
height, IV:377 
initial geometry negotiation, IV:376, 379 
inserting children, IV:391 
minimal useful size, IV:386 

querying; preferred geometry, IV:389; 
XtQueryGeometry, V:284-286 
resizing, IV:373, 379; 
by application, IV:381; 
by user, IV:379; 
by widget request, IV:379-381 
scope, IV:374 
scrollable widget, V:611-613 
size preferences, IV:389 
stacking order, IV:374, 410 
a-ickle-down, IV:389 
unmanaging widget, IV:388 
widget for tiles, V:550-556 
width, IV:377 
XtMakeGeometryRequest, IV:379, 381 
XtQueryGeometry, IV:378, 381 
(see also methods; XtDestroyWidget.) 
geometry option, (-geometry), IV:99 
get_values_hook method, IV:204, 325, 533; 
V:205 
global variables, IV:87 
glyph, IV:592 
grabs, about, IV:420, 585, 592; V:641 
active vs. passive, IV:420 
adding or removing explicitly, IV:441 
exclusive vs. nonexclusive, IV:421,434 
global, IV:421 
grab modes, IV:434 
in dialog boxes, IV:441 
keyboard, IV:420 
passive, IV:421,596 
pointer, IV:420 
reasons for in menus, IV:422 
XtAddGrab, V:73-74 
XtRemoveGrab, V:300 
graphics contexts, about, 1V:124, 188,206, 592 
caching, IV:216, 219 
changing, IV:219, 226-227 
creating, IV:216, 219, 221 
deallocating, V:293 
desa'oying, V: 161 
exclusive or logical function, 1V:353 
freeing, IV:226, 233; V:161 
hardcoding values in, 1V:221 
obtaining, V:187-188 
read-only, IV:219 
reasons for, IV:124 
setting with resources, 1V:221 
(see also XtDesa'oyGC; XtGetGC; 
XtReleaseGC.) 
graphics primitive, 1V:592 

614 X Toolkit Intrinsics Programming Manual, Motif Edition 



introduction to classes, V:423-428 
selection timeout, V:112 

J 
JumpProc, V:560 

key events, (see events or translations) 
key translation, registering, V:319 
XtKeyProc, V:402-404 
XtSetKeyTranslator, V:319 
keyboard, keyboard focus, IV:337; 
about, IV:337, 461; 
accept/reject method, V:387; 
in Motif widgets, IV: 173-174; 
redirecting input, V:317-318; 
setting, IV:337; 
styles, IV:337, 594; 
(see also accept_focus; XmNinput resource; 
XtSetKeyboardFocus.) 
keyboard grabbing; (see grabs) 
keyboard shortcuts; (see accelerators) 
keycodes, about, IV:244, 462, 594 
translating; keycode-to-keysym, V:339-342; 
XtTranslateKey, V:339-340; 
XtTranslateKeycode, V:341-342 
KeymapNotify event, V:683 
KeyPress event, IV:247; V:684-686 
KeyRelease event, IV:247; V:684-686 
keysyms, about, IV:244, 462, 594 
converting case, IV:251; V:379-380 
determining case, V:147 
key generated, IV:249 
keysymdef.h header file, IV:245, 248 
naming conventions, IV:245 
XtCascProc, V:379-380 
XtConvertCase, V: 147 

Label widget, IV:25, 32, 119, 228,375,422, 
518 
about, V:538-540 
creating, V:540 
destroying, V:540 
Label.h file, IV:34 

resources, V:538-540 
labels, setting, IV:50 
LANG environment variable, IV:303 
language, portability, IV:49 
string, IV:525 
layout Form method, IV:397 
LeaveNotify event, IV:246-247, 289, 422; 
V:666-671 
LeaveWindow event, IV:269, 430, 434 
libraries, Xext, IV:13 
Xlib, IV:39 
Xm, IV:39 
Xt, IV:39 
lint, IV:48, 105 
List widget, IV:158, 269, 490 
about, V:541-545 
creating, V:543 
destroying, V:543 
resources, V:541-543 
loose bindings, IV:299, 594 

M 

macros, IV:459-460 
main loop, IV:34, 38 
customizing example, IV:288 
internals, IV:288 
XtAppMainLoop, V: 102 
XtMainLoop, V:243 
MainWindow widget, IV:74-85, 158, 378 
creation example, IV:77 
Manager widget, IV:25 
MapNotify event, V:687-688 
mapping, IV:243 
MappingNotify event, V:689-690 
MapRequest event, V:691 
about, IV:56, 594 
XtMapWidget, V:252 
XtPopdown, V:279 
XtPopup, V:280-281 
(see also MappingNotify event; widgets, map- 
ping.) 
mechanism without policy, IV:I 1,331 
memory allocation, IV:463 
for widget instance record, IV:199 
MenuButton widget, V:546-549 
creating, V:549 
destroying, V:549 
resources, V:546-547 
menus, about, IV:38, 413-451,482 

616 X Too&# Intrinsics Programming Manual, Motif Edition 



displaying list, IV:249 
for button events, IV:254 
keys, IV:247-252, 595; V:712-719 
matching exactly, IV:251 
negating, IV:250 
None, IV:251 
monochrome, IV:595 
Motif, application's look and feel, IV:488 
popup widgets, IV:496 
version 1.0 vs. 1.1, IV:413 
Motif widgets, IV:39, 68-69, 71,487-497 
about, IV:21 
command, IV:490 
DrawingArea, IV:497 
inheritance among, IV:23 
Text, IV:497 
(see also Form widget; Label widget; 
PanedWindow widget; PushButton widget; 
RowColumn widget; Scrollbar widget.) 
_MOTIF_WM_HINTS, IV:344 
_MOTIF_WM_INFO, IV:344 
_MOTIF_WM_MESSAGES, IV:343 
motion compression, IV:289 
MotionNotify event, IV:247, 269, 289, 422; 
V:692-694 
multiple, click timing, IV:253 
toplevel shells, IV:468 
mwm, interclient communication, IV:342 
keyboard focus in, IV:338 
.mwmrc file, IV:331,343 
use of input hint, IV:337 

name option (-name), IV:99 
naming conventions, for widgets, IV:517 
newlines, in translations, IV:240 
NoExpose event, V:680-681 
nonfatal error, IV:243 
registering method, V: 115 
registering procedure, V:331,333 
(see also error handling; errors.) 
nonmaskable events, (see events) 
non-widget objects, V:423 
notify method, IV:451 
notify modes, (see translations) 

objects, V:443-446 
about, IV:32, 595 
in R4, IV:541-545 
Object class, IV:444; V:423 
objectClass, V:444 
ObjectClassPart, V:443 
ObjectClassRec, V:444 
object-oriented programming, IV:xxvi, 32-33, 
273,595 
ObjectPart, V:444 
ObjectRec, V:445 
(see also gadgets.) 
obscure, IV:595 
occlude, IV:595 
OOP, (see objects, object-oriented program- 
ming) 
OPEN LOOK, application's look and feel, 
IV:477 
popup widgets, IV:485 
OPEN LOOK widgets, 1V:477-487 
command, IV:478-480 
text, IV:487 
optimization, IV: 138,230, 466 
options, abbreviating, IV:98 
argument styles, IV: 101 
-background, IV:98-99, 501 
-border, IV:99, 501 
-bordercolor, IV:99 
-borderwidth, IV:99 
command line, 1V:97; 
styles, IV:101 
custom, IV:301 
defining your own, 1V:99 
-display, IV:99 
-font, IV:99 
-foreground, IV:99, 501 
-geometry, IV:336, 512-514 
handling errors in, IV: 103 
-iconic, IV:99, 335 
options table example, IV: 101 
overriding standard, 1V:102 
-rv/+rv, IV:99 
-selecrionTimeout, 1V:99 
standard, 1V:98 
-synchronous, IV:99 
-rifle, IV:99 
-xrm, IV:98, 301 
OR operator, V:71,120, 298, 302 
OverrideShell widget, 1V:78, 334; V:447, 
452-460 

618 X Toolkit Intrinsics Programming Manual, Motif Edition 



overriding, redirect, IV:334; 
window attribute, IV:206 
standard options, IV:102 
translations, IV:135-136 

padding, IV:596 
Paned widget, about, IV:70; V:550-556 
adding pane, V:554 
child resources, V:552 
deleting pane, V:554 
destroying, V:556 
functions, V:555 
PanedWindow widget, IV:69, 158 
parent, about, IV:596 
window, IV:596 
parsing, command-line arguments, IV:99-103 
translations, IV:136 
part (vs. record), IV:186 
passive grab, IV:420 
path resources, IV:301 
pipe Input, IV:280-281 
pixel values, about, IV:125, 596 
pixmap, about, IV:56, 222, 596 
built-in, IV:170 
freeing, IV:233 
icon, IV:340 
XYPixmap format, IV:603 
ZPixmap format, IV:604 
plane, IV:596 
(see also bit, bit plane.) 
plane mask, IV:596 
pointer, IV:420 
about, IV:4, 596 
dereferencing, IV:589 
device, IV:596 
events (see events or translations) 
grabbing, IV:596 
(see also grabs.) 
popup menus, example, IV:422, 425-426 
popup widgets, IV:475 
Motif, IV:496 
OPEN LOOK, IV:485 
popups, about, IV:19, 78, 597 
cascading, IV:413 
creating, IV:79, 81; V:151-153; 
before popping up, IV:85; 
in work procedure, IV:287; V:420 
example, IV:84 

from callback function, IV:85 
linking group, IV:334 
mapping, V:280-281 
menus, IV:413 
menus, spring-loaded using Box widget, 
IV:422, 425-427 
modal, IV:416; 
about, IV:595 
modeless, IV:416; 
about, IV:595 
OverrideShell, IV:334 
sensitivity, IV:441 
spring-loaded, IV:416, 601 
unmapping, V:279 
when application is iconified, IV:334 
(see also XtCreatePopupShell.) 
portability, IV:106, 278, 446, 462, 465-466 
position, about, IV:59, 312 
hints, IV:335 
relative to root window, IV:342 
setting with resources, IV:58 
PRIMARY selection, IV:346 
Primitive widget, IV:25, 120 
PrimitiveClassPart, IV: 187 
PrimitivePart, IV: 187 
printer fonts, (see fonts) 
private header file, BitmapEdiP.h, IV: 185-189 
private Instance variables, IV: 188 
process input, XtAppMainLoop, V: 102 
program structure, IV:34 
properties, about, IV:345, 597 
and atoms, IV:354 
PropertyNotify event, V:695 
protocol, _MOTIF_WM_MESSAGES atom, 
IV:343 
network, IV:6 
WM_DELETE_WINDOW atom, IV:343 
WM_PROTOCOLS atom, IV.'343 
WM_SAVE_YOURSELF atom, IV:343 
WM_TAKE_FOCUS atom, IV:343 
Protocols.h header file, IV:342 
PseudoColor, IV:597 
public, functions, IV:114, 118, 208 
header file, IV:34, 448; 
BitmapEdit.h, IV: 184, 207-209 
instance variables (see resources) 
routines, IV:408 
pulidown menu, IV:415, 428 
creating, IV:79 
example, IV:430 
vs. spring-loaded, IV:416 

Master Index 619 



push buttons, 1V:17 
PushButton widget, 1V:17, 25, 44-48, 66, 68, 
134 
PushButtonGadget, 1V:66 
example using, 1V:118 

Q 

quarks, IV:324, 597 
query_geometry method, IV:204, 230-233,447 
about, IV:230 
example from BitmapEdit, IV:233 
gadgets, IV:408, 447 

RadioBox widget, IV: 155 
raise, IV:598 
raw event handlers, IV:274; V:76-77 
(see also events.) 
realization, IV:38, 222, 226 
realize method, IV:201,204, 206, 336, 384, 535 
RealizeProc, V:438 
reason, in callbacks. IV:30 
rectangle, IV:598 
RectObj, IV:205,443-447, 541-543; V:423, 
448-451 
redrawing windows, IV:27, 221 
regions, IV:223,449; V:72 
registering, actions (see actions) 
callbacks, V:65-68 
converters, IV:316-321; V:69, 83-85,290 
event handlers, IV:271-273; V:70-71 
fatal error handlers, IV:203,455-458; 
V:109-110, 314 
file, V:75, 86-87 
nonfatal error handlers, IV:455-458; 
V:114-115, 316, 331,333 
raw event handler, V:76-77 
work procedure, V:79, 89 
Release 4 (R4), IV:246, 413,415, 442, 469 
compared to R3, IV:521-548 
removing, callbacks, V:295-297 
grabs, V:300 
input, V:301 
raw event handlers, V:302-303 
timeouts, V:304 
reparenting, IV:342, 430, 598 
(see also window manager.) 

ReparentNotify event, V:696 
reply, IV:598 
representation types, IV:92, 94 
about, IV:293,296, 599 
new in R4, IV:537 
ResizeRequest event, V:697 
reslzing, IV:374 
about, IV:67, 215, 227-230, 373,379 
caching old size, IV:230 
resize method, IV:215, 227-230, 227, 374; 
example from BitmapEdit, IV:229; 
in gadgets, IV:450 
(see also methods, resize.) 
Resource Manager, IV:599 
RESOURCE_MANAGER property, IV:300 
(see actions) 
resources, about, IV:25, 37, 39, 49, 54, 56, 
294-297, 599; V:431-432 
and set_values method, IV:225-227 
application, IV:91 
caching, IV:318 
callbacks, IV:44 
checking validity, IV:216 
classes and instances, IV:94 
comment character in files, IV:299 
constraint, IV:71,392; V:434-437 
copying; XtGetValues, V:205-206; 
XtSetValues, V:329-330 
database; about, IV:599; 
obtaining, V: 159; 
sources, IV:300 
default address; interpreting, IV:297 
default value; converting, IV:314; 
retrieving, IV:315; V:191-192; 
setting, IV:95, 314 
defined; by Core, IV:54; 
characteristics, IV:94-95; 
in widget, IV:191,193-194 
fallback, IV:304 
file format, V:709 
Form widget, IV:71,392, 394 
format of definitions, IV:298-299 
freeing compound strings, IV:53 
hardcoding; advantages, IV:43, 103, 105; 
disadvantages, IV: 104 
in instance record, IV:188 
inheritance of, IV:49, 191,193-194 
interactions between, IV:57-59; 
example, IV:58 
loading; from .Xdefaults file, IV:58; 
with xrdb, IV:58 

620 X Toolkit Intrinsics Programming Manual, Motif Edition 



loose bindings, W:299 
naming, IV:94, 295 
precedence rules, IV:307-311 
representation types, IV:92, 94, 296 
resource conversion; about, IV:94; 
in Xmu, W:312; 
method, V:408; 
registering, IV:317; 
XtConverter, V:383-386; 
XtDirectConvert, V: 164; 
(see also XtResourceDefaultProc.) 
resource list; copying, V:203-204, 325-326; 
declaring, IV:294-295; 
example, IV:93-94; 
format, W:94, 96; 
updating, V:181-183, 201-202; 
XmR, W:92 
retrieving; application resources, IV:96-97 
server resources, IV:26 
setting; about, IV:26, 599; 
defaults, IV: 171; 
for multiple widgets, IV:66; 
for widget hierarchy, IV:66; 
in application, IV:49; 
with XtSetValues, IV:51; 
XmNinput, IV:338 
size, IV:297 
sources priority, IV:30i 
specifications; about, IV:307-311,599; 
errors in, IV:42; 
format, IV:41, 43; 
merging of duplicate, IV:300-302; 
wildcards in, IV:298 
symbolic constants, IV:42, 51 
tight bindings, IV:299 
type conversion, IV:42, 311-325; 
XtConvert, V:142-143 
types table, IV:296 
use of classes, IV:295 
values; changing, IV:225; 
getting, IV:49, 54, 297-311 
XmN constants, IV:208 
XmNaccelerators (Core), IV:55 
XmNallowShellResize (Shell), IV:334 
XmNancestorSensidve (Core), IV:55 
XmNargc (Shell), IV:333-334 
XmNargv (Shell), IV:333-334 
XrnNbackground (Core), IV:55 
XmNbackgroundPixmap (Core), IV:55 
XmNbaseHeight (Shell), IV:334, 336 
XmNbaseWidth (Shell), IV:334, 336 

XmNborderColor (Core). IV:55 
XmNborderPixmap (Core), IV:55 
XmNborderWidth (Core), IV:55 
XmNclientDecoration (Shell). IV:344 
XmNcolormap (Core). IV:55 
XmNdepth (Core). IV:55 
XmNdesa'oyCallback (Core), IV:45.55 
XmNgeometry (Shell). IV:333, 335-336 
XmNheight (Core), IV:55 
XmNheightlnc (Shell), IV:334, 336 
XmNiconic (Shell), IV:333,335 
XmNiconMask (Shell), IV:334 
XmNiconName (Shell), IV:334, 340 
XmNiconPixmap (Shell). IV:334, 340 
XmNiconWindow (Shell), IV:334 
XmNiconX (Shell). IV:333, 335 
XmNiconY (Shell), IV:333, 335 
XmNinitialState (Shell), IV:334 
XmNinput (Shell), IV:337-338 
XmNmappedWhenManaged (Core). IV:55 
XmNmaxAspectX (Shell), IV:334, 336 
XmNmaxAspectY (Shell), IV:334, 336 
XmNmaxHeight (Shell), IV:334, 336 
XmNmaxWidth (Shell), IV:334, 336 
XmNminAspectX (Shell), IV:334, 336 
XmNminAspectY (Shell), IV:334, 336 
XmNminHeight (Shell). IV:334, 336 
XmNminWidth (Shell), IV:334. 336 
XmNoverrideRedirect (Shell), IV:333-334 
XmNsaveUnder (Shell), IV:334 
XmNscreen (Core), IV:55 
XmNsensitive (Core), IV:55 
XmNtifle (Shell). IV:333,340 
XmNtransient (Shell). IV:333-334 
XmNtranslations (Core), IV:55, 133, 137 
XmNwaitForWm (Shell). IV:333, 335 
XmNwidth (Core), IV:55 
XmNwidthlnc (Shell), IV:334. 336 
XmNwindowGroup (Shell), IV:333-334 
XmNwmTimeout (Shell), IV:333, 335 
XmNx (Core), IV:55 
XmNy (Core), IV:55 
xnlLanguage, IV:302 
XtNdefaultDistance (Form), IV:393 
XtNhodzDistance (Constrain0, IV:393 
XtNinsertPosition (Composite), IV:392 
XtNmappedWhenManaged (Core), IV:388 
XtNpopdownCallback (Shell), IV:428 
XtNpopupCallback (Shell), IV:428, 430 
XtNverfl)istance (ConstrainO, IV:393 
reverse option (-rv/+rv), IV:99 

Master Inclex 621 



ShellClassPart, V:454-456 
ShellPart, V:457-459 
types, V:453; 
XtIsShell, V:234 
sibling, IV:601 
Simple widgets, IV:474 
SimpleMenu widget, IV:436-440, 448-451; 
V:563-568 
single-line input field, IV:344 
sink, in Athena Text widget, IV:325 
size, IV:373 
hints, IV:335-336 
preferences, IV:389 
sizeof, IV: 199 
Sine, IV:436-448; V:569-570 
SmeBSB, V:571-573 
SmeLine, V:575 
software architecture, IV:9 
source, compatibility, IV:469 
files for widget, IV:184 
in Athena Text widget, IV:325 
obtaining source code, IV:39 
spring-loaded menu, IV:420-427, 601 
vs. pulldown, IV:416 
(see also popups.) 
stacking order, IV:374, 410, 601 
standard colormaps, X.mu utilities, IV:339 
StaticColor, IV:602 
StaticGray, IV:602 
status, IV:602 
stdio.h file, IV:190 
stipple, IV:602 
storage, allocating; XtMalloc, V:248; 
XtNew, V:260 
freeing (XtFree), V: 178 
resizing (XtRealloc), V:289 
strings, copying (XtNewSuSng), V:261 
error message (XtStringConversionWarning), 
V:335 
setting, IV:50 
su'ing to bitmap converter, IV:316 
StringDefs.h header file, IV:34, 51, 94, 190, 
316; V:721 
Su-ingToWidget resource converter, IV:393 
StripChart widget, V:576o578 
structure, determining field's byte offset, V:264 
of Motif applications, IV:34 
(see also XtOffset.) 
subclass, IV:25 
about, IV:602 
submenus, IV:434 

cascading, IV:435 
creating, IV:432 
popping up, IV:431 
(see also XtPopup.) 
subparts, IV:199, 204, 325-327 
subresources, IV:199, 204, 325-327 
managing, IV:326-327 
Super key, IV:248 
(see also modifiers.) 
superclass, IV:198, 226 
about, IV:23, 602 
class structure, IV: 186 
gadget, IV:447 
inheritance, IV:57 
of Core, IV:443 
synchronous option, IV:99 
syntax functions, IV:103 

TCP/IP, IV:345 
Template widget, V:579-586 
Text widget, IV:154, 199, 344; V:587-604 
creating, V:599 
default bindings, V:597-598 
edit modes, V:587 
Motif, IV:497 
OPEN LOOK text widgets, IV:487 
resources, V:588-591 
TextField widget, IV: 154 
tight bindings, IV:299, 602 
tilde, IV:250 
tiling, IV:56 
about, IV:602 
time, IV:602 
timeouts, about, IV:281 
adding, IV:281 
and visibility interest, IV:284 
callback method, V:413 
example, IV:283 
invoking procedure after timeout, V:88 
removing, IV:283-284 
selection timeout value, V:99, 112 
XtAddTimeout, V:78 
XtAppAddTimeOut, V:88 
XtAppGetSelecdonTimeout, V:99 
XtAppSetSelectionTimeout, V: 112 
XtGetSelectionTimeout, V:194 
XtRemoveTimeOut, V:304 
XtSetSelecdonTimeout, V:322 

Master Index 623 



XtTimerCallbackProc, V:413 
timing, multiple clicks, IV:253 
title option (-title), IV:99 
Toggle widget, V:605-610 
ToggleButton widget, IV: 155 
toolkits, XtInitialize, V:214-218 
XtToolkitlnitialize, V:337 
top-level, TopLevelShell, V:461-462 
topLevelShellWidgetClass, IV:333; V:452-460 
widget, IV:37; 
(see also Shell widget.) 
window, IV:602 
training, IV:579 
TransientSheli, V:463-464 
transientSheilWidgetClass, IV:78, 332; 
V:452-460 
translations, IV:133-137, 259 
# augment directive, IV:135 
! modifier symbol, IV:251 
# override directive, IV:135 
# replace directive, IV:135 
about, IV:31, 44, 56, 131,134, 602 
augmenting, IV:135-136 
compiling; table, V:275-276; 
when widget class initialized, IV: 196; 
XtParseTranslationTable, V:275-276 
def'ming; default in Core class part, IV:199; 
in source, IV:137 
details in, IV:244-247 
differences between directives, IV:241 
double-clicks, IV:252 
event abbreviations, IV:242-243 
event sequences, IV:252-254 
hardcoding, IV: 136 
in widget implementation file, IV:194-196 
inheritance, IV: 195 
interactions between, IV:254-259 
keyboard events, IV:244-245 
merging, IV:255; V:268; 
widget translations, V: 119 
modifiers, IV:247-252, 249; 
and event sequences, IV:253 
Motion events, IV:253 
newlines in, IV:240 
*Notify details, IV:246 
order, IV:255 
overriding, IV:135-136; V:268 
parsing, IV:136 
removing, V:347 
replacing, IV:135, 137 
resource converters, IV:312 

syntax, IV:240 
tilde modifier symbol, IV:250 
Translation Manager (see actions) 
translation table, IV:603; V:711; 
example, IV:134 
XtAugmentTranslations, V:119 
XtUninstallTranslations, V:347 
(see also accelerators; actions.) 
translations,, modifier symbol, IV:251-252 
traversai, post-order, IV:597 
pre-order, IV:597 
TrueColor, IV:603 
type converters, IV:42 
about, IV:107 
explicitly invoking, IV:321-322; 
example, IV:322 
format, IV:323-325 
passing arguments to, IV:319; 
example, IV:319 
registering, IV:316-321 
(see also resources.) 
type property, IV:603 
typedefs, IV:189 

UIL, IV:175-179 
units of measurement, setting, IV:172 
unmanaging widget, IV:388 
UnmapNotify event, V:687-688 
upward chaining, IV:201 
user interface language, (see UIL) 
uunet, IV:39 
uwm, IV:414 

varargs interfaces, advantages and disadvan- 
tages, IV: 109 
compared to ArgList functions, IV:524 
VendorSheli widget, IV:337; V:465 
Viewport widget, IV:382; V:611-613 
virtual colormaps, IV:206, 338 
visibility interest, IV: 199, 284-285 
VisibilityNotify event, V:701-702 
visual class, IV:603 

624 X Toolkit Intrinsics Programming Manual, Motif Edition 



W 

warning handler, calling high-level, V: 117-118, 
364-365 
(see also XtAppWarningMsg; XtWarning; 
XtWarningMsg.) 
warnings, IV:455 
listing, V:703 
(see also error handling.) 
WCL toolkit aid, IV:179 
widgets, IV:63 
about, IV:10, 17, 21,603 
accept_focus method, V:122 
actions example, IV:234, 236 
adding to parent list, IV: 18; V:249-251 
as data types, IV:37 
callback list; (see callbacks) 
child widget; creating/managing, IV:63, 375; 
V:150; 
layout of, IV:386-387 
class; determining subclass (XtIsSubclass), 
V:235; 
obtaining (XtClass), V:138; 
verifying (XtCheckSubclass), V:137; 
XtIsComposite, V:226; 
XtIsConstraint, V:227; 
XtIsShell, V:234; 
. 
XtIsSubclass, V:235 
converting (R3 to R4), IV:521 
Core, V:438-442 
creating, IV:34, 91; V:154-156; 
additional top-level, V:90-91,149; 
custom widget, V:579-586, 580; 
Motif vs. Xt, IV:75; 
working window, V:157-158; 
(see also XtAppCreateShell; XtCreateAppli- 
cationShell; XtCreateMgdWidget; 
XtCreateWidget.) 
declaring class record pointer, IV:204 
default size, IV:230 
defining conventions, IV:184, 299; 
summary, IV:211 
destroying, IV:30, 233-234; V:162-163 
display pointer, V: 167 
displaying; non-editable suing, V:538-540; 
real-time graphic chart, V:576-578 
dragging attachment point, V:535-537 
Exclusives and Nonexclusives, IV:480 
framework of code, IV: 183-211 
geometry (see geometry management) 
hierarchy, IV:85; 

creating, IV:65 
implementation files, IV:184, 189-207 
include files, IV:184 
inheritance among (Motif), IV:23 
installing accelerators (see accelerators) 
instance structure, IV:216 
internals, IV: 183-211 
macros for, IV:459 
management, IV:63, 230-233; V:228; 
child, IV:216-221; 
row-column geometry, V:541-545; 
XtIsManaged, V:228; 
(see also XtManageChild; XtManageChil- 
dren.) 
mapping, IV:56; 
changing map_when_managed field, V:320; 
to display, V:252; 
windows, IV:38; 
XtSetMappedWhenManaged, V:320 
merging translations, V:119 
modal widget; XtAddGrab, V:73-74; 
XtRemoveGrab, V:300 
moving (XtMoveWidget), V:257 
moving/resizing, IV:55; V:140-141; 
XtConfigureWidget, V: 140-141 
name defined, IV:199 
naming conventions, IV:517 
parent widget (XtParent), V:273 
popping down (XtMenupopdown), V:253 
popping up, IV:80-85; V:254-255 
private header file, IV:184-189 
public functions, IV:115, 118 
public header file, IV: 184, 207-209 
realizing, IV:226; 
XtlsRealized, V:231; 
XtRealizeWidget, V:287-288 
record size, IV:199 
removing, IV: 18; V:348-349 
resizing, IV:68, 227-230, 374-383; 
by application, IV:381; 
by parent, IV:379; 
per core dimensions, V:307; 
XtMakeResizeRequest, V:247; 
XtResizeWidget, V:306; 
XtResizeWindow, V:307 
retrieving event mask, V: 120-121 
returning screen pointer (XtScreen), V:310 
routines for creating, IV: 160-162 
scrolling viewing area in another widget, 
V:557-562 
sensitivity (see sensitivity) 

Master Index 625 



XawPanedGetNumSub, V:555 
XawPanedSetMinMax, V:555 
XawPanedSetRefigureMode, V:555 
XawScrollbarSetThumb. V:561 
XawSlmpleMenuAddGlobalActions, V:567 
XawSlmpleMenuClearActlveEntry, V:567 
XawSimpleMenuGetActlveEntry, V:567 
XawTextBIock, V:601 
XawTextDisableRedisplay, V:602 
XawTextDisplay, V:602 
XawTextDisplayCaret, V:603 
XawTextEnableRedisplay, V:602 
XawTextGetInsertionPolnt, V:603 
XawTextGetSelectionPos, V:600 
XawTextGetSource, V:603 
XawTextInvalldate, V:601 
XawTextReplace, V:600 
XawTextSearch, V:601 
XawTextSetInsertionPoint, V:603 
XawTextSetSelectlon, V:599 
XawTextSetSource, V:603 
XawTextTopPosition, 
XawTextUnsetSelection, V:600 
XawToggleChangeRadioGroup, V:608 
XawToggleGetCurrent, V:609 
XawToggleSetCurrent, V:609 
XawToggleUnsetCurrent, V:609 
xbltmap application, IV: 114, 551 
xbitmapl example, IV:114-119 
xbitmap2 example, IV: 119-127 
xbitmap3 example, IV: 129-138 
xbitmap4 example, IV: 138-147 
XChangeGC Xlib function, IV:219 
XClearArea Xlib function, IV:226 
xcllpboard, IV:365,369-370 
XConfigm'eWindow Xlib function, IV:410 
XCopyArea Xlib function, IV: 127, 224, 243 
XCopyColormapAndFree Xlib function, 
IV:339 
XCopyPlane Xlib function, IV:127, 224, 243 
XCreateGC Xlib function, IV:124, 216 
XCreateWindow Xlib function, IV:207 
Xdefaults file, IV:58 
xedlt, IV:344 
XENVIRONMENT environment variable, 
IV:300 
xev, IV:249 
xfd (font displayer), IV:509 
XFlush Xlib function, IV:467 
XGCValues structure, IV:219 
XGetIconSlzes Xlib function, IV:341 

XGetImage Xlib function, IV: 170 
XGetStandardColormap Xlib function, IV:339 
xgoodbye.c example, IV:45 
xhello.c example, IV:35-36 
XInternAtom Xlib function, IV:356-357 
Xlib library, IV:39, 221,223,227 
xload, IV:337 
XLookupStrlng Xlib function, IV:462 
XLowerWlndow Xlib function, IV:410 
Xm library, IV:39 
XmAddProtocolCaliback function, IV:343 
XmAddProtocois function, IV:343 
XmCreateMenuBar function, IV:75, 77 
XmCreatePopupMenu function, IV:417 
XmCreatePulldownMenu function, IV:418 
XmDestroyPixmap function, IV:170 
xmh, IV:70-71,344 
Xm.h header file, IV:lg0 
XmInstallImage function, IV: 170 
XmInternAtom function, IV:343 
XmIsMotifWMRunning function, IV:342 
XmMainWindowSetAreas function, IV:77 
XmN constants, IV:42 
XmNcolormap, setting, IV:340 
XmNfontList resource, IV: 167 
XmNinitiaiResourcesPersistent, IV:318 
XmNinput, setting, IV:338 
XmNmultiClickTime resource, IV:253 
XmNsubMenuId resource, IV:81 
xmodmap, IV:249 
XmP.h header file, IV:lg0 
XmR resource lists, IV:92 
XmRAcceleratorTable representation type, 
IV:311 
XmRBackingStore representation type, 
IV:316 
XmRBitmap representation type, IV:316 
XmRBool representation type, IV:311 
XmRBoolean representation type, IV:311 
XmRCallback representation type, IV:317 
XmRCallProc representation type, IV:297, 
315 
XmRCursor representation type, IV:311, 31 
XmRDimension representation type, IV:311 
XmRDisplay representation type, IV:311 
XmRFile representation type, IV:311 
XmRFloat representation type, IV:312 
XmRFont representation type, IV:312 
XmRFontStruct representation type, IV:312 
XmRFunction representation type, IV:317 
XmRGeometry representation type, IV:312 

Master Index 627 



XmRlmmedlate representation type, IV:314 
XmRlnitialState representation type, IV:312 
XmRInt representation type, IV:312 
XmRJustify representation type, IV:316 
XmROrientation representation type, IV:316 
XmRPixel representation type, IV:312 
XmRPosition representation type, IV:312 
XmRShort representation type, IV:312 
XmRTranslationTable representation type, 
IV:312 
XmRUnsignedChar representation type, 
IV:312 
XmRVisual representation type, IV:312 
XmRWidget representation type, IV:316 
XmStringByteCompare function, IV: 168 
XmStringCompare function, IV: 168 
XmStringConcat function, IV: 166, 168 
XmStringCopy function, IV:168 
XmStringCreate function, IV: 166 
XmStringCreateSimple, IV:50 
XmStringCreateSimple function, IV: 163 
XmStringFree function, IV: 163 
XmStringGetLtoR function, IV: 169 
XmStringHasSubstring function, IV:168 
XmStringLength fuuction, IV: 168 
XmStringNConcat function, IV: 168 
XmStringNCopy function, IV: 168 
Xmu library, IV:318, 364 
atom caching; initializing, IV:365 
resource converters in, IV:312 
XmuConvertS tandardSelection, IV:364-366; 
V:392 
XmulnternAtom, IV:365 
XNextEvent Xlib function, IV:379 
xnlLanguage option, IV:302, 525 
XParseGeometry Xlib function, IV:336 
XPutImage Xlib function, IV: 170 
XRaiseWindow Xlib function, IV:410 
xrdb, IV:58, 297, 300 
XRectInRegion Xlib function, IV:223 
XRestackWindows Xlib function, IV:410 
Xrm, XrmOptionDescRec, V:216; 
example, IV:101; 
structure, IV:99 
XrmOptionKind argument styles, IV: 101 - 102; 
V:218 
XSelectInput Xlib function, IV:259, 269 
XSetErrorHandler Xlib function, IV:455 
XSetInputFocus Xlib function, IV:461 
XSetIOErrorHandler Xlib function, IV:455 
XSync Xlib function, IV:467 

Xt library, IV:39 
XtActionHookProc, V:373 
XtActionProc, IV:132; V:374-375 
XtAddActions, IV:451; V:63-64 
XtAddCallback, IV:47-48, 312; V:65-66 
arguments, IV:48 
XtAddCallbacks, IV:91; V:67-68 
XtAddConverter, IV:317; V:69 
XtAddEventHandler, IV:267, 269; V:70-71 
arguments, IV:271 
when to call, IV:271 
XtAddExposureToRegion, V:72 
XtAddGrab, IV:441; V:73-74 
XtAddInput, IV:466; V:75 
XtAddRawEventHandler, IV:274; V:76-77 
XtAddress address mode constant, IV:320 
XtAddressMode chum, IV:320 
XtAddTimeOut, V:78 
XtAddWorkProc, V:79 
XtAppAddActionHook, IV:464, 466; V:80 
XtAppAddActions, IV:129, 133, 194, 466; 
V:81-82 
XtAppAddConverter, IV:466; V:83-85 
XtAppAddInput, IV:278, 280, 466; V:86-87 
XtAppAddTimeOut, IV:281; V:88 
XtAppAddWorkProc, IV:286; V:89 
XtAppCreateShell, IV:332, 466, 468; V:90-91 
XtAppError, IV:456-457, 466; V:92 
XtAppErrorMsg, IV:456-457, 466; V:93-94 
XtAppGetErrorDatabase, IV:466; V:95 
XtAppGetErrorDatabaseText' IV:466; 
V:96-98 
XtAppGetSelectionTimeout, IV:466 
XtAppInitialize, IV:34, 98, 221,297, 301,466; 
V:100 
fallback resources in, IV:304 
passing options table to, IV:102 
XtAppMainLoop, IV:35, 38, 189, 284, 466; 
V:102 
and multiple application contexts, IV:467 
XtAppNextEvent, IV:288, 466-467; V:103 
XtAppPeekEvent, IV:466-467; V:104-105 
XtAppPending, IV:466-467; V:106 
XtAppProcessEvent, IV:289, 466-467; V:107 
XtAppReleaseCacheRefs, IV:466; V:108 
XtAppSelectionTimeout, V:99 
XtAppSetErrorHandler, IV:457, 466; V:109 
XtAppSetErrorMsgHandler, IV:457, 466; 
V:110 
XtAppSetFallbackResources, IV:304, 466; 
V:111 

628 X Toolkit Intrinsics Programming Manual, Motif Edition 



XtAppSetSelectionTimeout, IV:466; V:112 
XtAppSetTypeConverter, IV:466; V:113 
XtAppSetWarningHandler, IV:457, 466; 
V:l14 
XtAppSetWarningMsgHandler, IV:457, 466; 
V:l15 
XtAppTimeOut, IV:466 
XtAppWarning, IV:456-457, 466; V: 116 
XtAppWarningMsg, IV:456-457, 466; 
V:117-118 
XtAppWorkProc, IV:466 
XtArgVai, IV:106 
XtAugmentTranslations, IV: 136; V: 119 
XtBaseOffset address mode constant, IV:320 
XtBuiidEventMask, V:120-121 
XtC symbols, see also XmC, IV:428 
XtCaliAcceptFocus, IV:204, 461; V:122 
XtCallActionProc, IV:464; V:123 
XtCalibackExclusive, IV:421; V:124-125 
XtCailbackList, V:376 
XtCalibackNone, IV:421; V:126 
XtCalibackNonexclusive, IV:421; V:127 
XtCailbackPopdown, IV:421; V: 128-129 
XtCalibackProc, V:376-377 
XtCalibackRec, V:376 
format, IV:91 
XtCailbackReleaseCacheRef, V:130 
XtCalibackReleaseCacheRefList, V:131 
XtCaliCailbackList, V:132 
XtCaliCalibacks, IV:44; V:133 
XtCaiIConverter, IV:319, 322; V:134 
XtCailoc, IV:234, 463; V:136 
XtCancelConvertSelectionProc, IV:367; V:378 
XtCaseProc, V:379-380 
function prototype, IV:463 
XtCheckSubclass, V: 137 
XtCiass, V:138 
XtCioseDisplay, V: 139 
XtConfigureWidget, IV:55; V:140-141 
XtConvert, IV:321; V:142-143 
XtConvertAndStore, IV:107, 319, 321-322; 
V:144-146 
XtConvertArgProc, V:381-382 
XtConvertArgRec, IV:320 
XtConvertCase, IV:463; V:147 
XtConverter, V:383-386 
XtConvertSelectionIncrProc, IV:367; 
V:387-388 
XtConvertSelectionProc, IV:346, 354; 
V:389-392 
XtCreateApplicationContext, V: 148 

XtCreateApplicationSheli, IV:466, 468; V:149 
XtCreateManagedWidget, IV:34, 67, 77, 108, 
189, 298; V:150 
XtCreatePopupChildProc, IV:440 
XtCreatePopupSheli, IV:332; V: 151-153 
XtCreateWidget, IV:34, 189, 215,298; 
V:154-156, 436 
hardcoding resources with, IV:106 
XtCreateWindow, IV:207; V:157-158 
XtDatabase, V:159 
XtDefaultBackground, IV:311,324, 339 
XtDefauitFont constant, IV:312 
XtDefaultForeground constant, IV:311,324, 
339 
XtDestroyApplicationContext, V:160 
XtDestroyGC, V: 161 
XtDestroyWidget, IV:215,392; V: 162-163, 436 
XtDestructor, V:393 
XtDirectConvert, V: 164 
XtDisownSelection, IV:363, 368; V: 165 
XtDispatchEvent, IV:288; V: 166 
XtDisplay, IV:322; V: 167 
XtD tsplayI nitialize, V: 168-169 
XtDisplayOfObject, IV:460; V: 170 
XtDisplayStringConversionWarning, IV:324, 
458; V:171 
XtDisplayToApplicationContext, IV:468; 
V:172 
xterm, IV:336, 414 
XtError, IV:466; V:173 
XtErrorHandler, V:394 
XtErrorMsg, IV:466; V:174-175 
XtErrorMsgHandler, V:395-396 
xtetris, IV:281,283 
XtEventHandler, V:397-398 
XtFilePredicate, V:399 
XtFindFile, IV:465, 548; V:176 
XtFree, IV:234, 362, 463; V:178 
XtGeometryAImost constant, IV:232, 378, 385, 
403, 408 
XtGeometryDone constant, IV:390, 400 
XtGeometryMask, V:245, 285 
XtGeometryNo constant, IV:232, 391,401,408 
XtGeometryResult, V:245,247, 285 
XtGeometryResult enum, IV:232, 385, 
388-389, 401,403, 408 
XtGeometryYes constant, IV:232, 385,388, 
400-401,403,408 
XtGetActionKeysym, IV:463; V:179 
XtGetApplicationNameAndClass, IV:460; 
V:180 

Master Index 629 



XtParseTranslationTable, IV: 136, 196, 262; 
V:275-276 
XtPeekEvent, IV:288, 466; V:277 
XtPending, IV:288, 466; V:278 
XtPointer, IV:315,446 
XtPopdown, IV:421,426; V:279, 460 
XtPopup, IV:421,434; V:280-281,460 
XtPopupSpringLoaded, IV:421-422; V:282 
XtProc, V:438 
XtProcedureArg address mode constant, 
IV:321 
XtProcessEvent, IV:466; V:283 
XtQueryGeometry, IV:377-378, 381; 
V:284-286 
XtR symbols, see also XmR, IV:428 
XTranslateCoordinates Xlib function, IV:430 
XtRealizeWidget, IV:34, 38, 203, 376, 379, 
388; V:287-288 
XtRealloc, IV:463; V:289 
XtRegisterCaseConverter, IV:463; V:290 
XtRegisterGrabAction, IV:422; V:291-292 
XtReleaseGC, IV:226; V:293 
XtRemoveAccelerators, IV:258 
XtRemoveActionHook, IV:464; V:294 
XtRemoveActions, IV: 194 
XtRemoveAilActions, IV: 194 
XtRemoveAIICalibacks, V:295 
warning about, IV:90 
XtRemoveCaliback, IV:90-91,429; V:296 
XtRemoveCalibacks, IV:90-91; V:297 
XtRemoveEventHandler, IV:234, 273; 
V:298-299 
XtRemoveGrab, IV:441; V:300 
XtRemoveInput, IV:280; V:301 
XtRemoveRawEventHandler, IV:274; 
V:302-303 
XtRemoveTimeOut, IV:234, 283; V:304 
XtRemoveWorkProc, IV:286; V:305,419 
XtResizeWidget, IV:376, 387; V:306 
XtResizeWindow, V:307 
XtResoivePathname, IV:465, 548; V:308-309 
XtResource, IV:294 
XtResourceDefauitProc, V:408 
example, IV:315 
XtResourceList, IV:294 
XtResourceQuark address mode constant, 
IV:321 
XtResourceString address mode constant, 
IV:321 
XtRImmediate representation type, IV:297 
XtScreen, V:310 

XtScreenOfObject, IV:460; V:311 
XtSelectionCailbackProc, IV:347, 367; 
V:409-410 
XtSelectionDonelncrProc, IV:367; V:411 
XtSelectionDoneProc, IV:347; V:412 
XtSetArg, IV:52-54, 107; V:312-313 
XtSetErrorHandler, IV:466; V:314 
XtSetErrorMsgHandler, IV:466; V:316 
XtSetKeyboardFocus, IV:461; V:317-318 
XtSetKeyTranslator, V:319 
XtSetMappedWhenManaged, V:320 
XtSetMuitiCiickTime, V:321 
XtSetSelectlonTimeout, IV:368,466; V:322 
XtSetSensitive, IV:441; V:323 
XtSetSubvalues, IV:326; V:325-326 
XtSetTypeConverter, IV:317-318,320; V:327 
arguments, IV:317 
XtSetValues, IV:26, 52, 137, 203,206, 387, 406; 
V:329-330, 436 
XtSetValuesFunc, IV:226 
XtSetWarningHandler, IV:466; V:331 
XtSetWarningMsgHandler, IV:466; V:333 
XtSetWMColormapWindows, V:334 
XtSheliExtensionVersion, V:455 
XtStringConversionWarning, V:335 
XtSuperclass, V:336 
XtTimeOut, IV:466 
XtTimerCallbackProc, V:413 
XtToolkitlnitialize, V:337 
XtTranslateCoords, IV:429-430; V:338 
XtTranslateKey, IV:462; V:339-340 
XtTranslateKeycode, IV:462; V:341-342 
XtTypeConverter, V:414-418 
XtUngrabButton, IV:464; V:343 
XtUngrabKey, IV:464; V:344 
XtUngrabKeyboard, IV:464; V:345 
XtUngrabPointer, IV:420, 464; V:346 
XtUninstaliTranslations, V:347 
XtUnmanageChild, IV:388; V:348 
XtUnmanageChildren, IV:388; V:349 
XtUnmapWidget, IV:388; V:350 
XtUnrealizeWidget, V:351 
XtUnspecifiedShelllnt, V:467 
XtUnspecifiedWindow, V:468 
XtUnspecifiedWindowGroup, V:468 
XtVaAppCreateSheli, IV:468; V:352 
XtVaApplnitialize, IV:34, 36; V:353 
arguments, IV:37 
fallback resources in, IV:304 
XtVaCreateArgsList, V:354 
XtVaCreateManagedWidget, IV:34, 37, 189, 
298; V:355 

Master Index 631 



XtVaCreatePopupSheli, V:356 
XtVaCreateWidget, IV:34, 65, 188-189, 298; 
V:357 
XtVaGetApplicationResources, V:358 
XtVaGetSubresources, IV:326; V:359 
XtVaGetSubvalues, 1V:326; V:360 
XtVaGetValues, 1V:50, 185; V:361 
XtVaSetSubvalues, 1V:326; V:362 
XtVaSetValues, IV:50, 185, 188, 215-216, 
225-227; V:363 
XtVaTypedArg, used with compound su-ings, 
IV:105, 163 
XtVersion constant, 1V:200 
XtVersionDontCheck constant, IV:200 
XtWarning, 1V:466; V:364 
XtWarningMsg, IV:466; V:365 
XtWidgetBaseOffset address mode constant, 
IV:321 
XtWidgetGeometry, 1V:389-390 
XtWidgetGeometry structure, IV:230o232 
XtWidgetToApplicationContext, IV:283; 
V:366 
XtW|ndow, IV:226, 448; V:367 
XtW|ndowOfObject, IV:460; V:368 
XtWindowToW|dget, IV:460; V:369 
XtWorkProc, IV:466; V:419-420 
XWMGeometry, V:468 

632 X Toolkit Intrinsics Programming Manual, Motif Edition 



NAME 
COMPANY 
ADDRESS 
CITY 

STATE ZIP 

II 

II 

NO POSTAGE 
NECESSARYIF 
MAILEDIN THE 
UNITED STATES 

BUSINESS REPLY MAIL 

FIRST CLASS MAIL PERMIT NO. 80 SEBASTOPOL, CA 

POSTAGE WILL BE PAID BY ADDRESSEE 
O'Reilly & Associates, Inc. 
632 Petaluma Avenue 
Sebastopol, CA 95472-9902 

NAME 
COMPANY 
ADDRESS. 
CITY 

STATE ZIP 

NO POSTAGE 
NECESSARYIF 
MAILEDIN THE 
UNITED STATES 

BUSINESS REPLY MAIL 

FIRST CLASS MAIL PERMIT NO. 80 SEBASTOPOL, CA 

POSTAGE WILL BE PAID BY ADDRESSEE 
O'Reilly & Associates, Inc. 
632 Petaluma Avenue 
Sebastopol, CA 95472-9902 



Overseas Distributors 

Effective January 1, 1990, customers outside the U.S. and Canada will be able to order O'Reilly & Associates 
books through disibutors near them. These overseas locations offer international customers faster order 
processing, more local bookstores and local dislributors, and increased representation at trade shows 
worldwide, as well as the high level, quality service our customers have always received. 

AUSTRALIA & NEW ZEALAND 
(orders and inquiries) 
Addison-Wesley Publishers, Pty. Ltd. 
6 Byfield Street 
North Ryde, N.S.W. 2113 
AUSTRALIA 
Telephone: 61-2-888-2733 
FAX: 61-2-888-9404 

GREAT BRITAIN & AFRICA 
(orders and inquiries) 
Addison-Wesley Publishers Ltd. 
Finchampstead Road 
Wokingham, Berkshire RG 11 2NZ 
ENGLAND 
Telephone: 44-734-794-000 
FAX: 44-734-794-035 

EUROPE & MIDDLE EAST 
(orders and inquiries) 
Addison-Wesley Publishing Group 
Concertgebouwplein 25 
1071 LM Amsterdam 
THE NETHERLANDS 
Telephone: 31-20-671-72-96 
FAX: 31-20-664-53-34 

LATIN AMERICA (inquiries) 
Addison-Wesley Iberoamericana S.A. 
Blvd. de las Cataratas No. 3 
Colonia Jardines del Pedregal 
Delegacion Alvaro Obregon 
Mexico 01900, D. F. 
MEXICO 
Telephone: 525-660-2497 
FAX: 525-660-4930 

ASIA except JAPAN (inquiries) 
Addison-Wesley (Singapore) Pte. Ltd. 
15 Beach Road 
05-09/10 Beach Centre 
SINGAPORE 0718 
Telephone: 65-339-7503 
FAX: 65-339-9709 

LATIN AMERICA and ASIA 
except JAPAN (orders only) 
Addison-Wesley Publishing Company 
International Order Department 
Jacob Way 
Reading, MA 01867 U.S.A. 
Telephone: 1-617-944-3700 
FAX: 1-617-942-2829 

JAPAN (orders and inquiries) 
Toppan Company, Ltd. 
Ochanomizu Square B, 1-6 
Kanda Surugadai 
Chiyoda-ku, Tokyo 101 
JAPAN 
Telephone: 81-3-3295-3461 
FAX: 81-3-3293-5963 

Maruzen Company, Limited 
(X Window System Series only) 
3-10 Nihonbashi, 2-Chome 
Chuo-Ku, Tokyo, 103 
JAPAN 
Telephone: 81-3-3275-8585 
FAX: 81-3-3274-3238