Conventions Used in this Manual
1.1. Intrinsics
1.2. Languages
1.3. Procedures and Macros
1.4. Widgets
1.4.1. Core Widgets
1.4.1.1. CoreClassPart Structure
1.4.1.2. CorePart Structure
1.4.1.3. Core Resources
1.4.1.4. CorePart Default Values
1.4.2. Composite Widgets
1.4.2.1. CompositeClassPart Structure
1.4.2.2. CompositePart Structure
1.4.2.3. Composite Resources
1.4.2.4. CompositePart Default Values
1.4.3. Constraint Widgets
1.4.3.1. ConstraintClassPart Structure
1.4.3.2. ConstraintPart Structure
1.4.3.3. Constraint Resources
1.5. Implementation-Specific Types
1.6. Widget Classing
1.6.1. Widget Naming Conventions
1.6.2. Widget Subclassing in Public .h Files
1.6.3. Widget Subclassing in Private .h Files
1.6.4. Widget Subclassing in .c Files
1.6.5. Widget Class and Superclass Look Up
1.6.6. Widget Subclass Verification
1.6.7. Superclass Chaining
1.6.8. Class Initialization: class_initialize and class_part_initialize Procedures
1.6.9. Initializing a Widget Class
1.6.10. Inheritance of Superclass Operations
1.6.11. Invocation of Superclass Operations
1.6.12. Class Extension Records
2.1. Initializing the X Toolkit
2.2. Establishing the Locale
2.3. Loading the Resource Database
2.4. Parsing the Command Line
2.5. Creating Widgets
2.5.1. Creating and Merging Argument Lists
2.5.2. Creating a Widget Instance
2.5.3. Creating an Application Shell Instance
2.5.4. Convenience Procedure to Initialize an Application
2.5.5. Widget Instance Allocation: The allocate Procedure
2.5.6. Widget Instance Initialization: The initialize Procedure
2.5.7. Constraint Instance Initialization: The ConstraintClassPart initialize Procedure
2.5.8. Nonwidget Data Initialization: The initialize_hook Procedure
2.6. Realizing Widgets
2.6.1. Widget Instance Window Creation: The realize Procedure
2.6.2. Window Creation Convenience Routine
2.7. Obtaining Window Information from a Widget
2.7.1. Unrealizing Widgets
2.8. Destroying Widgets
2.8.1. Adding and Removing Destroy Callbacks
2.8.2. Dynamic Data Deallocation: The destroy Procedure
2.8.3. Dynamic Constraint Data Deallocation: The ConstraintClassPart destroy Procedure
2.8.4. Widget Instance Deallocation: The deallocate Procedure
2.9. Exiting from an Application
3.1. Addition of Children to a Composite Widget: The insert_child Procedure
3.2. Insertion Order of Children: The insert_position Procedure
3.3. Deletion of Children: The delete_child Procedure
3.4. Adding and Removing Children from the Managed Set
3.4.1. Managing Children
3.4.2. Unmanaging Children
3.4.3. Bundling Changes to the Managed Set
3.4.4. Determining if a Widget Is Managed
3.5. Controlling When Widgets Get Mapped
3.6. Constrained Composite Widgets
4.1. Shell Widget Definitions
4.1.1. ShellClassPart Definitions
4.1.2. ShellPart Definition
4.1.3. Shell Resources
4.1.4. ShellPart Default Values
4.2. Session Participation
4.2.1. Joining a Session
4.2.2. Saving Application State
4.2.2.1. Requesting Interaction
4.2.2.2. Interacting with the User during a Checkpoint
4.2.2.3. Responding to a Shutdown Cancellation
4.2.2.4. Completing a Save
4.2.3. Responding to a Shutdown
4.2.4. Resigning from a Session
5.1. Pop-Up Widget Types
5.2. Creating a Pop-Up Shell
5.3. Creating Pop-Up Children
5.4. Mapping a Pop-Up Widget
5.5. Unmapping a Pop-Up Widget
6.1. Initiating Geometry Changes
6.2. General Geometry Manager Requests
6.3. Resize Requests
6.4. Potential Geometry Changes
6.5. Child Geometry Management: The geometry_manager Procedure
6.6. Widget Placement and Sizing
6.7. Preferred Geometry
6.8. Size Change Management: The resize Procedure
7.1. Adding and Deleting Additional Event Sources
7.1.1. Adding and Removing Input Sources
7.1.2. Adding and Removing Blocking Notifications
7.1.3. Adding and Removing Timeouts
7.1.4. Adding and Removing Signal Callbacks
7.2. Constraining Events to a Cascade of Widgets
7.2.1. Requesting Key and Button Grabs
7.3. Focusing Events on a Child
7.3.1. Events for Drawables That Are Not a Widget’s Window
7.4. Querying Event Sources
7.5. Dispatching Events
7.6. The Application Input Loop
7.7. Setting and Checking the Sensitivity State of a Widget
7.8. Adding Background Work Procedures
7.9. X Event Filters
7.9.1. Pointer Motion Compression
7.9.2. Enter/Leave Compression
7.9.3. Exposure Compression
7.10. Widget Exposure and Visibility
7.10.1. Redisplay of a Widget: The expose Procedure
7.10.2. Widget Visibility
7.11. X Event Handlers
7.11.1. Event Handlers That Select Events
7.11.2. Event Handlers That Do Not Select Events
7.11.3. Current Event Mask
7.11.4. Event Handlers for X11 Protocol Extensions
7.12. Using the Intrinsics in a Multi-Threaded Environment
7.12.1. Initializing a Multi-Threaded Intrinsics Application
7.12.2. Locking X Toolkit Data Structures
7.12.2.1. Locking the Application Context
7.12.2.2. Locking the Process
7.12.3. Event Management in a Multi-Threaded Environment
8.1. Using Callback Procedure and Callback List Definitions
8.2. Identifying Callback Lists
8.3. Adding Callback Procedures
8.4. Removing Callback Procedures
8.5. Executing Callback Procedures
8.6. Checking the Status of a Callback List
9.1. Resource Lists
9.2. Byte Offset Calculations
9.3. Superclass-to-Subclass Chaining of Resource Lists
9.4. Subresources
9.5. Obtaining Application Resources
9.6. Resource Conversions
9.6.1. Predefined Resource Converters
9.6.2. New Resource Converters
9.6.3. Issuing Conversion Warnings
9.6.4. Registering a New Resource Converter
9.6.5. Resource Converter Invocation
9.7. Reading and Writing Widget State
9.7.1. Obtaining Widget State
9.7.1.1. Widget Subpart Resource Data: The get_values_hook Procedure
9.7.1.2. Widget Subpart State
9.7.2. Setting Widget State
9.7.2.1. Widget State: The set_values Procedure
9.7.2.2. Widget State: The set_values_almost Procedure
9.7.2.3. Widget State: The ConstraintClassPart set_values Procedure
9.7.2.4. Widget Subpart State
9.7.2.5. Widget Subpart Resource Data: The set_values_hook Procedure
10.1. Action Tables
10.1.1. Action Table Registration
10.1.2. Action Names to Procedure Translations
10.1.3. Action Hook Registration
10.2. Translation Tables
10.2.1. Event Sequences
10.2.2. Action Sequences
10.2.3. Multi-Click Time
10.3. Translation Table Management
10.4. Using Accelerators
10.5. KeyCode-to-KeySym Conversions
10.6. Obtaining a KeySym in an Action Procedure
10.7. KeySym-to-KeyCode Conversions
10.8. Registering Button and Key Grabs for Actions
10.9. Invoking Actions Directly
10.10. Obtaining a Widget’s Action List
11.1. Determining the Number of Elements in an Array
11.2. Translating Strings to Widget Instances
11.3. Managing Memory Usage
11.4. Sharing Graphics Contexts
11.5. Managing Selections
11.5.1. Setting and Getting the Selection Timeout Value
11.5.2. Using Atomic Transfers
11.5.2.1. Atomic Transfer Procedures
11.5.2.2. Getting the Selection Value
11.5.2.3. Setting the Selection Owner
11.5.3. Using Incremental Transfers
11.5.3.1. Incremental Transfer Procedures
11.5.3.2. Getting the Selection Value Incrementally
11.5.3.3. Setting the Selection Owner for Incremental Transfers
11.5.4. Setting and Retrieving Selection Target Parameters
11.5.5. Generating MULTIPLE Requests
11.5.6. Auxiliary Selection Properties
11.5.7. Retrieving the Most Recent Timestamp
11.5.8. Retrieving the Most Recent Event
11.6. Merging Exposure Events into a Region
11.7. Translating Widget Coordinates
11.8. Translating a Window to a Widget
11.9. Handling Errors
11.10. Setting WM_COLORMAP_WINDOWS
11.11. Finding File Names
11.12. Hooks for External Agents
11.12.1. Hook Object Resources
11.12.2. Querying Open Displays
12.1. Data Structures
12.2. Object Objects
12.2.1. ObjectClassPart Structure
12.2.2. ObjectPart Structure
12.2.3. Object Resources
12.2.4. ObjectPart Default Values
12.2.5. Object Arguments to Intrinsics Routines
12.2.6. Use of Objects
12.3. Rectangle Objects
12.3.1. RectObjClassPart Structure
12.3.2. RectObjPart Structure
12.3.3. RectObj Resources
12.3.4. RectObjPart Default Values
12.3.5. Widget Arguments to Intrinsics Routines
12.3.6. Use of Rectangle Objects
12.4. Undeclared Class
12.5. Widget Arguments to Intrinsics Routines
13.1. Determining Specification Revision Level
13.2. Release 3 to Release 4 Compatibility
13.2.1. Additional Arguments
13.2.2. set_values_almost Procedures
13.2.3. Query Geometry
13.2.4. unrealizeCallback Callback List
13.2.5. Subclasses of WMShell
13.2.6. Resource Type Converters
13.2.7. KeySym Case Conversion Procedure
13.2.8. Nonwidget Objects
13.3. Release 4 to Release 5 Compatibility
13.3.1. baseTranslations Resource
13.3.2. Resource File Search Path
13.3.3. Customization Resource
13.3.4. Per-Screen Resource Database
13.3.5. Internationalization of Applications
13.3.6. Permanently Allocated Strings
13.3.7. Arguments to Existing Functions
13.4. Release 5 to Release 6 Compatibility
13.4.1. Widget Internals
13.4.2. General Application Development
13.4.3. Communication with Window and Session Managers
13.4.4. Geometry Management
13.4.5. Event Management
13.4.6. Resource Management
13.4.7. Translation Management
13.4.8. Selections
13.4.9. External Agent Hooks
Notation
Syntax
Modifier Names
Event Types
Canonical Representation
Examples
Error Messages
Warning Messages

X Toolkit Intrinsics —C Language Interface

X Window System

X Version 11, Release 6.4

First Revision - April, 1994

Joel McCormack
Digital Equipment Corporation
Western Software Laboratory

Paul Asente
Digital Equipment Corporation
Western Software Laboratory

Ralph R. Swick
Digital Equipment Corporation
External Research Group
MIT X Consortium

version 6 edited by Donna Converse
X Consortium, Inc.

X Window System is a trademark of X Consortium, Inc.

Copyright © 1985, 1986, 1987, 1988, 1991, 1994 X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.

Copyright © 1985, 1986, 1987, 1988, 1991, 1994 Digital Equipment Corporation, Maynard, Massachusetts.

Permission to use, copy, modify and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Digital not be used in in advertising or publicity pertaining to distribution of the software without specific, written prior permission. Digital makes no representations about the suitability of the software described herein for any purpose. It is provided ‘‘as is’’ without express or implied warranty.

Acknowledgments

The design of the X11 Intrinsics was done primarily by Joel McCormack of Digital WSL. Major contributions to the design and implementation also were done by Charles Haynes, Mike Chow, and Paul Asente of Digital WSL. Additional contributors to the design and/or implementation were:

     Loretta Guarino-Reid (Digital WSL)Rich Hyde (Digital WSL)
     Susan Angebranndt (Digital WSL)Terry Weissman (Digital WSL)

Mary Larson (Digital UEG)

Mark Manasse (Digital SRC)
Jim Gettys (Digital SRC)

Leo Treggiari (Digital SDT)

Ralph Swick (Project Athena and Digital ERP)Mark Ackerman (Project Athena)

Ron Newman (Project Athena)

Bob Scheifler (MIT LCS)

The contributors to the X10 toolkit also deserve mention. Although the X11 Intrinsics present an entirely different programming style, they borrow heavily from the implicit and explicit concepts in the X10 toolkit.

The design and implementation of the X10 Intrinsics were done by:

     Terry Weissman (Digital WSL)
     Smokey Wallace (Digital WSL)
     Phil Karlton (Digital WSL)
     Charles Haynes (Digital WSL)
     Frank Hall (HP)

The design and implementation of the X10 toolkit’s sample widgets were by the above, as well as by:

     Ram Rao (Digital UEG)
     Mary Larson (Digital UEG)
     Mike Gancarz (Digital UEG)
     Kathleen Langone  (Digital UEG)

These widgets provided a checklist of requirements that we had to address in the X11 Intrinsics.

Thanks go to Al Mento of Digital’s UEG Documentation Group for formatting and generally improving this document and to John Ousterhout of Berkeley for extensively reviewing early drafts of it.

Finally, a special thanks to Mike Chow, whose extensive performance analysis of the X10 toolkit provided the justification to redesign it entirely for X11.

Joel McCormack
Western Software Laboratory
Digital Equipment Corporation

March 1988

xi

The current design of the Intrinsics has benefited greatly from the input of several dedicated reviewers in the membership of the X Consortium. In addition to those already mentioned, the following individuals have dedicated significant time to suggesting improvements to the Intrinsics:

     Steve Pitschke (Stellar)      C. Doug Blewett (AT&T)

Bob Miller (HP)

David Schiferl (Tektronix)
Fred Taft (HP)

Michael Squires (Sequent)
Marcel Meth (AT&T)

Jim Fulton (MIT)
Mike Collins (Digital)

Kerry Kimbrough (Texas Instruments)
Scott McGregor (Digital)

Phil Karlton (Digital)
Julian Payne (ESS)

Jacques Davy (Bull)
Gabriel Beged-Dov (HP)

Glenn Widener (Tektronix)

Thanks go to each of them for the countless hours spent reviewing drafts and code.

Ralph R. Swick
External Research Group
Digital Equipment Corporation
MIT Project Athena

June 1988

From Release 3 to Release 4, several new members joined the design team. We greatly appreciate the thoughtful comments, suggestions, lengthy discussions, and in some cases implementation code contributed by each of the following:

     Don Alecci (AT&T)             Ellis Cohen (OSF)

Donna Converse (MIT)

Clive Feather (IXI)
Nayeem Islam (Sun)

Dana Laursen (HP)
Keith Packard (MIT)

Chris Peterson (MIT)
Richard Probst (Sun)

Larry Cable (Sun)

In Release 5, the effort to define the internationalization additions was headed by Bill McMahon of Hewlett Packard and Frank Rojas of IBM. This has been an educational process for many of us, and Bill and Frank’s tutelage has carried us through. Vania Joloboff of the OSF also contributed to the internationalization additions. The implementation efforts of Bill, Gabe Beged-Dov, and especially Donna Converse for this release are also gratefully acknowledged.

Ralph R. Swick

December 1989
and
July 1991

xii

The Release 6 Intrinsics is a result of the collaborative efforts of participants in the X Consortium’s intrinsics working group. A few individuals contributed substantial design proposals, participated in lengthy discussions, reviewed final specifications, and in most cases, were also responsible for sections of the implementation. They deserve recognition and thanks for their major contributions:

     Paul Asente (Adobe)           Larry Cable (SunSoft)

Ellis Cohen (OSF)

Daniel Dardailler (OSF)
Vania Joloboff (OSF)

Kaleb Keithley (X Consortium)
Courtney Loomis (HP)

Douglas Rand (OSF)
Bob Scheifler (X Consortium)

Ajay Vohra (SunSoft)

Many others analyzed designs, offered useful comments and suggestions, and participated in a significant subset of the process. The following people deserve thanks for their contributions: Andy Bovingdon, Sam Chang, Chris Craig, George Erwin-Grotsky, Keith Edwards, Clive Feather, Stephen Gildea, Dan Heller, Steve Humphrey, David Kaelbling, Jaime Lau, Rob Lembree, Stuart Marks, Beth Mynatt, Tom Paquin, Chris Peterson, Kamesh Ramakrishna, Tom Rodriguez, Jim VanGilder, Will Walker, and Mike Wexler.

I am especially grateful to two of my colleagues: Ralph Swick for expert editorial guidance, and Kaleb Keithley for leadership in the implementation and the specification work.

Donna Converse
X Consortium
April 1994

xiii

About This Manual

X Toolkit Intrinsics — C Language Interface is intended to be read by both application programmers who will use one or more of the many widget sets built with the Intrinsics and by widget programmers who will use the Intrinsics to build widgets for one of the widget sets. Not all the information in this manual, however, applies to both audiences. That is, because the application programmer is likely to use only a number of the Intrinsics functions in writing an application and because the widget programmer is likely to use many more, if not all, of the Intrinsics functions in building a widget, an attempt has been made to highlight those areas of information that are deemed to be of special interest for the application programmer. (It is assumed the widget programmer will have to be familiar with all the information.) Therefore, all entries in the table of contents that are printed in bold indicate the information that should be of special interest to an application programmer.

It is also assumed that, as application programmers become more familiar with the concepts discussed in this manual, they will find it more convenient to implement portions of their applications as special-purpose or custom widgets. It is possible, nonetheless, to use widgets without knowing how to build them.

Conventions Used in this Manual

This document uses the following conventions:

Global symbols are printed in this special font. These can be either function names, symbols defined in include files, data types, or structure names. Arguments to functions, procedures, or macros are printed in italics.

Each function is introduced by a general discussion that distinguishes it from other functions. The function declaration itself follows, and each argument is specifically explained. General discussion of the function, if any is required, follows the arguments.

To eliminate any ambiguity between those arguments that you pass and those that a function returns to you, the explanations for all arguments that you pass start with the word specifies or, in the case of multiple arguments, the word specify. The explanations for all arguments that are returned to you start with the word returns or, in the case of multiple arguments, the word return.

xiv

Chapter 1

Intrinsics and Widgets

The Intrinsics are a programming library tailored to the special requirements of user interface construction within a network window system, specifically the X Window System. The Intrinsics and a widget set make up an X Toolkit.

1.1. Intrinsics

The Intrinsics provide the base mechanism necessary to build a wide variety of interoperating widget sets and application environments. The Intrinsics are a layer on top of Xlib, the C Library X Interface. They extend the fundamental abstractions provided by the X Window System while still remaining independent of any particular user interface policy or style.

The Intrinsics use object-oriented programming techniques to supply a consistent architecture for constructing and composing user interface components, known as widgets. This allows programmers to extend a widget set in new ways, either by deriving new widgets from existing ones (subclassing) or by writing entirely new widgets following the established conventions.

When the Intrinsics were first conceived, the root of the object hierarchy was a widget class named Core. In Release 4 of the Intrinsics, three nonwidget superclasses were added above Core. These superclasses are described in Chapter 12. The name of the class now at the root of the Intrinsics class hierarchy is Object. The remainder of this specification refers uniformly to widgets and Core as if they were the base class for all Intrinsics operations. The argument descriptions for each Intrinsics procedure and Chapter 12 describe which operations are defined for the nonwidget superclasses of Core. The reader may determine by context whether a specific reference to widget actually means ‘‘widget’’ or ‘‘object.’’

1.2. Languages

The Intrinsics are intended to be used for two programming purposes. Programmers writing widgets will be using most of the facilities provided by the Intrinsics to construct user interface components from the simple, such as buttons and scrollbars, to the complex, such as control panels and property sheets. Application programmers will use a much smaller subset of the Intrinsics procedures in combination with one or more sets of widgets to construct and present complete user interfaces on an X display. The Intrinsics programming interfaces primarily intended for application use are designed to be callable from most procedural programming languages. Therefore, most arguments are passed by reference rather than by value. The interfaces primarily intended for widget programmers are expected to be used principally from the C language. In these cases, the usual C programming conventions apply. In this specification, the term client refers to any module, widget, or application that calls an Intrinsics procedure.

Applications that use the Intrinsics mechanisms must include the header files <X11/Intrinsic.h> and <X11/StringDefs.h>, or their equivalent, and they may also include <X11/Xatoms.h> and <X11/Shell.h>. In addition, widget implementations should include <X11/IntrinsicP.h> instead of <X11/Intrinsic.h>.

The applications must also include the additional header files for each widget class that they are to use (for example, <X11/Xaw/Label.h> or <X11/Xaw/Scrollbar.h>). On a POSIX-based system, the Intrinsics object library file is named libXt.a and is usually referenced as −lXt when linking the application.

1.3. Procedures and Macros

All functions defined in this specification except those specified below may be implemented as C macros with arguments. C applications may use ‘‘#undef’’ to remove a macro definition and ensure that the actual function is referenced. Any such macro will expand to a single expression that has the same precedence as a function call and that evaluates each of its arguments exactly once, fully protected by parentheses, so that arbitrary expressions may be used as arguments.

The following symbols are macros that do not have function equivalents and that may expand their arguments in a manner other than that described above: XtCheckSubclass, XtNew, XtNumber, XtOffsetOf, XtOffset, and XtSetArg.

1.4. Widgets

The fundamental abstraction and data type of the X Toolkit is the widget, which is a combination of an X window and its associated input and display semantics and which is dynamically allocated and contains state information. Some widgets display information (for example, text or graphics), and others are merely containers for other widgets (for example, a menu box). Some widgets are output-only and do not react to pointer or keyboard input, and others change their display in response to input and can invoke functions that an application has attached to them.

Every widget belongs to exactly one widget class, which is statically allocated and initialized and which contains the operations allowable on widgets of that class. Logically, a widget class is the procedures and data associated with all widgets belonging to that class. These procedures and data can be inherited by subclasses. Physically, a widget class is a pointer to a structure. The contents of this structure are constant for all widgets of the widget class but will vary from class to class. (Here, ‘‘constant’’ means the class structure is initialized at compile time and never changed, except for a one-time class initialization and in-place compilation of resource lists, which takes place when the first widget of the class or subclass is created.) For further information, see Section 2.5.

The distribution of the declarations and code for a new widget class among a public .h file for application programmer use, a private .h file for widget programmer use, and the implementation .c file is described in Section 1.6. The predefined widget classes adhere to these conventions.

A widget instance is composed of two parts:

A data structure which contains instance-specific values.

A class structure which contains information that is applicable to all widgets of that class.

Much of the input/output of a widget (for example, fonts, colors, sizes, or border widths) is customizable by users.

This chapter discusses the base widget classes, Core, Composite, and Constraint, and ends with a discussion of widget classing.

1.4.1. Core Widgets

The Core widget class contains the definitions of fields common to all widgets. All widgets classes are subclasses of the Core class, which is defined by the CoreClassPart and CorePart structures.

1.4.1.1. CoreClassPart Structure

All widget classes contain the fields defined in the CoreClassPart structure.

__ │

typedef struct {

WidgetClass superclass;

See Section 1.6

String class_name;

See Chapter 9

Cardinal widget_size;

See Section 1.6

XtProc class_initialize;

See Section 1.6

XtWidgetClassProc class_part_initialize;See Section 1.6

XtEnum class_inited;

See Section 1.6

XtInitProc initialize;

See Section 2.5

XtArgsProc initialize_hook;

See Section 2.5

XtRealizeProc realize;

See Section 2.6

XtActionList actions;

See Chapter 10

Cardinal num_actions;

See Chapter 10

XtResourceList resources;

See Chapter 9

Cardinal num_resources;

See Chapter 9

XrmClass xrm_class;

Private to resource manager

Boolean compress_motion;

See Section 7.9

XtEnum compress_exposure;

See Section 7.9

Boolean compress_enterleave;

See Section 7.9

Boolean visible_interest;

See Section 7.10

XtWidgetProc destroy;

See Section 2.8

XtWidgetProc resize;

See Chapter 6

XtExposeProc expose;

See Section 7.10

XtSetValuesFunc set_values;

See Section 9.7

XtArgsFunc set_values_hook;

See Section 9.7

XtAlmostProc set_values_almost;See Section 9.7

XtArgsProc get_values_hook;

See Section 9.7

XtAcceptFocusProc accept_focus;See Section 7.3

XtVersionType version;

See Section 1.6

XtPointer callback_private;

Private to callbacks

String tm_table;

See Chapter 10

XtGeometryHandler query_geometry;See Chapter 6

XtStringProc display_accelerator;See Chapter 10

XtPointer extension;

See Section 1.6

} CoreClassPart;

│__

All widget classes have the Core class fields as their first component. The prototypical WidgetClass and CoreWidgetClass are defined with only this set of fields.

__ │

typedef struct {

CoreClassPart core_class;

} WidgetClassRec, *WidgetClass, CoreClassRec, *CoreWidgetClass;

│__

Various routines can cast widget class pointers, as needed, to specific widget class types.

The single occurrences of the class record and pointer for creating instances of Core are

In IntrinsicP.h:

__ │

extern WidgetClassRec widgetClassRec;
#define coreClassRec widgetClassRec


│__

In Intrinsic.h:

__ │

extern WidgetClass widgetClass, coreWidgetClass;


│__

The opaque types Widget and WidgetClass and the opaque variable widgetClass are defined for generic actions on widgets. In order to make these types opaque and ensure that the compiler does not allow applications to access private data, the Intrinsics use incomplete structure definitions in Intrinsic.h:

__ │

typedef struct _WidgetClassRec *WidgetClass, *CoreWidgetClass;


│__

1.4.1.2. CorePart Structure

All widget instances contain the fields defined in the CorePart structure.

__ │

typedef struct _CorePart {

Widget self;

Described below

WidgetClass widget_class;See Section 1.6

Widget parent;

See Section 2.5

Boolean being_destroyed;

See Section 2.8

XtCallbackList destroy_callbacks;See Section 2.8

XtPointer constraints;

See Section 3.6

Position x;

See Chapter 6

Position y;

See Chapter 6

Dimension width;

See Chapter 6

Dimension height;

See Chapter 6

Dimension border_width;

See Chapter 6

Boolean managed;

See Chapter 3

Boolean sensitive;

See Section 7.7

Boolean ancestor_sensitive;See Section 7.7

XtTranslations accelerators;See Chapter 10

Pixel border_pixel;

See Section 2.6

Pixmap border_pixmap;

See Section 2.6

WidgetList popup_list;

See Chapter 5

Cardinal num_popups;

See Chapter 5

String name;

See Chapter 9

Screen *screen;

See Section 2.6

Colormap colormap;

See Section 2.6

Window window;

See Section 2.6

Cardinal depth;

See Section 2.6

Pixel background_pixel;

See Section 2.6

Pixmap background_pixmap;See Section 2.6

Boolean visible;

See Section 7.10

Boolean mapped_when_managed;See Chapter 3

} CorePart;

│__

All widget instances have the Core fields as their first component. The prototypical type Widget is defined with only this set of fields.

__ │

typedef struct {

CorePart core;

} WidgetRec, *Widget, CoreRec, *CoreWidget;

│__

Various routines can cast widget pointers, as needed, to specific widget types.

In order to make these types opaque and ensure that the compiler does not allow applications to access private data, the Intrinsics use incomplete structure definitions in Intrinsic.h.

__ │

typedef struct _WidgetRec *Widget, *CoreWidget;


│__

1.4.1.3. Core Resources

The resource names, classes, and representation types specified in the coreClassRec resource list are

Additional resources are defined for all widgets via the objectClassRec and rectObjClassRec resource lists; see Sections 12.2 and 12.3 for details.

1.4.1.4. CorePart Default Values

The default values for the Core fields, which are filled in by the Intrinsics, from the resource lists, and by the initialize procedures, are

XtUnspecifiedPixmap is a symbolic constant guaranteed to be unequal to any valid Pixmap id, None, and ParentRelative.

1.4.2. Composite Widgets

The Composite widget class is a subclass of the Core widget class (see Chapter 3). Composite widgets are intended to be containers for other widgets. The additional data used by composite widgets are defined by the CompositeClassPart and CompositePart structures.

1.4.2.1. CompositeClassPart Structure

In addition to the Core class fields, widgets of the Composite class have the following class fields.

__ │

typedef struct {

XtGeometryHandler geometry_manager;See Chapter 6

XtWidgetProc change_managed;

See Chapter 3

XtWidgetProc insert_child;

See Chapter 3

XtWidgetProc delete_child;

See Chapter 3

XtPointer extension;

See Section 1.6

} CompositeClassPart;

│__

The extension record defined for CompositeClassPart with record_type equal to NULLQUARK is CompositeClassExtensionRec.

__ │

typedef struct {

XtPointer next_extension;

See Section 1.6.12

XrmQuark record_type;

See Section 1.6.12

long version;

See Section 1.6.12

Cardinal record_size;

See Section 1.6.12

Boolean accepts_objects;

See Section 2.5.2

Boolean allows_change_managed_set;See Section 3.4.3

} CompositeClassExtensionRec, *CompositeClassExtension;

│__

Composite classes have the Composite class fields immediately following the Core class fields.

__ │

typedef struct {

CoreClassPart core_class;

CompositeClassPart composite_class;

} CompositeClassRec, *CompositeWidgetClass;

│__

The single occurrences of the class record and pointer for creating instances of Composite are

In IntrinsicP.h:

__ │

extern CompositeClassRec compositeClassRec;


│__

In Intrinsic.h:

__ │

extern WidgetClass compositeWidgetClass;


│__

The opaque types CompositeWidget and CompositeWidgetClass and the opaque variable compositeWidgetClass are defined for generic operations on widgets whose class is Composite or a subclass of Composite. The symbolic constant for the CompositeClassExtension version identifier is XtCompositeExtensionVersion (see Section 1.6.12). Intrinsic.h uses an incomplete structure definition to ensure that the compiler catches attempts to access private data.

__ │

typedef struct _CompositeClassRec *CompositeWidgetClass;


│__

1.4.2.2. CompositePart Structure

In addition to the Core instance fields, widgets of the Composite class have the following instance fields defined in the CompositePart structure.

__ │

typedef struct {

WidgetList children;

See Chapter 3

Cardinal num_children;

See Chapter 3

Cardinal num_slots;

See Chapter 3

XtOrderProc insert_position;See Section 3.2

} CompositePart;

│__

Composite widgets have the Composite instance fields immediately following the Core instance fields.

__ │

typedef struct {

CorePart core;

CompositePart composite;

} CompositeRec, *CompositeWidget;

│__

Intrinsic.h uses an incomplete structure definition to ensure that the compiler catches attempts to access private data.

__ │

typedef struct _CompositeRec *CompositeWidget;


│__

1.4.2.3. Composite Resources

The resource names, classes, and representation types that are specified in the compositeClassRec resource list are

1.4.2.4. CompositePart Default Values

The default values for the Composite fields, which are filled in from the Composite resource list and by the Composite initialize procedure, are

The children, num_children, and insert_position fields are declared as resources; XtNinsertPosition is a settable resource, XtNchildren and XtNnumChildren may be read by any client but should only be modified by the composite widget class procedures.

1.4.3. Constraint Widgets

The Constraint widget class is a subclass of the Composite widget class (see Section 3.6). Constraint widgets maintain additional state data for each child; for example, client-defined constraints on the child’s geometry. The additional data used by constraint widgets are defined by the ConstraintClassPart and ConstraintPart structures.

1.4.3.1. ConstraintClassPart Structure

In addition to the Core and Composite class fields, widgets of the Constraint class have the following class fields.

__ │

typedef struct {

XtResourceList resources;See Chapter 9

Cardinal num_resources;

See Chapter 9

Cardinal constraint_size;See Section 3.6

XtInitProc initialize;

See Section 3.6

XtWidgetProc destroy;

See Section 3.6

XtSetValuesFunc set_values;See Section 9.7.2

XtPointer extension;

See Section 1.6

} ConstraintClassPart;

│__

The extension record defined for ConstraintClassPart with record_type equal to NULLQUARK is ConstraintClassExtensionRec.

__ │

typedef struct {

XtPointer next_extension;See Section 1.6.12

XrmQuark record_type;

See Section 1.6.12

long version;

See Section 1.6.12

Cardinal record_size;

See Section 1.6.12

XtArgsProc get_values_hook;See Section 9.7.1

} ConstraintClassExtensionRec, *ConstraintClassExtension;

│__

Constraint classes have the Constraint class fields immediately following the Composite class fields.

__ │

typedef struct _ConstraintClassRec {

CoreClassPart core_class;

CompositeClassPart composite_class;

ConstraintClassPart constraint_class;

} ConstraintClassRec, *ConstraintWidgetClass;

│__

The single occurrences of the class record and pointer for creating instances of Constraint are

In IntrinsicP.h:

__ │

extern ConstraintClassRec constraintClassRec;


│__

In Intrinsic.h:

__ │

extern WidgetClass constraintWidgetClass;


│__

The opaque types ConstraintWidget and ConstraintWidgetClass and the opaque variable constraintWidgetClass are defined for generic operations on widgets whose class is Constraint or a subclass of Constraint. The symbolic constant for the ConstraintClassExtension version identifier is XtConstraintExtensionVersion (see Section 1.6.12). Intrinsic.h uses an incomplete structure definition to ensure that the compiler catches attempts to access private data.

__ │

typedef struct _ConstraintClassRec *ConstraintWidgetClass;


│__

1.4.3.2. ConstraintPart Structure

In addition to the Core and Composite instance fields, widgets of the Constraint class have the following unused instance fields defined in the ConstraintPart structure

__ │

typedef struct {
        int empty;
} ConstraintPart;


│__

Constraint widgets have the Constraint instance fields immediately following the Composite instance fields.

__ │

typedef struct {

CorePart core;

CompositePart composite;

ConstraintPart constraint;

} ConstraintRec, *ConstraintWidget;

│__

Intrinsic.h uses an incomplete structure definition to ensure that the compiler catches attempts to access private data.

__ │

typedef struct _ConstraintRec *ConstraintWidget;


│__

1.4.3.3. Constraint Resources

The constraintClassRec core_class and constraint_class resources fields are NULL, and the num_resources fields are zero; no additional resources beyond those declared by the superclasses are defined for Constraint.

1.5. Implementation-Specific Types

To increase the portability of widget and application source code between different system environments, the Intrinsics define several types whose precise representation is explicitly dependent upon, and chosen by, each individual implementation of the Intrinsics.

These implementation-defined types are

Boolean

A datum that contains a zero or nonzero value. Unless explicitly stated, clients should not assume that the nonzero value is equal to the symbolic value True.

Cardinal

An unsigned integer datum with a minimum range of [0..2^16-1].

Dimension

An unsigned integer datum with a minimum range of [0..2^16-1].

Position

A signed integer datum with a minimum range of [-2^15..2^15-1].

XtPointer

A datum large enough to contain the largest of a char*, int*, function pointer, structure pointer, or long value. A pointer to any type or function, or a long value may be converted to an XtPointer and back again and the result will compare equal to the original value. In ANSI C environments it is expected that XtPointer will be defined as void*.

XtArgVal

A datum large enough to contain an XtPointer, Cardinal, Dimension, or Position value.

XtEnum

An integer datum large enough to encode at least 128 distinct values, two of which are the symbolic values True and False. The symbolic values TRUE and FALSE are also defined to be equal to True and False, respectively.

In addition to these specific types, the precise order of the fields within the structure declarations for any of the instance part records ObjectPart, RectObjPart, CorePart, CompositePart, ShellPart, WMShellPart, TopLevelShellPart, and ApplicationShellPart is implementation-defined. These structures may also have additional private fields internal to the implementation. The ObjectPart, RectObjPart, and CorePart structures must be defined so that any member with the same name appears at the same offset in ObjectRec, RectObjRec, and CoreRec (WidgetRec). No other relations between the offsets of any two fields may be assumed.

1.6. Widget Classing

The widget_class field of a widget points to its widget class structure, which contains information that is constant across all widgets of that class. As a consequence, widgets usually do not implement directly callable procedures; rather, they implement procedures, called methods, that are available through their widget class structure. These methods are invoked by generic procedures that envelop common actions around the methods implemented by the widget class. Such procedures are applicable to all widgets of that class and also to widgets whose classes are subclasses of that class.

All widget classes are a subclass of Core and can be subclassed further. Subclassing reduces the amount of code and declarations necessary to make a new widget class that is similar to an existing class. For example, you do not have to describe every resource your widget uses in an XtResourceList. Instead, you describe only the resources your widget has that its superclass does not. Subclasses usually inherit many of their superclasses’ procedures (for example, the expose procedure or geometry handler).

Subclassing, however, can be taken too far. If you create a subclass that inherits none of the procedures of its superclass, you should consider whether you have chosen the most appropriate superclass.

To make good use of subclassing, widget declarations and naming conventions are highly stylized. A widget consists of three files:

A public .h file, used by client widgets or applications.

A private .h file, used by widgets whose classes are subclasses of the widget class.

A .c file, which implements the widget.

1.6.1. Widget Naming Conventions

The Intrinsics provide a vehicle by which programmers can create new widgets and organize a collection of widgets into an application. To ensure that applications need not deal with as many styles of capitalization and spelling as the number of widget classes it uses, the following guidelines should be followed when writing new widgets:

Use the X library naming conventions that are applicable. For example, a record component name is all lowercase and uses underscores (_) for compound words (for example, background_pixmap). Type and procedure names start with uppercase and use capitalization for compound words (for example, ArgList or XtSetValues).

A resource name is spelled identically to the field name except that compound names use capitalization rather than underscore. To let the compiler catch spelling errors, each resource name should have a symbolic identifier prefixed with ‘‘XtN’’. For example, the background_pixmap field has the corresponding identifier XtNbackgroundPixmap, which is defined as the string ‘‘backgroundPixmap’’. Many predefined names are listed in <X11/StringDefs.h>. Before you invent a new name, you should make sure there is not already a name that you can use.

A resource class string starts with a capital letter and uses capitalization for compound names (for example,‘‘BorderWidth’’). Each resource class string should have a symbolic identifier prefixed with ‘‘XtC’’ (for example, XtCBorderWidth). Many predefined classes are listed in <X11/StringDefs.h>.

A resource representation string is spelled identically to the type name (for example, ‘‘TranslationTable’’). Each representation string should have a symbolic identifier prefixed with ‘‘XtR’’ (for example, XtRTranslationTable). Many predefined representation types are listed in <X11/StringDefs.h>.

New widget classes start with a capital and use uppercase for compound words. Given a new class name AbcXyz, you should derive several names:

Additional widget instance structure part name AbcXyzPart.

Complete widget instance structure names AbcXyzRec and _AbcXyzRec.

Widget instance structure pointer type name AbcXyzWidget.

Additional class structure part name AbcXyzClassPart.

Complete class structure names AbcXyzClassRec and _AbcXyzClassRec.

Class structure pointer type name AbcXyzWidgetClass.

Class structure variable abcXyzClassRec.

Class structure pointer variable abcXyzWidgetClass.

Action procedures available to translation specifications should follow the same naming conventions as procedures. That is, they start with a capital letter, and compound names use uppercase (for example, ‘‘Highlight’’ and ‘‘NotifyClient’’).

The symbolic identifiers XtN..., XtC..., and XtR... may be implemented as macros, as global symbols, or as a mixture of the two. The (implicit) type of the identifier is String. The pointer value itself is not significant; clients must not assume that inequality of two identifiers implies inequality of the resource name, class, or representation string. Clients should also note that although global symbols permit savings in literal storage in some environments, they also introduce the possibility of multiple definition conflicts when applications attempt to use independently developed widgets simultaneously.

1.6.2. Widget Subclassing in Public .h Files

The public .h file for a widget class is imported by clients and contains

A reference to the public .h file for the superclass.

Symbolic identifiers for the names and classes of the new resources that this widget adds to its superclass. The definitions should have a single space between the definition name and the value and no trailing space or comment in order to reduce the possibility of compiler warnings from similar declarations in multiple classes.

Type declarations for any new resource data types defined by the class.

The class record pointer variable used to create widget instances.

The C type that corresponds to widget instances of this class.

Entry points for new class methods.

For example, the following is the public .h file for a possible implementation of a Label widget:

     #ifndef LABEL_H
     #define LABEL_H

    /* New resources */
     #define XtNjustify "justify"
     #define XtNforeground "foreground"
     #define XtNlabel "label"
     #define XtNfont "font"
     #define XtNinternalWidth "internalWidth"
     #define XtNinternalHeight "internalHeight"

    /* Class record pointer */
     extern WidgetClass labelWidgetClass;

    /* C Widget type definition */
     typedef struct _LabelRec      *LabelWidget;

    /* New class method entry points */
     extern void LabelSetText();

/* Widget w */
/* String text */

extern String LabelGetText();

/* Widget w */

#endif LABEL_H

The conditional inclusion of the text allows the application to include header files for different widgets without being concerned that they already may be included as a superclass of another widget.

To accommodate operating systems with file name length restrictions, the name of the public .h file is the first ten characters of the widget class. For example, the public .h file for the Constraint widget class is Constraint.h.

1.6.3. Widget Subclassing in Private .h Files

The private .h file for a widget is imported by widget classes that are subclasses of the widget and contains

A reference to the public .h file for the class.

A reference to the private .h file for the superclass.

Symbolic identifiers for any new resource representation types defined by the class. The definitions should have a single space between the definition name and the value and no trailing space or comment.

A structure part definition for the new fields that the widget instance adds to its superclass’s widget structure.

The complete widget instance structure definition for this widget.

A structure part definition for the new fields that this widget class adds to its superclass’s constraint structure if the widget class is a subclass of Constraint.

The complete constraint structure definition if the widget class is a subclass of Constraint.

Type definitions for any new procedure types used by class methods declared in the widget class part.

A structure part definition for the new fields that this widget class adds to its superclass’s widget class structure.

The complete widget class structure definition for this widget.

The complete widget class extension structure definition for this widget, if any.

The symbolic constant identifying the class extension version, if any.

The name of the global class structure variable containing the generic class structure for this class.

An inherit constant for each new procedure in the widget class part structure.

For example, the following is the private .h file for a possible Label widget:

     #ifndef LABELP_H
     #define LABELP_H

    #include <X11/Label.h>

    /* New representation types used by the Label widget */
     #define XtRJustify "Justify"

    /* New fields for the Label widget record */
     typedef struct {
     /* Settable resources */

Pixel foreground;
XFontStruct *font;
String label;

/* text to display */
XtJustify justify;
Dimension internal_width;/* # pixels horizontal border */
Dimension internal_height;/* # pixels vertical border */

/* Data derived from resources */

GC normal_GC;
GC gray_GC;
Pixmap gray_pixmap;
Position label_x;
Position label_y;
Dimension label_width;
Dimension label_height;
Cardinal label_len;
Boolean display_sensitive;

} LabelPart;

     /* Full instance record declaration */
     typedef struct _LabelRec {

CorePart core;
LabelPart label;

} LabelRec;

/* Types for Label class methods */
typedef void (*LabelSetTextProc)();

/* Widget w */
/* String text */

typedef String (*LabelGetTextProc)();

/* Widget w */

/* New fields for the Label widget class record */
typedef struct {

LabelSetTextProc set_text;
LabelGetTextProc get_text;
XtPointer extension;

} LabelClassPart;

/* Full class record declaration */
typedef struct _LabelClassRec {

CoreClassPart core_class;
LabelClassPart label_class;

} LabelClassRec;

/* Class record variable */
extern LabelClassRec labelClassRec;

#define LabelInheritSetText((LabelSetTextProc)_XtInherit)
#define LabelInheritGetText((LabelGetTextProc)_XtInherit)
#endif LABELP_H

To accommodate operating systems with file name length restrictions, the name of the private .h file is the first nine characters of the widget class followed by a capital P. For example, the private .h file for the Constraint widget class is ConstrainP.h.

1.6.4. Widget Subclassing in .c Files

The .c file for a widget contains the structure initializer for the class record variable, which contains the following parts:

Class information (for example, superclass, class_name, widget_size, class_initialize, and class_inited).

Data constants (for example, resources and num_resources, actions and num_actions, visible_interest, compress_motion, compress_exposure, and version).

Widget operations (for example, initialize, realize, destroy, resize, expose, set_values, accept_focus, and any new operations specific to the widget).

The superclass field points to the superclass global class record, declared in the superclass private .h file. For direct subclasses of the generic core widget, superclass should be initialized to the address of the widgetClassRec structure. The superclass is used for class chaining operations and for inheriting or enveloping a superclass’s operations (see Sections 1.6.7, 1.6.9, and 1.6.10).

The class_name field contains the text name for this class, which is used by the resource manager. For example, the Label widget has the string ‘‘Label’’. More than one widget class can share the same text class name. This string must be permanently allocated prior to or during the execution of the class initialization procedure and must not be subsequently deallocated.

The widget_size field is the size of the corresponding widget instance structure (not the size of the class structure).

The version field indicates the toolkit implementation version number and is used for runtime consistency checking of the X Toolkit and widgets in an application. Widget writers must set it to the implementation-defined symbolic value XtVersion in the widget class structure initialization. Those widget writers who believe that their widget binaries are compatible with other implementations of the Intrinsics can put the special value XtVersionDontCheck in the version field to disable version checking for those widgets. If a widget needs to compile alternative code for different revisions of the Intrinsics interface definition, it may use the symbol XtSpecificationRelease, as described in Chapter 13. Use of XtVersion allows the Intrinsics implementation to recognize widget binaries that were compiled with older implementations.

The extension field is for future upward compatibility. If the widget programmer adds fields to class parts, all subclass structure layouts change, requiring complete recompilation. To allow clients to avoid recompilation, an extension field at the end of each class part can point to a record that contains any additional class information required.

All other fields are described in their respective sections.

The .c file also contains the declaration of the global class structure pointer variable used to create instances of the class. The following is an abbreviated version of the .c file for a Label widget. The resources table is described in Chapter 9.

     /* Resources specific to Label */
     static XtResource resources[] = {

{XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
XtOffset(LabelWidget, label.foreground), XtRString,
XtDefaultForeground},
{XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
XtOffset(LabelWidget, label.font),XtRString,
XtDefaultFont},
{XtNlabel, XtCLabel, XtRString, sizeof(String),
XtOffset(LabelWidget, label.label), XtRString, NULL},

.

.

.

}

/* Forward declarations of procedures */
static void ClassInitialize();
static void Initialize();
static void Realize();
static void SetText();
static void GetText();

.
.
.

     /* Class record constant */
     LabelClassRec labelClassRec = {
       {
         /* core_class fields */

/* superclass

*/

(WidgetClass)&coreClassRec,
/* class_name

*/

"Label",
/* widget_size

*/

sizeof(LabelRec),
/* class_initialize

*/ClassInitialize,
/* class_part_initialize

*/NULL,
/* class_inited

*/False,
/* initialize

*/

Initialize,
/* initialize_hook

*/NULL,
/* realize

*/

Realize,
/* actions

*/

NULL,
/* num_actions

*/

0,
/* resources

*/

resources,
/* num_resources

*/XtNumber(resources),
/* xrm_class

*/

NULLQUARK,
/* compress_motion

*/True,
/* compress_exposure

*/True,
/* compress_enterleave

*/True,
/* visible_interest

*/False,
/* destroy

*/

NULL,
/* 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_offsets

*/NULL,
/* tm_table

*/

NULL,
/* query_geometry

*/XtInheritQueryGeometry,
/* display_accelerator

*/NULL,
/* extension

*/

NULL

},
{

/* Label_class fields

*/
/* get_text

*/

GetText,
/* set_text

*/

SetText,
/* extension

*/

NULL

}
};

/* Class record pointer */
WidgetClass labelWidgetClass = (WidgetClass) &labelClassRec;

/* New method access routines */
void LabelSetText(w, text)

Widget w;
String text;

{

Label WidgetClass lwc = (Label WidgetClass)XtClass(w);
XtCheckSubclass(w, labelWidgetClass, NULL);
*(lwc->label_class.set_text)(w, text)

}
/* Private procedures */

.
.
.

1.6.5. Widget Class and Superclass Look Up

To obtain the class of a widget, use XtClass.

__ │

WidgetClass XtClass(w)
      Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

The XtClass function returns a pointer to the widget’s class structure.

To obtain the superclass of a widget, use XtSuperclass.

__ │

WidgetClass XtSuperclass(w)
      Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

The XtSuperclass function returns a pointer to the widget’s superclass class structure.

1.6.6. Widget Subclass Verification

To check the subclass to which a widget belongs, use XtIsSubclass.

__ │

Boolean XtIsSubclass(w, widget_class)
      Widget w;
      WidgetClass widget_class;

w

Specifies the widget or object instance whose class is to be checked. Must be of class Object or any subclass thereof.

widget_class Specifies the widget class for which to test. Must be objectClass or any subclass thereof.

│__

The XtIsSubclass function returns True if the class of the specified widget is equal to or is a subclass of the specified class. The widget’s class can be any number of subclasses down the chain and need not be an immediate subclass of the specified class. Composite widgets that need to restrict the class of the items they contain can use XtIsSubclass to find out if a widget belongs to the desired class of objects.

To test if a given widget belongs to a subclass of an Intrinsics-defined class, the Intrinsics define macros or functions equivalent to XtIsSubclass for each of the built-in classes. These procedures are XtIsObject, XtIsRectObj, XtIsWidget, XtIsComposite, XtIsConstraint, XtIsShell, XtIsOverrideShell, XtIsWMShell, XtIsVendorShell, XtIsTransientShell, XtIsTopLevelShell, XtIsApplicationShell, and XtIsSessionShell.

All these macros and functions have the same argument description.

__ │

Boolean XtIs<class> (w)
      Widget w;

w

Specifies the widget or object instance whose class is to be checked. Must be of class Object or any subclass thereof.

│__

These procedures may be faster than calling XtIsSubclass directly for the built-in classes.

To check a widget’s class and to generate a debugging error message, use XtCheckSubclass, defined in <X11/IntrinsicP.h>:

__ │

void XtCheckSubclass(w, widget_class, message)
      Widget w;
      WidgetClass widget_class;
      String message;

w

Specifies the widget or object whose class is to be checked. Must be of class Object or any subclass thereof.

widget_class Specifies the widget class for which to test. Must be objectClass or any subclass thereof.

message

Specifies the message to be used.

│__

The XtCheckSubclass macro determines if the class of the specified widget is equal to or is a subclass of the specified class. The widget’s class can be any number of subclasses down the chain and need not be an immediate subclass of the specified class. If the specified widget’s class is not a subclass, XtCheckSubclass constructs an error message from the supplied message, the widget’s actual class, and the expected class and calls XtErrorMsg. XtCheckSubclass should be used at the entry point of exported routines to ensure that the client has passed in a valid widget class for the exported operation.

XtCheckSubclass is only executed when the module has been compiled with the compiler symbol DEBUG defined; otherwise, it is defined as the empty string and generates no code.

1.6.7. Superclass Chaining

While most fields in a widget class structure are self-contained, some fields are linked to their corresponding fields in their superclass structures. With a linked field, the Intrinsics access the field’s value only after accessing its corresponding superclass value (called downward superclass chaining) or before accessing its corresponding superclass value (called upward superclass chaining). The self-contained fields are

In all widget classes:class_name

class_initialize

widget_size

realize

visible_interest

resize

expose

accept_focus

compress_motion

compress_exposure

compress_enterleave

set_values_almost

tm_table

version

allocate

deallocate

In Composite widget classes:geometry_manager

change_managed

insert_child

delete_child

accepts_objects

allows_change_managed_set

In Constraint widget classes:constraint_size

In Shell widget classes:root_geometry_manager

With downward superclass chaining, the invocation of an operation first accesses the field from the Object, RectObj, and Core class structures, then from the subclass structure, and so on down the class chain to that widget’s class structure. These superclass-to-subclass fields are

class_part_initialize

get_values_hook

initialize

initialize_hook

set_values

set_values_hook

resources

In addition, for subclasses of Constraint, the following fields of the ConstraintClassPart and ConstraintClassExtensionRec structures are chained from the Constraint class down to the subclass:

resources

initialize

set_values

get_values_hook

With upward superclass chaining, the invocation of an operation first accesses the field from the widget class structure, then from the superclass structure, and so on up the class chain to the Core, RectObj, and Object class structures. The subclass-to-superclass fields are

destroy

actions

For subclasses of Constraint, the following field of ConstraintClassPart is chained from the subclass up to the Constraint class:

destroy

1.6.8. Class Initialization: class_initialize and class_part_initialize Procedures

Many class records can be initialized completely at compile or link time. In some cases, however, a class may need to register type converters or perform other sorts of once-only runtime initialization.

Because the C language does not have initialization procedures that are invoked automatically when a program starts up, a widget class can declare a class_initialize procedure that will be automatically called exactly once by the Intrinsics. A class initialization procedure pointer is of type XtProc:

__ │

typedef void (*XtProc)(void);

│__

A widget class indicates that it has no class initialization procedure by specifying NULL in the class_initialize field.

In addition to the class initialization that is done exactly once, some classes perform initialization for fields in their parts of the class record. These are performed not just for the particular class, but for subclasses as well, and are done in the class’s class part initialization procedure, a pointer to which is stored in the class_part_initialize field. The class_part_initialize procedure pointer is of type XtWidgetClassProc.

__ │

typedef void (*XtWidgetClassProc)(WidgetClass);
      WidgetClass widget_class;

widget_class Points to the class structure for the class being initialized.

│__

During class initialization, the class part initialization procedures for the class and all its superclasses are called in superclass-to-subclass order on the class record. These procedures have the responsibility of doing any dynamic initializations necessary to their class’s part of the record. The most common is the resolution of any inherited methods defined in the class. For example, if a widget class C has superclasses Core, Composite, A, and B, the class record for C first is passed to Core ’s class_part_initialize procedure. This resolves any inherited Core methods and compiles the textual representations of the resource list and action table that are defined in the class record. Next, Composite’s class_part_initialize procedure is called to initialize the composite part of C’s class record. Finally, the class_part_initialize procedures for A, B, and C, in that order, are called. For further information, see Section 1.6.9. Classes that do not define any new class fields or that need no extra processing for them can specify NULL in the class_part_initialize field.

All widget classes, whether they have a class initialization procedure or not, must start with their class_inited field False.

The first time a widget of a class is created, XtCreateWidget ensures that the widget class and all superclasses are initialized, in superclass-to-subclass order, by checking each class_inited field and, if it is False, by calling the class_initialize and the class_part_initialize procedures for the class and all its superclasses. The Intrinsics then set the class_inited field to a nonzero value. After the one-time initialization, a class structure is constant.

The following example provides the class initialization procedure for a Label class.

     static void ClassInitialize()
     {

XtSetTypeConverter(XtRString, XtRJustify, CvtStringToJustify,

NULL, 0, XtCacheNone, NULL);

}

1.6.9. Initializing a Widget Class

A class is initialized when the first widget of that class or any subclass is created. To initialize a widget class without creating any widgets, use XtInitializeWidgetClass.

__ │

void XtInitializeWidgetClass(object_class)
      WidgetClass object_class;

object_class Specifies the object class to initialize. May be objectClass or any subclass thereof.

│__

If the specified widget class is already initialized, XtInitializeWidgetClass returns immediately.

If the class initialization procedure registers type converters, these type converters are not available until the first object of the class or subclass is created or XtInitializeWidgetClass is called (see Section 9.6).

1.6.10. Inheritance of Superclass Operations

A widget class is free to use any of its superclass’s self-contained operations rather than implementing its own code. The most frequently inherited operations are

expose

realize

insert_child

delete_child

geometry_manager

set_values_almost

To inherit an operation xyz, specify the constant XtInheritXyz in your class record.

Every class that declares a new procedure in its widget class part must provide for inheriting the procedure in its class_part_initialize procedure. The chained operations declared in Core and Constraint records are never inherited. Widget classes that do nothing beyond what their superclass does specify NULL for chained procedures in their class records.

Inheriting works by comparing the value of the field with a known, special value and by copying in the superclass’s value for that field if a match occurs. This special value, called the inheritance constant, is usually the Intrinsics internal value _XtInherit cast to the appropriate type. _XtInherit is a procedure that issues an error message if it is actually called.

For example, CompositeP.h contains these definitions:

     #define XtInheritGeometryManager ((XtGeometryHandler) _XtInherit)
     #define XtInheritChangeManaged ((XtWidgetProc) _XtInherit)
     #define XtInheritInsertChild ((XtArgsProc) _XtInherit)
     #define XtInheritDeleteChild ((XtWidgetProc) _XtInherit)

Composite’s class_part_initialize procedure begins as follows:

     static void CompositeClassPartInitialize(widgetClass)

WidgetClass widgetClass;

{

CompositeWidgetClass wc = (CompositeWidgetClass)widgetClass;
CompositeWidgetClass super = (CompositeWidgetClass)wc->core_class.superclass;

if (wc->composite_class.geometry_manager == XtInheritGeometryManager) {
wc->composite_class.geometry_manager = super->composite_class.geometry_manager;
}

if (wc->composite_class.change_managed == XtInheritChangeManaged) {
wc->composite_class.change_managed = super->composite_class.change_managed;
}
.
.
.

Nonprocedure fields may be inherited in the same manner as procedure fields. The class may declare any reserved value it wishes for the inheritance constant for its new fields. The following inheritance constants are defined:

For Object:

XtInheritAllocate

XtInheritDeallocate

For Core:

XtInheritRealize

XtInheritResize

XtInheritExpose

XtInheritSetValuesAlmost

XtInheritAcceptFocus

XtInheritQueryGeometry

XtInheritTranslations

XtInheritDisplayAccelerator

For Composite:

XtInheritGeometryManager

XtInheritChangeManaged

XtInheritInsertChild

XtInheritDeleteChild

For Shell:

XtInheritRootGeometryManager

1.6.11. Invocation of Superclass Operations

A widget sometimes needs to call a superclass operation that is not chained. For example, a widget’s expose procedure might call its superclass’s expose and then perform a little more work on its own. For example, a Composite class with predefined managed children can implement insert_child by first calling its superclass’s insert_child and then calling XtManageChild to add the child to the managed set.

Note

A class method should not use XtSuperclass but should instead call the class method of its own specific superclass directly through the superclass record. That is, it should use its own class pointers only, not the widget’s class pointers, as the widget’s class may be a subclass of the class whose implementation is being referenced.

This technique is referred to as enveloping the superclass’s operation.

1.6.12. Class Extension Records

It may be necessary at times to add new fields to already existing widget class structures. To permit this to be done without requiring recompilation of all subclasses, the last field in a class part structure should be an extension pointer. If no extension fields for a class have yet been defined, subclasses should initialize the value of the extension pointer to NULL.

If extension fields exist, as is the case with the Composite, Constraint, and Shell classes, subclasses can provide values for these fields by setting the extension pointer for the appropriate part in their class structure to point to a statically declared extension record containing the additional fields. Setting the extension field is never mandatory; code that uses fields in the extension record must always check the extension field and take 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;

};

next_extension Specifies the next record in the list, or NULL.

record_type

Specifies the particular structure declaration to which each extension record instance conforms.

version

Specifies a version id symbolic constant supplied by the definer of the structure.

record_size

Specifies the total number of bytes allocated for the extension record.

│__

The record_type field identifies the contents of the extension record and is used by the definer of the record to locate its particular extension record in the list. The record_type field is normally assigned the result of XrmStringToQuark for a registered string constant. The Intrinsics reserve all record type strings beginning with the two characters ‘‘XT’’ for future standard uses. The value NULLQUARK may also be used by the class part owner in extension records attached to its own class part extension field to identify the extension record unique to that particular class.

The version field is an owner-defined constant that may be used to identify binary files that have been compiled with alternate definitions of the remainder of the extension record data structure. The private header file for a widget class should provide a symbolic constant for subclasses to use to initialize this field. The record_size field value includes the four common header fields and should normally be initialized with sizeof().

Any value stored in the class part extension fields of CompositeClassPart, ConstraintClassPart, or ShellClassPart must point to an extension record conforming to this definition.

The Intrinsics provide a utility function for widget writers to locate a particular class extension record in a linked list, given a widget class and the offset of the extension field in the class record.

To locate a class extension record, use XtGetClassExtension.

__ │

XtPointer XtGetClassExtension(object_class, byte_offset, type, version, record_size)
      WidgetClass object_class;
      Cardinal byte_offset;
      XrmQuark type;
      long version;
      Cardinal record_size;

object_class Specifies the object class containing the extension list to be searched.

byte_offset Specifies the offset in bytes from the base of the class record of the extension field to be searched.

type

Specifies the record_type of the class extension to be located.

version

Specifies the minimum acceptable version of the class extension required for a match.

record_size Specifies the minimum acceptable length of the class extension record required for a match, or 0.

│__

The list of extension records at the specified offset in the specified object class will be searched for a match on the specified type, a version greater than or equal to the specified version, and a record size greater than or equal the specified record_size if it is nonzero. XtGetClassExtension returns a pointer to a matching extension record or NULL if no match is found. The returned extension record must not be modified or freed by the caller if the caller is not the extension owner.

1

X Toolkit Intrinsics X11 Release 6.4

Chapter 2

Widget Instantiation

A hierarchy of widget instances constitutes a widget tree. The shell widget returned by XtAppCreateShell is the root of the widget tree instance. The widgets with one or more children are the intermediate nodes of that tree, and the widgets with no children of any kind are the leaves of the widget tree. With the exception of pop-up children (see Chapter 5), this widget tree instance defines the associated X Window tree.

Widgets can be either composite or primitive. Both kinds of widgets can contain children, but the Intrinsics provide a set of management mechanisms for constructing and interfacing between composite widgets, their children, and other clients.

Composite widgets, that is, members of the class compositeWidgetClass, are containers for an arbitrary, but widget implementation-defined, collection of children, which may be instantiated by the composite widget itself, by other clients, or by a combination of the two. Composite widgets also contain methods for managing the geometry (layout) of any child widget. Under unusual circumstances, a composite widget may have zero children, but it usually has at least one. By contrast, primitive widgets that contain children typically instantiate specific children of known classes themselves and do not expect external clients to do so. Primitive widgets also do not have general geometry management methods.

In addition, the Intrinsics recursively perform many operations (for example, realization and destruction) on composite widgets and all their children. Primitive widgets that have children must be prepared to perform the recursive operations themselves on behalf of their children.

A widget tree is manipulated by several Intrinsics functions. For example, XtRealizeWidget traverses the tree downward and recursively realizes all pop-up widgets and children of composite widgets. XtDestroyWidget traverses the tree downward and destroys all pop-up widgets and children of composite widgets. The functions that fetch and modify resources traverse the tree upward and determine the inheritance of resources from a widget’s ancestors. XtMakeGeometryRequest traverses the tree up one level and calls the geometry manager that is responsible for a widget child’s geometry.

To facilitate upward traversal of the widget tree, each widget has a pointer to its parent widget. The Shell widget that XtAppCreateShell returns has a parent pointer of NULL.

To facilitate downward traversal of the widget tree, the children field of each composite widget is a pointer to an array of child widgets, which includes all normal children created, not just the subset of children that are managed by the composite widget’s geometry manager. Primitive widgets that instantiate children are entirely responsible for all operations that require downward traversal below themselves. In addition, every widget has a pointer to an array of pop-up children.

2.1. Initializing the X Toolkit

Before an application can call any Intrinsics function other than XtSetLanguageProc and XtToolkitThreadInitialize, it must initialize the Intrinsics by using

XtToolkitInitialize, which initializes the Intrinsics internals

XtCreateApplicationContext, which initializes the per-application state

XtDisplayInitialize or XtOpenDisplay, which initializes the per-display state

XtAppCreateShell, which creates the root of a widget tree

Or an application can call the convenience procedure XtOpenApplication, which combines the functions of the preceding procedures. An application wishing to use the ANSI C locale mechanism should call XtSetLanguageProc prior to calling XtDisplayInitialize, XtOpenDisplay, XtOpenApplication, or XtAppInitialize.

Multiple instances of X Toolkit applications may be implemented in a single address space. Each instance needs to be able to read input and dispatch events independently of any other instance. Further, an application instance may need multiple display connections to have widgets on multiple displays. From the application’s point of view, multiple display connections usually are treated together as a single unit for purposes of event dispatching. To accommodate both requirements, the Intrinsics define application contexts, each of which provides the information needed to distinguish one application instance from another. The major component of an application context is a list of one or more X Display pointers for that application. The Intrinsics handle all display connections within a single application context simultaneously, handling input in a round-robin fashion. The application context type XtAppContext is opaque to clients.

To initialize the Intrinsics internals, use XtToolkitInitialize.

__ │

void XtToolkitInitialize()

│__

If XtToolkitInitialize was previously called, it returns immediately. When XtToolkitThreadInitialize is called before XtToolkitInitialize, the latter is protected against simultaneous activation by multiple threads.

To create an application context, use XtCreateApplicationContext.

__ │

XtAppContext XtCreateApplicationContext()

│__

The XtCreateApplicationContext function returns an application context, which is an opaque type. Every application must have at least one application context.

To destroy an application context and close any remaining display connections in it, use XtDestroyApplicationContext.

__ │

void XtDestroyApplicationContext(app_context)
      XtAppContext app_context;

app_context Specifies the application context.

│__

The XtDestroyApplicationContext function destroys the specified application context. If called from within an event dispatch (for example, in a callback procedure), XtDestroyApplicationContext does not destroy the application context until the dispatch is complete.

To get the application context in which a given widget was created, use XtWidgetToApplicationContext.

__ │

XtAppContext XtWidgetToApplicationContext(w)
      Widget w;

w

Specifies the widget for which you want the application context. Must be of class Object or any subclass thereof.

│__

The XtWidgetToApplicationContext function returns the application context for the specified widget.

To initialize a display and add it to an application context, use XtDisplayInitialize.

__ │

void XtDisplayInitialize(app_context, display, application_name, application_class,
                       options, num_options, argc, argv)
      XtAppContext app_context;
      Display *display;
      String application_name;
      String application_class;
      XrmOptionDescRec *options;
      Cardinal num_options;
      int *argc;
      String *argv;

app_context

Specifies the application context.

display

Specifies a previously opened display connection. Note that a single display connection can be in at most one application context.

application_name Specifies the name of the application instance.

application_class Specifies the class name of this application, which is usually the generic name for all instances of this application.

options

Specifies how to parse the command line for any application-specific resources. The options argument is passed as a parameter to XrmParseCommand. For further information, see Section 15.9 in Xlib — C Language X Interface and Section 2.4 of this specification.

num_options

Specifies the number of entries in the options list.

argc

Specifies a pointer to the number of command line parameters.

argv

Specifies the list of command line parameters.

│__

The XtDisplayInitialize function retrieves the language string to be used for the specified display (see Section 11.11), calls the language procedure (if set) with that language string, builds the resource database for the default screen, calls the Xlib XrmParseCommand function to parse the command line, and performs other per-display initialization. After XrmParseCommand has been called, argc and argv contain only those parameters that were not in the standard option table or in the table specified by the options argument. If the modified argc is not zero, most applications simply print out the modified argv along with a message listing the allowable options. On POSIX-based systems, the application name is usually the final component of argv[0]. If the synchronous resource is True, XtDisplayInitialize calls the Xlib XSynchronize function to put Xlib into synchronous mode for this display connection and any others currently open in the application context. See Sections 2.3 and 2.4 for details on the application_name, application_class, options, and num_options arguments.

XtDisplayInitialize calls XrmSetDatabase to associate the resource database of the default screen with the display before returning.

To open a display, initialize it, and then add it to an application context, use XtOpenDisplay.

__ │

Display *XtOpenDisplay(app_context, display_string, application_name, application_class,
                       options, num_options, argc, argv)
       XtAppContext app_context;
       String display_string;
       String application_name;
       String application_class;
       XrmOptionDescRec *options;
       Cardinal num_options;
       int *argc;
       String *argv;

app_context

Specifies the application context.

display_string Specifies the display string, or NULL.

application_name Specifies the name of the application instance, or NULL.

application_class Specifies the class name of this application, which is usually the generic name for all instances of this application.

options

Specifies how to parse the command line for any application-specific resources. The options argument is passed as a parameter to XrmParseCommand.

num_options

Specifies the number of entries in the options list.

argc

Specifies a pointer to the number of command line parameters.

argv

Specifies the list of command line parameters.

│__

The XtOpenDisplay function calls XOpenDisplay with the specified display_string. If display_string is NULL, XtOpenDisplay uses the current value of the −display option specified in argv. If no display is specified in argv, the user’s default display is retrieved from the environment. On POSIX-based systems, this is the value of the DISPLAY environment variable.

If this succeeds, XtOpenDisplay then calls XtDisplayInitialize and passes it the opened display and the value of the −name option specified in argv as the application name. If no −name option is specified and application_name is non-NULL, application_name is passed to XtDisplayInitialize. If application_name is NULL and if the environment variable RESOURCE_NAME is set, the value of RESOURCE_NAME is used. Otherwise, the application name is the name used to invoke the program. On implementations that conform to ANSI C Hosted Environment support, the application name will be argv[0] less any directory and file type components, that is, the final component of argv[0], if specified. If argv[0] does not exist or is the empty string, the application name is ‘‘main’’. XtOpenDisplay returns the newly opened display or NULL if it failed.

See Section 7.12 for information regarding the use of XtOpenDisplay in multiple threads.

To close a display and remove it from an application context, use XtCloseDisplay.

__ │

void XtCloseDisplay(display)
      Display *display;

display

Specifies the display.

│__

The XtCloseDisplay function calls XCloseDisplay with the specified display as soon as it is safe to do so. If called from within an event dispatch (for example, a callback procedure), XtCloseDisplay does not close the display until the dispatch is complete. Note that applications need only call XtCloseDisplay if they are to continue executing after closing the display; otherwise, they should call XtDestroyApplicationContext.

See Section 7.12 for information regarding the use of XtCloseDisplay in multiple threads.

2.2. Establishing the Locale

Resource databases are specified to be created in the current process locale. During display initialization prior to creating the per-screen resource database, the Intrinsics will call out to a specified application procedure to set the locale according to options found on the command line or in the per-display resource specifications.

The callout procedure provided by the application is of type XtLanguageProc.

__ │

typedef String (*XtLanguageProc)(Display*, String, XtPointer);
      Display *display;
      String language;
      XtPointer client_data;

display

Passes the display.

language

Passes the initial language value obtained from the command line or server per-display resource specifications.

client_data Passes the additional client data specified in the call to XtSetLanguageProc.

│__

The language procedure allows an application to set the locale to the value of the language resource determined by XtDisplayInitialize. The function returns a new language string that will be subsequently used by XtDisplayInitialize to establish the path for loading resource files. The returned string will be copied by the Intrinsics into new memory.

Initially, no language procedure is set by the Intrinsics. To set the language procedure for use by XtDisplayInitialize, use XtSetLanguageProc.

__ │

XtLanguageProc XtSetLanguageProc(app_context, proc, client_data)
      XtAppContext app_context;
      XtLanguageProc proc;
      XtPointer client_data;

app_context Specifies the application context in which the language procedure is to be used, or NULL.

proc

Specifies the language procedure.

client_data Specifies additional client data to be passed to the language procedure when it is called.

│__

XtSetLanguageProc sets the language procedure that will be called from XtDisplayInitialize for all subsequent Displays initialized in the specified application context. If app_context is NULL, the specified language procedure is registered in all application contexts created by the calling process, including any future application contexts that may be created. If proc is NULL, a default language procedure is registered. XtSetLanguageProc returns the previously registered language procedure. If a language procedure has not yet been registered, the return value is unspecified, but if this return value is used in a subsequent call to XtSetLanguageProc, it will cause the default language procedure to be registered.

The default language procedure does the following:

Sets the locale according to the environment. On ANSI C-based systems this is done by calling setlocale( LC_ALL, language ). If an error is encountered, a warning message is issued with XtWarning.

Calls XSupportsLocale to verify that the current locale is supported. If the locale is not supported, a warning message is issued with XtWarning and the locale is set to ‘‘C’’.

Calls XSetLocaleModifiers specifying the empty string.

Returns the value of the current locale. On ANSI C-based systems this is the return value from a final call to setlocale( LC_ALL, NULL ).

A client wishing to use this mechanism to establish locale can do so by calling XtSetLanguageProc prior to XtDisplayInitialize, as in the following example.

     Widget top;

XtSetLanguageProc(NULL, NULL, NULL);

top = XtOpenApplication(...);

...

2.3. Loading the Resource Database

The XtDisplayInitialize function first determines the language string to be used for the specified display. It then creates a resource database for the default screen of the display by combining the following sources in order, with the entries in the first named source having highest precedence:

Application command line (argc, argv).

Per-host user environment resource file on the local host.

Per-screen resource specifications from the server.

Per-display resource specifications from the server or from

the user preference file on the local host.

Application-specific user resource file on the local host.

Application-specific class resource file on the local host.

When the resource database for a particular screen on the display is needed (either internally, or when XtScreenDatabase is called), it is created in the following manner using the sources listed above in the same order:

A temporary database, the ‘‘server resource database’’, is created from the string returned by XResourceManagerString or, if XResourceManagerString returns NULL, the contents of a resource file in the user’s home directory. On POSIX-based systems, the usual name for this user preference resource file is $HOME/.Xdefaults.

If a language procedure has been set, XtDisplayInitialize first searches the command line for the option ‘‘-xnlLanguage’’, or for a -xrm option that specifies the xnlLanguage/XnlLanguage resource, as specified by Section 2.4. If such a resource is found, the value is assumed to be entirely in XPCS, the X Portable Character Set. If neither option is specified on the command line, XtDisplayInitialize queries the server resource database (which is assumed to be entirely in XPCS) for the resource name.xnlLanguage, class Class.XnlLanguage where name and Class are the application_name and application_class specified to XtDisplayInitialize. The language procedure is then invoked with the resource value if found, else the empty string. The string returned from the language procedure is saved for all future references in the Intrinsics that require the per-display language string.

The screen resource database is initialized by parsing the command line in the manner specified by Section 2.4.

If a language procedure has not been set, the initial database is then queried for the resource name.xnlLanguage, class Class.XnlLanguage as specified above. If this database query fails, the server resource database is queried; if this query also fails, the language is determined from the environment; on POSIX-based systems, this is done by retrieving the value of the LANG environment variable. If no language string is found, the empty string is used. This language string is saved for all future references in the Intrinsics that require the per-display language string.

After determining the language string, the user’s environment resource file is then merged into the initial resource database if the file exists. This file is user-, host-, and process-specific and is expected to contain user preferences that are to override those specifications in the per-display and per-screen resources. On POSIX-based systems, the user’s environment resource file name is specified by the value of the XENVIRONMENT environment variable. If this environment variable does not exist, the user’s home directory is searched for a file named .Xdefaults-host, where host is the host name of the machine on which the application is running.

The per-screen resource specifications are then merged into the screen resource database, if they exist. These specifications are the string returned by XScreenResourceString for the respective screen and are owned entirely by the user.

Next, the server resource database created earlier is merged into the screen resource database. The server property, and corresponding user preference file, are owned and constructed entirely by the user.

The application-specific user resource file from the local host is then merged into the screen resource database. This file contains user customizations and is stored in a directory owned by the user. Either the user or the application or both can store resource specifications in the file. Each should be prepared to find and respect entries made by the other. The file name is found by calling XrmSetDatabase with the current screen resource database, after preserving the original display-associated database, then calling XtResolvePathname with the parameters (display, NULL, NULL, NULL, path, NULL, 0, NULL), where path is defined in an operating-system-specific way. On POSIX-based systems, path is defined to be the value of the environment variable XUSERFILESEARCHPATH if this is defined. If XUSERFILESEARCHPATH is not defined, an implementation-dependent default value is used. This default value is constrained in the following manner:

If the environment variable XAPPLRESDIR is not defined, the default XUSERFILESEARCHPATH must contain at least six entries. These entries must contain $HOME as the directory prefix, plus the following substitutions:

1. %C, %N, %L or %C, %N, %l, %t, %c

2.

%C, %N, %l

3.

%C, %N

4.

%N, %L

or

%N, %l, %t, %c

5.

%N, %l

6.

%N

The order of these six entries within the path must be as given above. The order and use of substitutions within a given entry are implementation-dependent.

If XAPPLRESDIR is defined, the default XUSERFILESEARCHPATH must contain at least seven entries. These entries must contain the following directory prefixes and substitutions:

1. $XAPPLRESDIR with %C, %N, %L or %C, %N, %l, %t, %c

2.

$XAPPLRESDIR

with

%C, %N, %l

3.

$XAPPLRESDIR

with

%C, %N

4.

$XAPPLRESDIR

with

%N, %L

or

%N, %l, %t, %c

5.

$XAPPLRESDIR

with

%N, %l

6.

$XAPPLRESDIR

with

%N

7.

$HOME

with

%N

The order of these seven entries within the path must be as given above. The order and use of substitutions within a given entry are implementation-dependent.

Last, the application-specific class resource file from the local host is merged into the screen resource database. This file is owned by the application and is usually installed in a system directory when the application is installed. It may contain sitewide customizations specified by the system manager. The name of the application class resource file is found by calling XtResolvePathname with the parameters (display, ‘‘app-defaults’’, NULL, NULL, NULL, NULL, 0, NULL). This file is expected to be provided by the developer of the application and may be required for the application to function properly. A simple application that wants to be assured of having a minimal set of resources in the absence of its class resource file can declare fallback resource specifications with XtAppSetFallbackResources. Note that the customization substitution string is retrieved dynamically by XtResolvePathname so that the resolved file name of the application class resource file can be affected by any of the earlier sources for the screen resource database, even though the contents of the class resource file have lowest precedence. After calling XtResolvePathname, the original display-associated database is restored.

To obtain the resource database for a particular screen, use XtScreenDatabase.

__ │

XrmDatabase XtScreenDatabase(screen)
      Screen *screen;

screen

Specifies the screen whose resource database is to be returned.

│__

The XtScreenDatabase function returns the fully merged resource database as specified above, associated with the specified screen. If the specified screen does not belong to a Display initialized by XtDisplayInitialize, the results are undefined.

To obtain the default resource database associated with a particular display, use XtDatabase.

__ │

XrmDatabase XtDatabase(display)
      Display *display;

display

Specifies the display.

│__

The XtDatabase function is equivalent to XrmGetDatabase. It returns the database associated with the specified display, or NULL if a database has not been set.

To specify a default set of resource values that will be used to initialize the resource database if no application-specific class resource file is found (the last of the six sources listed above), use XtAppSetFallbackResources.

__ │

void XtAppSetFallbackResources(app_context, specification_list)
      XtAppContext app_context;
      String *specification_list;

app_context

Specifies the application context in which the fallback specifications will be used.

specification_list Specifies a NULL-terminated list of resource specifications to preload the database, or NULL.

│__

Each entry in specification_list points to a string in the format of XrmPutLineResource. Following a call to XtAppSetFallbackResources, when a resource database is being created for a particular screen and the Intrinsics are not able to find or read an application-specific class resource file according to the rules given above and if specification_list is not NULL, the resource specifications in specification_list will be merged into the screen resource database in place of the application-specific class resource file. XtAppSetFallbackResources is not required to copy specification_list; the caller must ensure that the contents of the list and of the strings addressed by the list remain valid until all displays are initialized or until XtAppSetFallbackResources is called again. The value NULL for specification_list removes any previous fallback resource specification for the application context. The intended use for fallback resources is to provide a minimal number of resources that will make the application usable (or at least terminate with helpful diagnostic messages) when some problem exists in finding and loading the application defaults file.

2.4. Parsing the Command Line

The XtOpenDisplay function first parses the command line for the following options:

−display

Specifies the display name for XOpenDisplay.

−name

Sets the resource name prefix, which overrides the application name passed to XtOpenDisplay.

−xnllanguage

Specifies the initial language string for establishing locale and for finding application class resource files.

XtDisplayInitialize has a table of standard command line options that are passed to XrmParseCommand for adding resources to the resource database, and it takes as a parameter additional application-specific resource abbreviations. The format of this table is described in Section 15.9 in Xlib — C Language X Interface.

__ │

typedef enum {

XrmoptionNoArg,

/* Value is specified in OptionDescRec.value */

XrmoptionIsArg,

/* Value is the option string itself */

XrmoptionStickyArg,

/* Value is characters immediately following option */

XrmoptionSepArg,

/* Value is next argument in argv */

XrmoptionResArg,

/* Use the next argument as input to XrmPutLineResource*/

XrmoptionSkipArg,

/* Ignore this option and the next argument in argv */

XrmoptionSkipNArgs,

/* Ignore this option and the next */

/* OptionDescRec.value arguments in argv */

XrmoptionSkipLine

/* Ignore this option and the rest of argv */

} XrmOptionKind;

typedef struct {

char *option;

/* Option name in argv */

char *specifier;

/* Resource name (without application name) */

XrmOptionKind argKind;/* Location of the resource value */

XPointer value;

/* Value to provide if XrmoptionNoArg */

} XrmOptionDescRec, *XrmOptionDescList;

│__

The standard table contains the following entries:

Note that any unique abbreviation for an option name in the standard table or in the application table is accepted.

If reverseVideo is True, the values of XtDefaultForeground and XtDefaultBackground are exchanged for all screens on the Display.

The value of the synchronous resource specifies whether or not Xlib is put into synchronous mode. If a value is found in the resource database during display initialization, XtDisplayInitialize makes a call to XSynchronize for all display connections currently open in the application context. Therefore, when multiple displays are initialized in the same application context, the most recent value specified for the synchronous resource is used for all displays in the application context.

The value of the selectionTimeout resource applies to all displays opened in the same application context. When multiple displays are initialized in the same application context, the most recent value specified is used for all displays in the application context.

The −xrm option provides a method of setting any resource in an application. The next argument should be a quoted string identical in format to a line in the user resource file. For example, to give a red background to all command buttons in an application named xmh, you can start it up as

     xmh −xrm ’xmh*Command.background: red’

When it parses the command line, XtDisplayInitialize merges the application option table with the standard option table before calling the Xlib XrmParseCommand function. An entry in the application table with the same name as an entry in the standard table overrides the standard table entry. If an option name is a prefix of another option name, both names are kept in the merged table. The Intrinsics reserve all option names beginning with the characters ‘‘-xt’’ for future standard uses.

2.5. Creating Widgets

The creation of widget instances is a three-phase process:

1.

The widgets are allocated and initialized with resources and are optionally added to the managed subset of their parent.

2.

All composite widgets are notified of their managed children in a bottom-up traversal of the widget tree.

3.

The widgets create X windows, which then are mapped.

To start the first phase, the application calls XtCreateWidget for all its widgets and adds some (usually, most or all) of its widgets to their respective parents’ managed set by calling XtManageChild. To avoid an O(n 2 ) creation process where each composite widget lays itself out each time a widget is created and managed, parent widgets are not notified of changes in their managed set during this phase.

After all widgets have been created, the application calls XtRealizeWidget with the top-level widget to execute the second and third phases. XtRealizeWidget first recursively traverses the widget tree in a postorder (bottom-up) traversal and then notifies each composite widget with one or more managed children by means of its change_managed procedure.

Notifying a parent about its managed set involves geometry layout and possibly geometry negotiation. A parent deals with constraints on its size imposed from above (for example, when a user specifies the application window size) and suggestions made from below (for example, when a primitive child computes its preferred size). One difference between the two can cause geometry changes to ripple in both directions through the widget tree. The parent may force some of its children to change size and position and may issue geometry requests to its own parent in order to better accommodate all its children. You cannot predict where anything will go on the screen until this process finishes.

Consequently, in the first and second phases, no X windows are actually created, because it is likely that they will get moved around after creation. This avoids unnecessary requests to the X server.

Finally, XtRealizeWidget starts the third phase by making a preorder (top-down) traversal of the widget tree, allocates an X window to each widget by means of its realize procedure, and finally maps the widgets that are managed.

2.5.1. Creating and Merging Argument Lists

Many Intrinsics functions may be passed pairs of resource names and values. These are passed as an arglist, a pointer to an array of Arg structures, which contains

__ │

typedef struct {

String name;

XtArgVal value;

} Arg, *ArgList;

│__

where XtArgVal is as defined in Section 1.5.

If the size of the resource is less than or equal to the size of an XtArgVal, the resource value is stored directly in value; otherwise, a pointer to it is stored in value.

To set values in an ArgList, use XtSetArg.

__ │

void XtSetArg(arg, name, value)
      Arg arg;
      String name;
      XtArgVal value;

arg

Specifies the name/value pair to set.

name

Specifies the name of the resource.

value

Specifies the value of the resource if it will fit in an XtArgVal, else the address.

│__

The XtSetArg function is usually used in a highly stylized manner to minimize the probability of making a mistake; for example:

     Arg args[20];
     int n;

    n = 0;
     XtSetArg(args[n], XtNheight, 100);n++;
     XtSetArg(args[n], XtNwidth, 200);n++;
     XtSetValues(widget, args, n);

Alternatively, an application can statically declare the argument list and use XtNumber:

     static Args args[] = {

{XtNheight, (XtArgVal) 100},
{XtNwidth, (XtArgVal) 200},

};
XtSetValues(Widget, args, XtNumber(args));

Note that you should not use expressions with side effects such as auto-increment or auto-decrement within the first argument to XtSetArg. XtSetArg can be implemented as a macro that evaluates the first argument twice.

To merge two arglist arrays, use XtMergeArgLists.

__ │

ArgList XtMergeArgLists(args1, num_args1, args2, num_args2)
     ArgList args1;
     Cardinal num_args1;
     ArgList args2;
     Cardinal num_args2;

args1

Specifies the first argument list.

num_args1

Specifies the number of entries in the first argument list.

args2

Specifies the second argument list.

num_args2

Specifies the number of entries in the second argument list.

│__

The XtMergeArgLists function allocates enough storage to hold the combined arglist arrays and copies them into it. Note that it does not check for duplicate entries. The length of the returned list is the sum of the lengths of the specified lists. When it is no longer needed, free the returned storage by using XtFree.

All Intrinsics interfaces that require ArgList arguments have analogs conforming to the ANSI C variable argument list (traditionally called ‘‘varargs’’) calling convention. The name of the analog is formed by prefixing ‘‘Va’’ to the name of the corresponding ArgList procedure; e.g., XtVaCreateWidget. Each procedure named XtVasomething takes as its last arguments, in place of the corresponding ArgList/ Cardinal parameters, a variable parameter list of resource name and value pairs where each name is of type String and each value is of type XtArgVal. The end of the list is identified by a name entry containing NULL. Developers writing in the C language wishing to pass resource name and value pairs to any of these interfaces may use the ArgList and varargs forms interchangeably.

Two special names are defined for use only in varargs lists: XtVaTypedArg and XtVaNestedList.

__ │

#define XtVaTypedArg "XtVaTypedArg"


│__

If the name XtVaTypedArg is specified in place of a resource name, then the following four arguments are interpreted as a name/type/value/size tuple where name is of type String, type is of type String, value is of type XtArgVal, and size is of type int. When a varargs list containing XtVaTypedArg is processed, a resource type conversion (see Section 9.6) is performed if necessary to convert the value into the format required by the associated resource. If type is XtRString, then value contains a pointer to the string and size contains the number of bytes allocated, including the trailing null byte. If type is not XtRString, then if size is less than or equal to sizeof(XtArgVal), the value should be the data cast to the type XtArgVal, otherwise value is a pointer to the data. If the type conversion fails for any reason, a warning message is issued and the list entry is skipped.

__ │

#define XtVaNestedList  "XtVaNestedList"


│__

If the name XtVaNestedList is specified in place of a resource name, then the following argument is interpreted as an XtVarArgsList value, which specifies another varargs list that is logically inserted into the original list at the point of declaration. The end of the nested list is identified with a name entry containing NULL. Varargs lists may nest to any depth.

To dynamically allocate a varargs list for use with XtVaNestedList in multiple calls, use XtVaCreateArgsList.

__ │

typedef XtPointer XtVarArgsList;


XtVarArgsList XtVaCreateArgsList(unused, ...)
      XtPointer unused;

unused

This argument is not currently used and must be specified as NULL.

Specifies a variable parameter list of resource name and value pairs.

│__

The XtVaCreateArgsList function allocates memory and copies its arguments into a single list pointer, which may be used with XtVaNestedList. The end of both lists is identified by a name entry containing NULL. Any entries of type XtVaTypedArg are copied as specified without applying conversions. Data passed by reference (including Strings) are not copied, only the pointers themselves; the caller must ensure that the data remain valid for the lifetime of the created varargs list. The list should be freed using XtFree when no longer needed.

Use of resource files and of the resource database is generally encouraged over lengthy arglist or varargs lists whenever possible in order to permit modification without recompilation.

2.5.2. Creating a Widget Instance

To create an instance of a widget, use XtCreateWidget.

__ │

Widget XtCreateWidget(name, object_class, parent, args, num_args)
      String name;
      WidgetClass object_class;
      Widget parent;
      ArgList args;
      Cardinal num_args;

name

Specifies the resource instance name for the created widget, which is used for retrieving resources and, for that reason, should not be the same as any other widget that is a child of the same parent.

object_class Specifies the widget class pointer for the created object. Must be objectClass or any subclass thereof.

parent

Specifies the parent widget. Must be of class Object or any subclass thereof.

args

Specifies the argument list to override any other resource specifications.

num_args

Specifies the number of entries in the argument list.

│__

The XtCreateWidget function performs all the boilerplate operations of widget creation, doing the following in order:

Checks to see if the class_initialize procedure has been called for this class and for all superclasses and, if not, calls those necessary in a superclass-to-subclass order.

If the specified class is not coreWidgetClass or a subclass thereof, and the parent’s class is a subclass of compositeWidgetClass and either no extension record in the parent’s composite class part extension field exists with the record_type NULLQUARK or the accepts_objects field in the extension record is False, XtCreateWidget issues a fatal error; see Section 3.1 and Chapter 12.

If the specified class contains an extension record in the object class part extension field with record_type NULLQUARK and the allocate field is not NULL, the procedure is invoked to allocate memory for the widget instance. If the parent is a member of the class constraintWidgetClass, the procedure also allocates memory for the parent’s constraints and stores the address of this memory into the constraints field. If no allocate procedure is found, the Intrinsics allocate memory for the widget and, when applicable, the constraints, and initializes the constraints field.

Initializes the Core nonresource data fields self, parent, widget_class, being_destroyed, name, managed, window, visible, popup_list, and num_popups.

Initializes the resource fields (for example, background_pixel) by using the CoreClassPart resource lists specified for this class and all superclasses.

If the parent is a member of the class constraintWidgetClass, initializes the resource fields of the constraints record by using the ConstraintClassPart resource lists specified for the parent’s class and all superclasses up to constraintWidgetClass.

Calls the initialize procedures for the widget starting at the Object initialize procedure on down to the widget’s initialize procedure.

If the parent is a member of the class constraintWidgetClass, calls the ConstraintClassPart initialize procedures, starting at constraintWidgetClass on down to the parent’s ConstraintClassPart initialize procedure.

If the parent is a member of the class compositeWidgetClass, puts the widget into its parent’s children list by calling its parent’s insert_child procedure. For further information, see Section 3.1.

To create an instance of a widget using varargs lists, use XtVaCreateWidget.

__ │

Widget XtVaCreateWidget(name, object_class, parent, ...)
      String name;
      WidgetClass object_class;
      Widget parent;

name

Specifies the resource name for the created widget.

object_class Specifies the widget class pointer for the created object. Must be objectClass or any subclass thereof.

parent

Specifies the parent widget. Must be of class Object or any subclass thereof.

Specifies the variable argument list to override any other resource specifications.

│__

The XtVaCreateWidget procedure is identical in function to XtCreateWidget with the args and num_args parameters replaced by a varargs list, as described in Section 2.5.1.

2.5.3. Creating an Application Shell Instance

An application can have multiple top-level widgets, each of which specifies a unique widget tree that can potentially be on different screens or displays. An application uses XtAppCreateShell to create independent widget trees.

__ │

Widget XtAppCreateShell(name, application_class, widget_class, display, args, num_args)
      String name;
      String application_class;
      WidgetClass widget_class;
      Display *display;
      ArgList args;
      Cardinal num_args;

name

Specifies the instance name of the shell widget. If name is NULL, the application name passed to XtDisplayInitialize is used.

application_class Specifies the resource class string to be used in place of the widget class_name string when widget_class is applicationShellWidgetClass or a subclass thereof.

widget_class Specifies the widget class for the top-level widget (e.g., applicationShellWidgetClass).

display

Specifies the display for the default screen and for the resource database used to retrieve the shell widget resources.

args

Specifies the argument list to override any other resource specifications.

num_args

Specifies the number of entries in the argument list.

│__

The XtAppCreateShell function creates a new shell widget instance as the root of a widget tree. The screen resource for this widget is determined by first scanning args for the XtNscreen argument. If no XtNscreen argument is found, the resource database associated with the default screen of the specified display is queried for the resource name.screen, class Class.Screen where Class is the specified application_class if widget_class is applicationShellWidgetClass or a subclass thereof. If widget_class is not applicationShellWidgetClass or a subclass, Class is the class_name field from the CoreClassPart of the specified widget_class. If this query fails, the default screen of the specified display is used. Once the screen is determined, the resource database associated with that screen is used to retrieve all remaining resources for the shell widget not specified in args. The widget name and Class as determined above are used as the leftmost (i.e., root) components in all fully qualified resource names for objects within this widget tree.

If the specified widget class is a subclass of WMShell, the name and Class as determined above will be stored into the WM_CLASS property on the widget’s window when it becomes realized. If the specified widget_class is applicationShellWidgetClass or a subclass thereof, the WM_COMMAND property will also be set from the values of the XtNargv and XtNargc resources.

To create multiple top-level shells within a single (logical) application, you can use one of two methods:

Designate one shell as the real top-level shell and create the others as pop-up children of it by using XtCreatePopupShell.

Have all shells as pop-up children of an unrealized top-level shell.

The first method, which is best used when there is a clear choice for what is the main window, leads to resource specifications like the following:

     xmail.geometry:...  (the main window)
     xmail.read.geometry:...(the read window)
     xmail.compose.geometry:...(the compose window)

The second method, which is best if there is no main window, leads to resource specifications like the following:

     xmail.headers.geometry:...(the headers window)
     xmail.read.geometry:...(the read window)
     xmail.compose.geometry:...(the compose window)

To create a top-level widget that is the root of a widget tree using varargs lists, use XtVaAppCreateShell.

__ │

Widget XtVaAppCreateShell(name, application_class, widget_class, display, ...)
    String name;
    String application_class;
    WidgetClass widget_class;
    Display *display;

name

Specifies the instance name of the shell widget. If name is NULL, the application name passed to XtDisplayInitialize is used.

application_class Specifies the resource class string to be used in place of the widget class_name string when widget_class is applicationShellWidgetClass or a subclass thereof.

widget_class

Specifies the widget class for the top-level widget.

display

Specifies the display for the default screen and for the resource database used to retrieve the shell widget resources.

Specifies the variable argument list to override any other resource specifications.

│__

The XtVaAppCreateShell procedure is identical in function to XtAppCreateShell with the args and num_args parameters replaced by a varargs list, as described in Section 2.5.1.

2.5.4. Convenience Procedure to Initialize an Application

To initialize the Intrinsics internals, create an application context, open and initialize a display, and create the initial root shell instance, an application may use XtOpenApplication or XtVaOpenApplication.

__ │

Widget XtOpenApplication(app_context_return, application_class, options, num_options,
                       argc_in_out, argv_in_out, fallback_resources, widget_class, args, num_args)
      XtAppContext *app_context_return;
      String application_class;
      XrmOptionDescList options;
      Cardinal num_options;
      int *argc_in_out;
      String *argv_in_out;
      String *fallback_resources;
      WidgetClass widget_class;
      ArgList args;
      Cardinal num_args;

app_context_return Returns the application context, if non-NULL.

application_class Specifies the class name of the application.

options

Specifies the command line options table.

num_options

Specifies the number of entries in options.

argc_in_out

Specifies a pointer to the number of command line arguments.

argv_in_out

Specifies a pointer to the command line arguments.

fallback_resources Specifies resource values to be used if the application class resource file cannot be opened or read, or NULL.

widget_class

Specifies the class of the widget to be created. Must be shellWidgetClass or a subclass.

args

Specifies the argument list to override any other resource specifications for the created shell widget.

num_args

Specifies the number of entries in the argument list.

│__

The XtOpenApplication function calls XtToolkitInitialize followed by XtCreateApplicationContext, then calls XtOpenDisplay with display_string NULL and application_name NULL, and finally calls XtAppCreateShell with name NULL, the specified widget_class, an argument list and count, and returns the created shell. The recommended widget_class is sessionShellWidgetClass. The argument list and count are created by merging the specified args and num_args with a list containing the specified argc and argv. The modified argc and argv returned by XtDisplayInitialize are returned in argc_in_out and argv_in_out. If app_context_return is not NULL, the created application context is also returned. If the display specified by the command line cannot be opened, an error message is issued and XtOpenApplication terminates the application. If fallback_resources is non-NULL, XtAppSetFallbackResources is called with the value prior to calling XtOpenDisplay.

__ │

Widget XtVaOpenApplication(app_context_return, application_class, options, num_options,
                         argc_in_out, argv_in_out, fallback_resources, widget_class, ...)
    XtAppContext *app_context_return;
    String application_class;
    XrmOptionDescList options;
    Cardinal num_options;
    int *argc_in_out;
    String *argv_in_out;
    String *fallback_resources;
    WidgetClass widget_class;

app_context_return Returns the application context, if non-NULL.

application_class Specifies the class name of the application.

options

Specifies the command line options table.

num_options

Specifies the number of entries in options.

argc_in_out

Specifies a pointer to the number of command line arguments.

argv_in_out

Specifies the command line arguments array.

fallback_resources Specifies resource values to be used if the application class resource file cannot be opened, or NULL.

widget_class

Specifies the class of the widget to be created. Must be shellWidgetClass or a subclass.

Specifies the variable argument list to override any other resource specifications for the created shell.

│__

The XtVaOpenApplication procedure is identical in function to XtOpenApplication with the args and num_args parameters replaced by a varargs list, as described in Section 2.5.1.

2.5.5. Widget Instance Allocation: The allocate Procedure

A widget class may optionally provide an instance allocation procedure in the ObjectClassExtension record.

When the call to create a widget includes a varargs list containing XtVaTypedArg, these arguments will be passed to the allocation procedure in an XtTypedArgList.

__ │

typedef struct {

String name;

String type;

XtArgVal value;

int size;

} XtTypedArg, *XtTypedArgList;

│__

The allocate procedure pointer in the ObjectClassExtension record is of type XtAllocateProc.

__ │

typedef void (*XtAllocateProc)(WidgetClass, Cardinal*, Cardinal*, ArgList, Cardinal*,
                                            XtTypedArgList, Cardinal*, Widget*, XtPointer*);
      WidgetClass widget_class;
      Cardinal* constraint_size;
      Cardinal* more_bytes;
      ArgList args;
      Cardinal* num_args;
      XtTypedArgList typed_args,
      Cardinal* num_typed_args;
      Widget* new_return;
      XtPointer* more_bytes_return;

widget_class

Specifies the widget class of the instance to allocate.

constraint_size Specifies the size of the constraint record to allocate, or 0.

more_bytes

Specifies the number of auxiliary bytes of memory to allocate.

args

Specifies the argument list as given in the call to create the widget.

num_args

Specifies the number of arguments.

typed_args

Specifies the list of typed arguments given in the call to create the widget.

num_typed_args

Specifies the number of typed arguments.

new_return

Returns a pointer to the newly allocated instance, or NULL in case of error.

more_bytes_return Returns the auxiliary memory if it was requested, or NULL if requested and an error occurred; otherwise, unchanged.

│__

At widget allocation time, if an extension record with record_type equal to NULLQUARK is located through the object class part extension field and the allocate field is not NULL, the XtAllocateProc will be invoked to allocate memory for the widget. If no ObjectClassPart extension record is declared with record_type equal to NULLQUARK, then XtInheritAllocate and XtInheritDeallocate are assumed. If no XtAllocateProc is found, the Intrinsics will allocate memory for the widget.

An XtAllocateProc must perform the following:

Allocate memory for the widget instance and return it in new_return. The memory must be at least wc->core_class.widget_size bytes in length, double-word aligned.

Initialize the core.constraints field in the instance record to NULL or to point to a constraint record. If constraint_size is not 0, the procedure must allocate memory for the constraint record. The memory must be double-word aligned.

If more_bytes is not 0, then the address of a block of memory at least more_bytes in size, double-word aligned, must be returned in the more_bytes_return parameter, or NULL to indicate an error.

A class allocation procedure that envelops the allocation procedure of a superclass must rely on the enveloped procedure to perform the instance and constraint allocation. Allocation procedures should refrain from initializing fields in the widget record except to store pointers to newly allocated additional memory. Under no circumstances should an allocation procedure that envelopes its superclass allocation procedure modify fields in the instance part of any superclass.

2.5.6. Widget Instance Initialization: The initialize Procedure

The initialize procedure pointer in a widget class is of type XtInitProc.

__ │

typedef void (*XtInitProc)(Widget, Widget, ArgList, Cardinal*);
      Widget request;
      Widget new;
      ArgList args;
      Cardinal *num_args;

request

Specifies a copy of the widget with resource values as requested by the argument list, the resource database, and the widget defaults.

new

Specifies the widget with the new values, both resource and nonresource, that are actually allowed.

args

Specifies the argument list passed by the client, for computing derived resource values. If the client created the widget using a varargs form, any resources specified via XtVaTypedArg are converted to the widget representation and the list is transformed into the ArgList format.

num_args

Specifies the number of entries in the argument list.

│__

An initialization procedure performs the following:

Allocates space for and copies any resources referenced by address that the client is allowed to free or modify after the widget has been created. For example, if a widget has a field that is a String, it may choose not to depend on the characters at that address remaining constant but dynamically allocate space for the string and copy it to the new space. Widgets that do not copy one or more resources referenced by address should clearly so state in their user documentation.

Note

It is not necessary to allocate space for or to copy callback lists.

Computes values for unspecified resource fields. For example, if width and height are zero, the widget should compute an appropriate width and height based on its other resources.

Note

A widget may directly assign only its own width and height within the initialize, initialize_hook, set_values, and set_values_hook procedures; see Chapter 6.

Computes values for uninitialized nonresource fields that are derived from resource fields. For example, graphics contexts (GCs) that the widget uses are derived from resources like background, foreground, and font.

An initialization procedure also can check certain fields for internal consistency. For example, it makes no sense to specify a colormap for a depth that does not support that colormap.

Initialization procedures are called in superclass-to-subclass order after all fields specified in the resource lists have been initialized. The initialize procedure does not need to examine args and num_args if all public resources are declared in the resource list. Most of the initialization code for a specific widget class deals with fields defined in that class and not with fields defined in its superclasses.

If a subclass does not need an initialization procedure because it does not need to perform any of the above operations, it can specify NULL for the initialize field in the class record.

Sometimes a subclass may want to overwrite values filled in by its superclass. In particular, size calculations of a superclass often are incorrect for a subclass, and in this case, the subclass must modify or recalculate fields declared and computed by its superclass.

As an example, a subclass can visually surround its superclass display. In this case, the width and height calculated by the superclass initialize procedure are too small and need to be incremented by the size of the surround. The subclass needs to know if its superclass’s size was calculated by the superclass or was specified explicitly. All widgets must place themselves into whatever size is explicitly given, but they should compute a reasonable size if no size is requested.

The request and new arguments provide the necessary information for a subclass to determine the difference between an explicitly specified field and a field computed by a superclass. The request widget is a copy of the widget as initialized by the arglist and resource database. The new widget starts with the values in the request, but it has been updated by all superclass initialization procedures called so far. A subclass initialize procedure can compare these two to resolve any potential conflicts.

In the above example, the subclass with the visual surround can see if the width and height in the request widget are zero. If so, it adds its surround size to the width and height fields in the new widget. If not, it must make do with the size originally specified.

The new widget will become the actual widget instance record. Therefore, the initialization procedure should do all its work on the new widget; the request widget should never be modified. If the initialize procedure needs to call any routines that operate on a widget, it should specify new as the widget instance.

2.5.7. Constraint Instance Initialization: The ConstraintClassPart initialize Procedure

The constraint initialization procedure pointer, found in the ConstraintClassPart initialize field of the widget class record, is of type XtInitProc. The values passed to the parent constraint initialization procedures are the same as those passed to the child’s class widget initialization procedures.

The constraints field of the request widget points to a copy of the constraints record as initialized by the arglist and resource database.

The constraint initialization procedure should compute any constraint fields derived from constraint resources. It can make further changes to the new widget to make the widget and any other constraint fields conform to the specified constraints, for example, changing the widget’s size or position.

If a constraint class does not need a constraint initialization procedure, it can specify NULL for the initialize field of the ConstraintClassPart in the class record.

2.5.8. Nonwidget Data Initialization: The initialize_hook Procedure

Note

The initialize_hook procedure is obsolete, as the same information is now available to the initialize procedure. The procedure has been retained for those widgets that used it in previous releases.

The initialize_hook procedure pointer is of type XtArgsProc:

__ │

typedef void (*XtArgsProc)(Widget, ArgList, Cardinal*);
      Widget w;
      ArgList args;
      Cardinal *num_args;

w

Specifies the widget.

args

Specifies the argument list passed by the client. If the client created the widget using a varargs form, any resources specified via XtVaTypedArg are converted to the widget representation and the list is transformed into the ArgList format.

num_args

Specifies the number of entries in the argument list.

│__

If this procedure is not NULL, it is called immediately after the corresponding initialize procedure or in its place if the initialize field is NULL.

The initialize_hook procedure allows a widget instance to initialize nonresource data using information from the specified argument list as if it were a resource.

2.6. Realizing Widgets

To realize a widget instance, use XtRealizeWidget.

__ │

void XtRealizeWidget(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

If the widget is already realized, XtRealizeWidget simply returns. Otherwise it performs the following:

Binds all action names in the widget’s translation table to procedures (see Section 10.1.2).

Makes a postorder traversal of the widget tree rooted at the specified widget and calls each non-NULL change_managed procedure of all composite widgets that have one or more managed children.

Constructs an XSetWindowAttributes structure filled in with information derived from the Core widget fields and calls the realize procedure for the widget, which adds any widget-specific attributes and creates the X window.

If the widget is not a subclass of compositeWidgetClass, XtRealizeWidget returns; otherwise it continues and performs the following:

Descends recursively to each of the widget’s managed children and calls the realize procedures. Primitive widgets that instantiate children are responsible for realizing those children themselves.

Maps all of the managed children windows that have mapped_when_managed True. If a widget is managed but mapped_when_managed is False, the widget is allocated visual space but is not displayed.

If the widget is a top-level shell widget (that is, it has no parent), and mapped_when_managed is True, XtRealizeWidget maps the widget window.

XtCreateWidget, XtVaCreateWidget, XtRealizeWidget, XtManageChildren, XtUnmanageChildren, XtUnrealizeWidget, XtSetMappedWhenManaged, and XtDestroyWidget maintain the following invariants:

If a composite widget is realized, then all its managed children are realized.

If a composite widget is realized, then all its managed children that have mapped_when_managed True are mapped.

All Intrinsics functions and all widget routines should accept either realized or unrealized widgets. When calling the realize or change_managed procedures for children of a composite widget, XtRealizeWidget calls the procedures in reverse order of appearance in the CompositePart children list. By default, this ordering of the realize procedures will result in the stacking order of any newly created subwindows being top-to-bottom in the order of appearance on the list, and the most recently created child will be at the bottom.

To check whether or not a widget has been realized, use XtIsRealized.

__ │

Boolean XtIsRealized(w)
      Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

The XtIsRealized function returns True if the widget has been realized, that is, if the widget has a nonzero window ID. If the specified object is not a widget, the state of the nearest widget ancestor is returned.

Some widget procedures (for example, set_values) might wish to operate differently after the widget has been realized.

2.6.1. Widget Instance Window Creation: The realize Procedure

The realize procedure pointer in a widget class is of type XtRealizeProc.

__ │

typedef void (*XtRealizeProc)(Widget, XtValueMask*, XSetWindowAttributes*);
      Widget w;
      XtValueMask *value_mask;
      XSetWindowAttributes *attributes;

w

Specifies the widget.

value_mask Specifies which fields in the attributes structure are used.

attributes Specifies the window attributes to use in the XCreateWindow call.

│__

The realize procedure must create the widget’s window.

Before calling the class realize procedure, the generic XtRealizeWidget function fills in a mask and a corresponding XSetWindowAttributes structure. It sets the following fields in attributes and corresponding bits in value_mask based on information in the widget core structure:

The background_pixmap (or background_pixel if background_pixmap is XtUnspecifiedPixmap) is filled in from the corresponding field.

The border_pixmap (or border_pixel if border_pixmap is XtUnspecifiedPixmap) is filled in from the corresponding field.

The colormap is filled in from the corresponding field.

The event_mask is filled in based on the event handlers registered, the event translations specified, whether the expose field is non-NULL, and whether visible_interest is True.

The bit_gravity is set to NorthWestGravity if the expose field is NULL.

These or any other fields in attributes and the corresponding bits in value_mask can be set by the realize procedure.

Note that because realize is not a chained operation, the widget class realize procedure must update the XSetWindowAttributes structure with all the appropriate fields from non-Core superclasses.

A widget class can inherit its realize procedure from its superclass during class initialization. The realize procedure defined for coreWidgetClass calls XtCreateWindow with the passed value_mask and attributes and with window_class and visual set to CopyFromParent. Both compositeWidgetClass and constraintWidgetClass inherit this realize procedure, and most new widget subclasses can do the same (see Section 1.6.10).

The most common noninherited realize procedures set bit_gravity in the mask and attributes to the appropriate value and then create the window. For example, depending on its justification, Label might set bit_gravity to WestGravity, CenterGravity, or EastGravity. Consequently, shrinking it would just move the bits appropriately, and no exposure event is needed for repainting.

If a composite widget’s children should be realized in an order other than that specified (to control the stacking order, for example), it should call XtRealizeWidget on its children itself in the appropriate order from within its own realize procedure.

Widgets that have children and whose class is not a subclass of compositeWidgetClass are responsible for calling XtRealizeWidget on their children, usually from within the realize procedure.

Realize procedures cannot manage or unmanage their descendants.

2.6.2. Window Creation Convenience Routine

Rather than call the Xlib XCreateWindow function explicitly, a realize procedure should normally call the Intrinsics analog XtCreateWindow, which simplifies the creation of windows for widgets.

__ │

void XtCreateWindow(w, window_class, visual, value_mask, attributes)
      Widget w;
      unsigned int window_class;
      Visual *visual;
      XtValueMask value_mask;
      XSetWindowAttributes *attributes;

w

Specifies the widget that defines the additional window attributed. Must be of class Core or any subclass thereof.

window_class Specifies the Xlib window class (for example, InputOutput, InputOnly, or CopyFromParent).

visual

Specifies the visual type (usually CopyFromParent).

value_mask Specifies which fields in the attributes structure are used.

attributes Specifies the window attributes to use in the XCreateWindow call.

│__

The XtCreateWindow function calls the Xlib XCreateWindow function with values from the widget structure and the passed parameters. Then, it assigns the created window to the widget’s window field.

XtCreateWindow evaluates the following fields of the widget core structure: depth, screen, parent->core.window, x, y, width, height, and border_width.

2.7. Obtaining Window Information from a Widget

The Core widget class definition contains the screen and window ids. The window field may be NULL for a while (see Sections 2.5 and 2.6).

The display pointer, the parent widget, screen pointer, and window of a widget are available to the widget writer by means of macros and to the application writer by means of functions.

__ │

Display *XtDisplay(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

XtDisplay returns the display pointer for the specified widget.

__ │

Widget XtParent(w)
     Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

XtParent returns the parent object for the specified widget. The returned object will be of class Object or a subclass.

__ │

Screen *XtScreen(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

XtScreen returns the screen pointer for the specified widget.

__ │

Window XtWindow(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

XtWindow returns the window of the specified widget.

The display pointer, screen pointer, and window of a widget or of the closest widget ancestor of a nonwidget object are available by means of XtDisplayOfObject, XtScreenOfObject, and XtWindowOfObject.

__ │

Display *XtDisplayOfObject(object)
      Widget object;

object

Specifies the object. Must be of class Object or any subclass thereof.

│__

XtDisplayOfObject is identical in function to XtDisplay if the object is a widget; otherwise XtDisplayOfObject returns the display pointer for the nearest ancestor of object that is of class Widget or a subclass thereof.

__ │

Screen *XtScreenOfObject(object)
      Widget object;

object

Specifies the object. Must be of class Object or any subclass thereof.

│__

XtScreenOfObject is identical in function to XtScreen if the object is a widget; otherwise XtScreenOfObject returns the screen pointer for the nearest ancestor of object that is of class Widget or a subclass thereof.

__ │

Window XtWindowOfObject(object)
      Widget object;

object

Specifies the object. Must be of class Object or any subclass thereof.

│__

XtWindowOfObject is identical in function to XtWindow if the object is a widget; otherwise XtWindowOfObject returns the window for the nearest ancestor of object that is of class Widget or a subclass thereof.

To retrieve the instance name of an object, use XtName.

__ │

String XtName(object)
      Widget object;

object

Specifies the object whose name is desired. Must be of class Object or any subclass thereof.

│__

XtName returns a pointer to the instance name of the specified object. The storage is owned by the Intrinsics and must not be modified. The name is not qualified by the names of any of the object’s ancestors.

Several window attributes are locally cached in the widget instance. Thus, they can be set by the resource manager and XtSetValues as well as used by routines that derive structures from these values (for example, depth for deriving pixmaps, background_pixel for deriving GCs, and so on) or in the XtCreateWindow call.

The x, y, width, height, and border_width window attributes are available to geometry managers. These fields are maintained synchronously inside the Intrinsics. When an XConfigureWindow is issued by the Intrinsics on the widget’s window (on request of its parent), these values are updated immediately rather than some time later when the server generates a ConfigureNotify event. (In fact, most widgets do not select SubstructureNotify events.) This ensures that all geometry calculations are based on the internally consistent toolkit world rather than on either an inconsistent world updated by asynchronous ConfigureNotify events or a consistent, but slow, world in which geometry managers ask the server for window sizes whenever they need to lay out their managed children (see Chapter 6).

2.7.1. Unrealizing Widgets

To destroy the windows associated with a widget and its non-pop-up descendants, use XtUnrealizeWidget.

__ │

void XtUnrealizeWidget(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

If the widget is currently unrealized, XtUnrealizeWidget simply returns. Otherwise it performs the following:

Unmanages the widget if the widget is managed.

Makes a postorder (child-to-parent) traversal of the widget tree rooted at the specified widget and, for each widget that has declared a callback list resource named ‘‘unrealizeCallback’’, executes the procedures on the XtNunrealizeCallback list.

Destroys the widget’s window and any subwindows by calling XDestroyWindow with the specified widget’s window field.

Any events in the queue or which arrive following a call to XtUnrealizeWidget will be dispatched as if the window(s) of the unrealized widget(s) had never existed.

2.8. Destroying Widgets

The Intrinsics provide support

To destroy all the pop-up children of the widget being destroyed and destroy all children of composite widgets.

To remove (and unmap) the widget from its parent.

To call the callback procedures that have been registered to trigger when the widget is destroyed.

To minimize the number of things a widget has to deallocate when destroyed.

To minimize the number of XDestroyWindow calls when destroying a widget tree.

To destroy a widget instance, use XtDestroyWidget.

__ │

void XtDestroyWidget(w)
      Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

The XtDestroyWidget function provides the only method of destroying a widget, including widgets that need to destroy themselves. It can be called at any time, including from an application callback routine of the widget being destroyed. This requires a two-phase destroy process in order to avoid dangling references to destroyed widgets.

In phase 1, XtDestroyWidget performs the following:

If the being_destroyed field of the widget is True, it returns immediately.

Recursively descends the widget tree and sets the being_destroyed field to True for the widget and all normal and pop-up children.

Adds the widget to a list of widgets (the destroy list) that should be destroyed when it is safe to do so.

Entries on the destroy list satisfy the invariant that if w2 occurs after w1 on the destroy list, then w2 is not a descendent, either normal or pop-up, of w1.

Phase 2 occurs when all procedures that should execute as a result of the current event have been called, including all procedures registered with the event and translation managers, that is, when the current invocation of XtDispatchEvent is about to return, or immediately if not in XtDispatchEvent.

In phase 2, XtDestroyWidget performs the following on each entry in the destroy list in the order specified:

If the widget is not a pop-up child and the widget’s parent is a subclass of compositeWidgetClass, and if the parent is not being destroyed, it calls XtUnmanageChild on the widget and then calls the widget’s parent’s delete_child procedure (see Section 3.3).

Calls the destroy callback procedures registered on the widget and all normal and pop-up descendants in postorder (it calls child callbacks before parent callbacks).

The XtDestroyWidget function then makes second traversal of the widget and all normal and pop-up descendants to perform the following three items on each widget in postorder:

If the widget is not a pop-up child and the widget’s parent is a subclass of constraintWidgetClass, it calls the ConstraintClassPart destroy procedure for the parent, then for the parent’s superclass, until finally it calls the ConstraintClassPart destroy procedure for constraintWidgetClass.

Calls the CoreClassPart destroy procedure declared in the widget class, then the destroy procedure declared in its superclass, until finally it calls the destroy procedure declared in the Object class record. Callback lists are deallocated.

If the widget class object class part contains an ObjectClassExtension record with the record_type NULLQUARK and the deallocate field is not NULL, calls the deallocate procedure to deallocate the instance and if one exists, the constraint record. Otherwise, the Intrinsics will deallocate the widget instance record and if one exists, the constraint record.

Calls XDestroyWindow if the specified widget is realized (that is, has an X window). The server recursively destroys all normal descendant windows. (Windows of realized pop-up Shell children, and their descendants, are destroyed by a shell class destroy procedure.)

2.8.1. Adding and Removing Destroy Callbacks

When an application needs to perform additional processing during the destruction of a widget, it should register a destroy callback procedure for the widget. The destroy callback procedures use the mechanism described in Chapter 8. The destroy callback list is identified by the resource name XtNdestroyCallback.

For example, the following adds an application-supplied destroy callback procedure ClientDestroy with client data to a widget by calling XtAddCallback.

     XtAddCallback(w, XtNdestroyCallback, ClientDestroy, client_data)

Similarly, the following removes the application-supplied destroy callback procedure ClientDestroy by calling XtRemoveCallback.

     XtRemoveCallback(w, XtNdestroyCallback, ClientDestroy, client_data)

The ClientDestroy argument is of type XtCallbackProc; see Section 8.1.

2.8.2. Dynamic Data Deallocation: The destroy Procedure

The destroy procedure pointers in the ObjectClassPart, RectObjClassPart, and CoreClassPart structures are of type XtWidgetProc.

__ │

typedef void (*XtWidgetProc)(Widget);
      Widget w;

w

Specifies the widget being destroyed.

│__

The destroy procedures are called in subclass-to-superclass order. Therefore, a widget’s destroy procedure should deallocate only storage that is specific to the subclass and should ignore the storage allocated by any of its superclasses. The destroy procedure should deallocate only resources that have been explicitly created by the subclass. Any resource that was obtained from the resource database or passed in an argument list was not created by the widget and therefore should not be destroyed by it. If a widget does not need to deallocate any storage, the destroy procedure entry in its class record can be NULL.

Deallocating storage includes, but is not limited to, the following steps:

Calling XtFree on dynamic storage allocated with XtMalloc, XtCalloc, and so on.

Calling XFreePixmap on pixmaps created with direct X calls.

Calling XtReleaseGC on GCs allocated with XtGetGC.

Calling XFreeGC on GCs allocated with direct X calls.

Calling XtRemoveEventHandler on event handlers added to other widgets.

Calling XtRemoveTimeOut on timers created with XtAppAddTimeOut.

Calling XtDestroyWidget for each child if the widget has children and is not a subclass of compositeWidgetClass.

During destroy phase 2 for each widget, the Intrinsics remove the widget from the modal cascade, unregister all event handlers, remove all key, keyboard, button, and pointer grabs and remove all callback procedures registered on the widget. Any outstanding selection transfers will time out.

2.8.3. Dynamic Constraint Data Deallocation: The ConstraintClassPart destroy Procedure

The constraint destroy procedure identified in the ConstraintClassPart structure is called for a widget whose parent is a subclass of constraintWidgetClass. This constraint destroy procedure pointer is of type XtWidgetProc. The constraint destroy procedures are called in subclass-to-superclass order, starting at the class of the widget’s parent and ending at constraintWidgetClass. Therefore, a parent’s constraint destroy procedure should deallocate only storage that is specific to the constraint subclass and not storage allocated by any of its superclasses.

If a parent does not need to deallocate any constraint storage, the constraint destroy procedure entry in its class record can be NULL.

2.8.4. Widget Instance Deallocation: The deallocate Procedure

The deallocate procedure pointer in the ObjectClassExtension record is of type XtDeallocateProc.

__ │

typedef void (*XtDeallocateProc)(Widget, XtPointer);
      Widget widget;
      XtPointer more_bytes;

widget

Specifies the widget being destroyed.

more_bytes Specifies the auxiliary memory received from the corresponding allocator along with the widget, or NULL.

│__

When a widget is destroyed, if an ObjectClassExtension record exists in the object class part extension field with record_type NULLQUARK and the deallocate field is not NULL, the XtDeallocateProc will be called. If no ObjectClassPart extension record is declared with record_type equal to NULLQUARK, then XtInheritAllocate and XtInheritDeallocate are assumed. The responsibilities of the deallocate procedure are to deallocate the memory specified by more_bytes if it is not NULL, to deallocate the constraints record as specified by the widget’s core.constraints field if it is not NULL, and to deallocate the widget instance itself.

If no XtDeallocateProc is found, it is assumed that the Intrinsics originally allocated the memory and is responsible for freeing it.

2.9. Exiting from an Application

All X Toolkit applications should terminate by calling XtDestroyApplicationContext and then exiting using the standard method for their operating system (typically, by calling exit for POSIX-based systems). The quickest way to make the windows disappear while exiting is to call XtUnmapWidget on each top-level shell widget. The Intrinsics have no resources beyond those in the program image, and the X server will free its resources when its connection to the application is broken.

Depending upon the widget set in use, it may be necessary to explicitly destroy individual widgets or widget trees with XtDestroyWidget before calling XtDestroyApplicationContext in order to ensure that any required widget cleanup is properly executed. The application developer must refer to the widget documentation to learn if a widget needs to perform cleanup beyond that performed automatically by the operating system. If the client is a session participant (see Section 4.2), then the client may wish to resign from the session before exiting. See Section 4.2.4 for details.

2

X Toolkit Intrinsics X11 Release 6.4

Chapter 3

Composite Widgets and Their Children

Composite widgets (widgets whose class is a subclass of compositeWidgetClass) can have an arbitrary number of children. Consequently, they are responsible for much more than primitive widgets. Their responsibilities (either implemented directly by the widget class or indirectly by Intrinsics functions) include:

Overall management of children from creation to destruction.

Destruction of descendants when the composite widget is destroyed.

Physical arrangement (geometry management) of a displayable subset of children (that is, the managed children).

Mapping and unmapping of a subset of the managed children.

Overall management is handled by the generic procedures XtCreateWidget and XtDestroyWidget. XtCreateWidget adds children to their parent by calling the parent’s insert_child procedure. XtDestroyWidget removes children from their parent by calling the parent’s delete_child procedure and ensures that all children of a destroyed composite widget also get destroyed.

Only a subset of the total number of children is actually managed by the geometry manager and hence possibly visible. For example, a composite editor widget supporting multiple editing buffers might allocate one child widget for each file buffer, but it might display only a small number of the existing buffers. Widgets that are in this displayable subset are called managed widgets and enter into geometry manager calculations. The other children are called unmanaged widgets and, by definition, are not mapped by the Intrinsics.

Children are added to and removed from their parent’s managed set by using XtManageChild, XtManageChildren, XtUnmanageChild, XtUnmanageChildren, and XtChangeManagedSet, which notify the parent to recalculate the physical layout of its children by calling the parent’s change_managed procedure. The XtCreateManagedWidget convenience function calls XtCreateWidget and XtManageChild on the result.

Most managed children are mapped, but some widgets can be in a state where they take up physical space but do not show anything. Managed widgets are not mapped automatically if their map_when_managed field is False. The default is True and is changed by using XtSetMappedWhenManaged.

Each composite widget class declares a geometry manager, which is responsible for figuring out where the managed children should appear within the composite widget’s window. Geometry management techniques fall into four classes:

Fixed boxes

Fixed boxes have a fixed number of children created by the parent. All these children are managed, and none ever makes geometry manager requests.

Homogeneous boxes

Homogeneous boxes treat all children equally and apply the same geometry constraints to each child. Many clients insert and delete widgets freely.

Heterogeneous boxes

Heterogeneous boxes have a specific location where each child is placed. This location usually is not specified in pixels, because the window may be resized, but is expressed rather in terms of the relationship between a child and the parent or between the child and other specific children. The class of heterogeneous boxes is usually a subclass of Constraint.

Shell boxes

Shell boxes typically have only one child, and the child’s size is usually exactly the size of the shell. The geometry manager must communicate with the window manager, if it exists, and the box must also accept ConfigureNotify events when the window size is changed by the window manager.

3.1. Addition of Children to a Composite Widget: The insert_child Procedure

To add a child to the parent’s list of children, the XtCreateWidget function calls the parent’s class routine insert_child. The insert_child procedure pointer in a composite widget is of type XtWidgetProc.

__ │

typedef void (*XtWidgetProc)(Widget);
      Widget w;

w

Passes the newly created child.

│__

Most composite widgets inherit their superclass’s operation. The insert_child routine in CompositeWidgetClasscalls and inserts the child at the specified position in the children list, expanding it if necessary.

Some composite widgets define their own insert_child routine so that they can order their children in some convenient way, create companion controller widgets for a new widget, or limit the number or class of their child widgets. A composite widget class that wishes to allow nonwidget children (see Chapter 12) must specify a CompositeClassExtension extension record as described in Section 1.4.2.1 and set the accepts_objects field in this record to True. If the CompositeClassExtension record is not specified or the accepts_objects field is False, the composite widget can assume that all its children are of a subclass of Core without an explicit subclass test in the insert_child procedure.

If there is not enough room to insert a new child in the children array (that is, num_children is equal to num_slots), the insert_child procedure must first reallocate the array and update num_slots. The insert_child procedure then places the child at the appropriate position in the array and increments the num_children field.

3.2. Insertion Order of Children: The insert_position Procedure

Instances of composite widgets sometimes need to specify more about the order in which their children are kept. For example, an application may want a set of command buttons in some logical order grouped by function, and it may want buttons that represent file names to be kept in alphabetical order without constraining the order in which the buttons are created.

An application controls the presentation order of a set of children by supplying an XtNinsertPosition resource. The insert_position procedure pointer in a composite widget instance is of type XtOrderProc.

__ │

typedef Cardinal (*XtOrderProc)(Widget);
      Widget w;

w

Passes the newly created widget.

│__

Composite widgets that allow clients to order their children (usually homogeneous boxes) can call their widget instance’s insert_position procedure from the class’s insert_child procedure to determine where a new child should go in its children array. Thus, a client using a composite class can apply different sorting criteria to widget instances of the class, passing in a different insert_position procedure resource when it creates each composite widget instance.

The return value of the insert_position procedure indicates how many children should go before the widget. Returning zero indicates that the widget should go before all other children, and returning num_children indicates that it should go after all other children. The default insert_position function returns num_children and can be overridden by a specific composite widget’s resource list or by the argument list provided when the composite widget is created.

3.3. Deletion of Children: The delete_child Procedure

To remove the child from the parent’s children list, the XtDestroyWidget function eventually causes a call to the Composite parent’s class delete_child procedure. The delete_child procedure pointer is of type XtWidgetProc.

__ │

typedef void (*XtWidgetProc)(Widget);
      Widget w;

w

Passes the child being deleted.

│__

Most widgets inherit the delete_child procedure from their superclass. Composite widgets that create companion widgets define their own delete_child procedure to remove these companion widgets.

3.4. Adding and Removing Children from the Managed Set

The Intrinsics provide a set of generic routines to permit the addition of widgets to or the removal of widgets from a composite widget’s managed set. These generic routines eventually call the composite widget’s change_managed procedure if the procedure pointer is non-NULL. The change_managed procedure pointer is of type XtWidgetProc. The widget argument specifies the composite widget whose managed child set has been modified.

3.4.1. Managing Children

To add a list of widgets to the geometry-managed (and hence displayable) subset of their Composite parent, use XtManageChildren.

__ │

typedef Widget *WidgetList;


void XtManageChildren(children, num_children)
      WidgetList children;
      Cardinal num_children;

children

Specifies a list of child widgets. Each child must be of class RectObj or any subclass thereof.

num_children Specifies the number of children in the list.

│__

The XtManageChildren function performs the following:

Issues an error if the children do not all have the same parent or if the parent’s class is not a subclass of compositeWidgetClass.

Returns immediately if the common parent is being destroyed; otherwise, for each unique child on the list, XtManageChildren ignores the child if it already is managed or is being destroyed, and marks it if not.

If the parent is realized and after all children have been marked, it makes some of the newly managed children viewable:

Calls the change_managed routine of the widgets’ parent.

Calls XtRealizeWidget on each previously unmanaged child that is unrealized.

Maps each previously unmanaged child that has map_when_managed True.

Managing children is independent of the ordering of children and independent of creating and deleting children. The layout routine of the parent should consider children whose managed field is True and should ignore all other children. Note that some composite widgets, especially fixed boxes, call XtManageChild from their insert_child procedure.

If the parent widget is realized, its change_managed procedure is called to notify it that its set of managed children has changed. The parent can reposition and resize any of its children. It moves each child as needed by calling XtMoveWidget, which first updates the x and y fields and which then calls XMoveWindow.

If the composite widget wishes to change the size or border width of any of its children, it calls XtResizeWidget, which first updates the width, height, and border_width fields and then calls XConfigureWindow. Simultaneous repositioning and resizing may be done with XtConfigureWidget; see Section 6.6.

To add a single child to its parent widget’s set of managed children, use XtManageChild.

__ │

void XtManageChild(child)
      Widget child;

child

Specifies the child. Must be of class RectObj or any subclass thereof.

│__

The XtManageChild function constructs a WidgetList of length 1 and calls XtManageChildren.

To create and manage a child widget in a single procedure, use XtCreateManagedWidget or XtVaCreateManagedWidget.

__ │

Widget XtCreateManagedWidget(name, widget_class, parent, args, num_args)
      String name;
      WidgetClass widget_class;
      Widget parent;
      ArgList args;
      Cardinal num_args;

name

Specifies the resource instance name for the created widget.

widget_class Specifies the widget class pointer for the created widget. Must be rectObjClass or any subclass thereof.

parent

Specifies the parent widget. Must be of class Composite or any subclass thereof.

args

Specifies the argument list to override any other resource specifications.

num_args

Specifies the number of entries in the argument list.

│__

The XtCreateManagedWidget function is a convenience routine that calls XtCreateWidget and XtManageChild.

__ │

Widget XtVaCreateManagedWidget(name, widget_class, parent, ...)
      String name;
      WidgetClass widget_class;
      Widget parent;

name

Specifies the resource instance name for the created widget.

widget_class Specifies the widget class pointer for the created widget. Must be rectObjClass or any subclass thereof.

parent

Specifies the parent widget. Must be of class Composite or any subclass thereof.

Specifies the variable argument list to override any other resource specifications.

│__

XtVaCreateManagedWidget is identical in function to XtCreateManagedWidget with the args and num_args parameters replaced by a varargs list, as described in Section 2.5.1.

3.4.2. Unmanaging Children

To remove a list of children from a parent widget’s managed list, use XtUnmanageChildren.

__ │

void XtUnmanageChildren(children, num_children)
      WidgetList children;
      Cardinal num_children;

children

Specifies a list of child widgets. Each child must be of class RectObj or any subclass thereof.

num_children Specifies the number of children.

│__

The XtUnmanageChildren function performs the following:

Returns immediately if the common parent is being destroyed.

Issues an error if the children do not all have the same parent or if the parent is not a subclass of compositeWidgetClass.

For each unique child on the list, XtUnmanageChildren ignores the child if it is unmanaged; otherwise it performs the following:

Marks the child as unmanaged.

If the child is realized and the map_when_managed field is True, it is unmapped.

If the parent is realized and if any children have become unmanaged, calls the change_managed routine of the widgets’ parent.

XtUnmanageChildren does not destroy the child widgets. Removing widgets from a parent’s managed set is often a temporary banishment, and some time later the client may manage the children again. To destroy widgets entirely, XtDestroyWidget should be called instead; see Section 2.9.

To remove a single child from its parent widget’s managed set, use XtUnmanageChild.

__ │

void XtUnmanageChild(child)
      Widget child;

child

Specifies the child. Must be of class RectObj or any subclass thereof.

│__

The XtUnmanageChild function constructs a widget list of length 1 and calls XtUnmanageChildren.

These functions are low-level routines that are used by generic composite widget building routines. In addition, composite widgets can provide widget-specific, high-level convenience procedures.

3.4.3. Bundling Changes to the Managed Set

A client may simultaneously unmanage and manage children with a single call to the Intrinsics. In this same call the client may provide a callback procedure that can modify the geometries of one or more children. The composite widget class defines whether this single client call results in separate invocations of the change_managed method, one to unmanage and the other to manage, or in just a single invocation.

To simultaneously remove from and add to the geometry-managed set of children of a composite parent, use XtChangeManagedSet.

__ │

void XtChangeManagedSet(unmanage_children, num_unmanage_children,
                                              do_change_proc, client_data,
                                              manage_children, num_manage_children)
      WidgetList unmanage_children;
      Cardinal num_unmanage_children;
      XtDoChangeProc do_change_proc;
      XtPointer client_data;
      WidgetList manage_children;
      Cardinal num_manage_children;

unmanage_children

Specifies the list of widget children to initially remove from the managed set.

num_unmanage_children Specifies the number of entries in the unmanage_children list.

do_change_proc

Specifies a procedure to invoke between unmanaging and managing the children, or NULL.

client_data

Specifies client data to be passed to the do_change_proc.

manage_children

Specifies the list of widget children to finally add to the managed set.

num_manage_children Specifies the number of entries in the manage_children list.

│__

The XtChangeManagedSet function performs the following:

Returns immediately if num_unmanage_children and num_manage_children are both 0.

Issues a warning and returns if the widgets specified in the manage_children and the unmanage_children lists do not all have the same parent or if that parent is not a subclass of compositeWidgetClass.

Returns immediately if the common parent is being destroyed.

If do_change_proc is not NULL and the parent’s CompositeClassExtension allows_change_managed_set field is False, then XtChangeManagedSet performs the following:

Calls XtUnmanageChildren (unmanage_children, num_unmanage_children).

Calls the do_change_proc.

Calls XtManageChildren (manage_children, num_manage_children).

Otherwise, the following is performed:

For each child on the unmanage_children list; if the child is already unmanaged it is ignored, otherwise it is marked as unmanaged, and if it is realized and its map_when_managed field is True, it is unmapped.

If do_change_proc is non-NULL, the procedure is invoked.

For each child on the manage_children list; if the child is already managed or is being destroyed, it is ignored; otherwise it is marked as managed.

If the parent is realized and after all children have been marked, the change_managed method of the parent is invoked, and subsequently some of the newly managed children are made viewable by calling XtRealizeWidget on each previously unmanaged child that is unrealized and mapping each previously unmanaged child that has map_when_managed True.

If no CompositeClassExtension record is found in the parent’s composite class part extension field with record type NULLQUARK and version greater than 1, and if XtInheritChangeManaged was specified in the parent’s class record during class initialization, the value of the allows_change_managed_set field is inherited from the superclass. The value inherited from compositeWidgetClass for the allows_change_managed_set field is False.

It is not an error to include a child in both the unmanage_children and the manage_children lists. The effect of such a call is that the child remains managed following the call, but the do_change_proc is able to affect the child while it is in an unmanaged state.

The do_change_proc is of type XtDoChangeProc.

__ │

typedef void (*XtDoChangeProc)(Widget, WidgetList, Cardinal*, WidgetList, Cardinal*, XtPointer);
      Widget composite_parent;
      WidgetList unmange_children;
      Cardinal *num_unmanage_children;
      WidgetList manage_children;
      Cardinal *num_manage_children;
      XtPointer client_data;

composite_parent

Passes the composite parent whose managed set is being altered.

unmanage_children

Passes the list of children just removed from the managed set.

num_unmanage_children Passes the number of entries in the unmanage_children list.

manage_children

Passes the list of children about to be added to the managed set.

num_manage_children Passes the number of entries in the manage_children list.

client_data

Passes the client data passed to XtChangeManagedSet.

│__

The do_change_proc procedure is used by the caller of XtChangeManagedSet to make changes to one or more children at the point when the managed set contains the fewest entries. These changes may involve geometry requests, and in this case the caller of XtChangeManagedSet may take advantage of the fact that the Intrinsics internally grant geometry requests made by unmanaged children without invoking the parent’s geometry manager. To achieve this advantage, if the do_change_proc procedure changes the geometry of a child or of a descendant of a child, then that child should be included in the unmanage_children and manage_children lists.

3.4.4. Determining if a Widget Is Managed

To determine the managed state of a given child widget, use XtIsManaged.

__ │

Boolean XtIsManaged(w)
       Widget w;

w

Specifies the widget. Must be of class Object or any subclass thereof.

│__

The XtIsManaged function returns True if the specified widget is of class RectObj or any subclass thereof and is managed, or False otherwise.

3.5. Controlling When Widgets Get Mapped

A widget is normally mapped if it is managed. However, this behavior can be overridden by setting the XtNmappedWhenManaged resource for the widget when it is created or by setting the map_when_managed field to False.

To change the value of a given widget’s map_when_managed field, use XtSetMappedWhenManaged.

__ │

void XtSetMappedWhenManaged(w, map_when_managed)
      Widget w;
      Boolean map_when_managed;

w

Specifies the widget. Must be of class Core or any subclass thereof.

map_when_managed Specifies a Boolean value that indicates the new value that is stored into the widget’s map_when_managed field.

│__

If the widget is realized and managed, and if map_when_managed is True, XtSetMappedWhenManaged maps the window. If the widget is realized and managed, and if map_when_managed is False, it unmaps the window. XtSetMappedWhenManaged is a convenience function that is equivalent to (but slightly faster than) calling XtSetValues and setting the new value for the XtNmappedWhenManaged resource then mapping the widget as appropriate. As an alternative to using XtSetMappedWhenManaged to control mapping, a client may set mapped_when_managed to False and use XtMapWidget and XtUnmapWidget explicitly.

To map a widget explicitly, use XtMapWidget.

__ │

XtMapWidget(w)
     Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

To unmap a widget explicitly, use XtUnmapWidget.

__ │

XtUnmapWidget(w)
     Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

3.6. Constrained Composite Widgets

The Constraint widget class is a subclass of compositeWidgetClass. The name is derived from the fact that constraint widgets may manage the geometry of their children based on constraints associated with each child. These constraints can be as simple as the maximum width and height the parent will allow the child to occupy or can be as complicated as how other children should change if this child is moved or resized. Constraint widgets let a parent define constraints as resources that are supplied for their children. For example, if the Constraint parent defines the maximum sizes for its children, these new size resources are retrieved for each child as if they were resources that were defined by the child widget’s class. Accordingly, constraint resources may be included in the argument list or resource file just like any other resource for the child.

Constraint widgets have all the responsibilities of normal composite widgets and, in addition, must process and act upon the constraint information associated with each of their children.

To make it easy for widgets and the Intrinsics to keep track of the constraints associated with a child, every widget has a constraints field, which is the address of a parent-specific structure that contains constraint information about the child. If a child’s parent does not belong to a subclass of constraintWidgetClass, then the child’s constraints field is NULL.

Subclasses of Constraint can add constraint data to the constraint record defined by their superclass. To allow this, widget writers should define the constraint records in their private .h file by using the same conventions as used for widget records. For example, a widget class that needs to maintain a maximum width and height for each child might define its constraint record as follows:

     typedef struct {

Dimension max_width, max_height;

} MaxConstraintPart;

typedef struct {

MaxConstraintPart max;

} MaxConstraintRecord, *MaxConstraint;

A subclass of this widget class that also needs to maintain a minimum size would define its constraint record as follows:

     typedef struct {

Dimension min_width, min_height;

} MinConstraintPart;

typedef struct {

MaxConstraintPart max;
MinConstraintPart min;

} MaxMinConstraintRecord, *MaxMinConstraint;

Constraints are allocated, initialized, deallocated, and otherwise maintained insofar as possible by the Intrinsics. The Constraint class record part has several entries that facilitate this. All entries in ConstraintClassPart are fields and procedures that are defined and implemented by the parent, but they are called whenever actions are performed on the parent’s children.

The XtCreateWidget function uses the constraint_size field in the parent’s class record to allocate a constraint record when a child is created. XtCreateWidget also uses the constraint resources to fill in resource fields in the constraint record associated with a child. It then calls the constraint initialize procedure so that the parent can compute constraint fields that are derived from constraint resources and can possibly move or resize the child to conform to the given constraints.

When the XtGetValues and XtSetValues functions are executed on a child, they use the constraint resources to get the values or set the values of constraints associated with that child. XtSetValues then calls the constraint set_values procedures so that the parent can recompute derived constraint fields and move or resize the child as appropriate. If a Constraint widget class or any of its superclasses have declared a ConstraintClassExtension record in the ConstraintClassPart extension fields with a record type of NULLQUARK and the get_values_hook field in the extension record is non-NULL, XtGetValues calls the get_values_hook procedure(s) to allow the parent to return derived constraint fields.

The XtDestroyWidget function calls the constraint destroy procedure to deallocate any dynamic storage associated with a constraint record. The constraint record itself must not be deallocated by the constraint destroy procedure; XtDestroyWidget does this automatically.

3

X Toolkit Intrinsics X11 Release 6.4

Chapter 4

Shell Widgets

Shell widgets hold an application’s top-level widgets to allow them to communicate with the window manager and session manager. Shells have been designed to be as nearly invisible as possible. Clients have to create them, but they should never have to worry about their sizes.

If a shell widget is resized from the outside (typically by a window manager), the shell widget also resizes its managed child widget automatically. Similarly, if the shell’s child widget needs to change size, it can make a geometry request to the shell, and the shell negotiates the size change with the outer environment. Clients should never attempt to change the size of their shells directly.

The five types of public shells are:

4.1. Shell Widget Definitions

Widgets negotiate their size and position with their parent widget, that is, the widget that directly contains them. Widgets at the top of the hierarchy do not have parent widgets. Instead, they must deal with the outside world. To provide for this, each top-level widget is encapsulated in a special widget, called a shell widget.

Shell widgets, whose class is a subclass of the Composite class, encapsulate other widgets and can allow a widget to avoid the geometry clipping imposed by the parent-child window relationship. They also can provide a layer of communication with the window manager.

The eight different types of shells are:

Note that the classes Shell, WMShell, and VendorShell are internal and should not be instantiated or subclassed. Only OverrrideShell, TransientShell, TopLevelShell, ApplicationShell, and SessionShell are intended for public use.

4.1.1. ShellClassPart Definitions

Only the Shell class has additional class fields, which are all contained in the ShellClassExtensionRec. None of the other Shell classes have any additional class fields:

__ │

typedef struct {
        XtPointer extension;
} ShellClassPart, OverrideShellClassPart,
WMShellClassPart, VendorShellClassPart, TransientShellClassPart,
TopLevelShellClassPart, ApplicationShellClassPart, SessionShellClassPart;


│__

The full Shell class record definitions are:

__ │

typedef struct _ShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

} ShellClassRec;

typedef struct {

XtPointer

next_extension;

See Section 1.6.12

XrmQuark

record_type;

See Section 1.6.12

long

version;

See Section 1.6.12

Cardinal

record_size;

See Section 1.6.12

XtGeometryHandler

root_geometry_manager;See below

} ShellClassExtensionRec, *ShellClassExtension;

typedef struct _OverrideShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

OverrideShellClassPart

override_shell_class;

} OverrideShellClassRec;

typedef struct _WMShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

} WMShellClassRec;

typedef struct _VendorShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

VendorShellClassPart

vendor_shell_class;

} VendorShellClassRec;

typedef struct _TransientShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

VendorShellClassPart

vendor_shell_class;

TransientShellClassPart

transient_shell_class;

} TransientShellClassRec;

typedef struct _TopLevelShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

VendorShellClassPart

vendor_shell_class;

TopLevelShellClassPart

top_level_shell_class;

} TopLevelShellClassRec;

typedef struct _ApplicationShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

VendorShellClassPart

vendor_shell_class;

TopLevelShellClassPart

top_level_shell_class;

ApplicationShellClassPart

application_shell_class;

} ApplicationShellClassRec;

typedef struct _SessionShellClassRec {

CoreClassPart

core_class;

CompositeClassPart

composite_class;

ShellClassPart

shell_class;

WMShellClassPart

wm_shell_class;

VendorShellClassPart

vendor_shell_class;

TopLevelShellClassPart

top_level_shell_class;

ApplicationShellClassPart

application_shell_class;

SessionShellClassPart

session_shell_class;

} SessionShellClassRec;

│__

The single occurrences of the class records and pointers for creating instances of shells are:

__ │

extern ShellClassRec shellClassRec;
extern OverrideShellClassRec overrideShellClassRec;
extern WMShellClassRec wmShellClassRec;
extern VendorShellClassRec vendorShellClassRec;
extern TransientShellClassRec transientShellClassRec;
extern TopLevelShellClassRec topLevelShellClassRec;
extern ApplicationShellClassRec applicationShellClassRec;
extern SessionShellClassRec sessionShellClassRec;


extern WidgetClass shellWidgetClass;
extern WidgetClass overrideShellWidgetClass;
extern WidgetClass wmShellWidgetClass;
extern WidgetClass vendorShellWidgetClass;
extern WidgetClass transientShellWidgetClass;
extern WidgetClass topLevelShellWidgetClass;
extern WidgetClass applicationShellWidgetClass;
extern WidgetClass sessionShellWidgetClass;


│__

The following opaque types and opaque variables are defined for generic operations on widgets whose class is a subclass of Shell.

The declarations for all Intrinsics-defined shells except VendorShell appear in Shell.h and ShellP.h. VendorShell has separate public and private .h files which are included by Shell.h and ShellP.h.

Shell.h uses incomplete structure definitions to ensure that the compiler catches attempts to access private data in any of the Shell instance or class data structures.

The symbolic constant for the ShellClassExtension version identifier is XtShellExtensionVersion (see Section 1.6.12).

The root_geometry_manager procedure acts as the parent geometry manager for geometry requests made by shell widgets. When a shell widget calls either XtMakeGeometryRequest or XtMakeResizeRequest, the root_geometry_manager procedure is invoked to negotiate the new geometry with the window manager. If the window manager permits the new geometry, the root_geometry_manager procedure should return XtGeometryYes; if the window manager denies the geometry request or does not change the window geometry within some timeout interval (equal to wm_timeout in the case of WMShells), the root_geometry_manager procedure should return XtGeometryNo. If the window manager makes some alternative geometry change, the root_geometry_manager procedure may return either XtGeometryNo and handle the new geometry as a resize or XtGeometryAlmost in anticipation that the shell will accept the compromise. If the compromise is not accepted, the new size must then be handled as a resize. Subclasses of Shell that wish to provide their own root_geometry_manager procedures are strongly encouraged to use enveloping to invoke their superclass’s root_geometry_manager procedure under most situations, as the window manager interaction may be very complex.

If no ShellClassPart extension record is declared with record_type equal to NULLQUARK, then XtInheritRootGeometryManager is assumed.

4.1.2. ShellPart Definition

The various shell widgets have the following additional instance fields defined in their widget records:

__ │

typedef struct {

String

geometry;

XtCreatePopupChildProc

create_popup_child_proc;

XtGrabKind

grab_kind;

Boolean

spring_loaded;

Boolean

popped_up;

Boolean

allow_shell_resize;

Boolean

client_specified;

Boolean

save_under;

Boolean

override_redirect;

XtCallbackList

popup_callback;

XtCallbackList

popdown_callback;

Visual *

visual;

} ShellPart;

typedef struct {

int

empty;

} OverrideShellPart;

typedef struct {

String

title;

int

wm_timeout;

Boolean

wait_for_wm;

Boolean

transient;

Boolean

urgency;

Widget

client_leader;

String

window_role;

struct _OldXSizeHints {

long

flags;

int

x, y;

int

width, height;

int

min_width, min_height;

int

max_width, max_height;

int

width_inc, height_inc;

struct {

int

x;

int

y;

} min_aspect, max_aspect;

} size_hints;

XWMHints

wm_hints;

int

base_width, base_height, win_gravity;

Atom

title_encoding;

} WMShellPart;

typedef struct {

int

vendor_specific;

} VendorShellPart;

typedef struct {

Widget

transient_for;

} TransientShellPart;

typedef struct {

String

icon_name;

Boolean

iconic;

Atom

icon_name_encoding;

} TopLevelShellPart;

typedef struct {

char *

class;

XrmClass

xrm_class;

int

argc;

char **

argv;

} ApplicationShellPart;

typedef struct {

SmcConn

connection;

String

session_id;

String *

restart_command;

String *

clone_command;

String *

discard_command;

String *

resign_command;

String *

shutdown_command;

String *

environment;

String

current_dir;

String

program_path;

unsigned char

restart_style;

Boolean

join_session;

XtCallbackList

save_callbacks;

XtCallbackList

interact_callbacks;

XtCallbackList

cancel_callbacks;

XtCallbackList

save_complete_callbacks;

XtCallbackList

die_callbacks;

XtCallbackList

error_callbacks;

} SessionShellPart;

│__

The full shell widget instance record definitions are:

__ │

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

} ShellRec, *ShellWidget;

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

OverrideShellPart

override;

} OverrideShellRec, *OverrideShellWidget;

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

} WMShellRec, *WMShellWidget;

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

VendorShellPart

vendor;

} VendorShellRec, *VendorShellWidget;

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

VendorShellPart

vendor;

TransientShellPart

transient;

} TransientShellRec, *TransientShellWidget;

typedef struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

VendorShellPart

vendor;

TopLevelShellPart

topLevel;

} TopLevelShellRec, *TopLevelShellWidget;

typedef  struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

VendorShellPart

vendor;

TopLevelShellPart

topLevel;

ApplicationShellPart

application;

} ApplicationShellRec, *ApplicationShellWidget;

typedef  struct {

CorePart

core;

CompositePart

composite;

ShellPart

shell;

WMShellPart

wm;

VendorShellPart

vendor;

TopLevelShellPart

topLevel;

ApplicationShellPart

application;

SessionShellPart

session;

} SessionShellRec, *SessionShellWidget;

│__

4.1.3. Shell Resources

The resource names, classes, and representation types specified in the shellClassRec resource list are:

OverrideShell declares no additional resources beyond those defined by Shell.

The resource names, classes, and representation types specified in the wmShellClassRec resource list are:

The class resource list for VendorShell is implementation-defined.

The resource names, classes, and representation types that are specified in the transientShellClassRec resource list are:

The resource names, classes, and representation types that are specified in the topLevelShellClassRec resource list are:

The resource names, classes, and representation types that are specified in the applicationShellClassRec resource list are:

The resource names, classes, and representation types that are specified in the sessionShellClassRec resource list are:

4.1.4. ShellPart Default Values

The default values for fields common to all classes of public shells (filled in by the Shell resource lists and the Shell initialize procedures) are:

The geometry field specifies the size and position and is usually given only on a command line or in a defaults file. If the geometry field is non-NULL when a widget of class WMShell is realized, the geometry specification is parsed using XWMGeometry with a default geometry string constructed from the values of x, y, width, height, width_inc, and height_inc and the size and position flags in the window manager size hints are set. If the geometry specifies an x or y position, then USPosition is set. If the geometry specifies a width or height, then USSize is set. Any fields in the geometry specification override the corresponding values in the Core x, y, width, and height fields. If geometry is NULL or contains only a partial specification, then the Core x, y, width, and height fields are used and PPosition and PSize are set as appropriate. The geometry string is not copied by any of the Intrinsics Shell classes; a client specifying the string in an arglist or varargs list must ensure that the value remains valid until the shell widget is realized. For further information on the geometry string, see Section 16.4 in Xlib — C Language X Interface.

The create_popup_child_proc procedure is called by the XtPopup procedure and may remain NULL. The grab_kind, spring_loaded, and popped_up fields maintain widget state information as described under XtPopup, XtMenuPopup, XtPopdown, and XtMenuPopdown. The allow_shell_resize field controls whether the widget contained by the shell is allowed to try to resize itself. If allow_shell_resize is False, any geometry requests made by the child will always return XtGeometryNo without interacting with the window manager. Setting save_under True instructs the server to attempt to save the contents of windows obscured by the shell when it is mapped and to restore those contents automatically when the shell is unmapped. It is useful for pop-up menus. Setting override_redirect True determines whether the window manager can intercede when the shell window is mapped. For further information on override_redirect, see Section 3.2 in Xlib — C Language X Interface and Sections 4.1.10 and 4.2.2 in the Inter-Client Communication Conventions Manual. The pop-up and pop-down callbacks are called during XtPopup and XtPopdown. The default value of the visual resource is the symbolic value CopyFromParent. The Intrinsics do not need to query the parent’s visual type when the default value is used; if a client using XtGetValues to examine the visual type receives the value CopyFromParent, it must then use XGetWindowAttributes if it needs the actual visual type.

The default values for Shell fields in WMShell and its subclasses are:

The title and title_encoding fields are stored in the WM_NAME property on the shell’s window by the WMShell realize procedure. If the title_encoding field is None, the title string is assumed to be in the encoding of the current locale and the encoding of the WM_NAME property is set to XStdICCTextStyle. If a language procedure has not been set the default value of title_encoding is XA_STRING, otherwise the default value is None. The wm_timeout field specifies, in milliseconds, the amount of time a shell is to wait for confirmation of a geometry request to the window manager. If none comes back within that time, the shell assumes the window manager is not functioning properly and sets wait_for_wm to False (later events may reset this value). When wait_for_wm is False, the shell does not wait for a response, but relies on asynchronous notification. If transient is True, the WM_TRANSIENT_FOR property will be stored on the shell window with a value as specified below. The interpretation of this property is specific to the window manager under which the application is run; see the Inter-Client Communication Conventions Manual for more details.

The realize and set_values procedures of WMShell store the WM_CLIENT_LEADER property on the shell window. When client_leader is not NULL and the client leader widget is realized, the property will be created with the value of the window of the client leader widget. When client_leader is NULL and the shell widget has a NULL parent, the widget’s window is used as the value of the property. When client_leader is NULL and the shell widget has a non-NULL parent, a search is made for the closest shell ancestor with a non-NULL client_leader, and if none is found the shell ancestor with a NULL parent is the result. If the resulting widget is realized, the property is created with the value of the widget’s window.

When the value of window_role is not NULL, the realize and set_values procedures store the WM_WINDOW_ROLE property on the shell’s window with the value of the resource.

All other resources specify fields in the window manager hints and the window manager size hints. The realize and set_values procedures of WMShell set the corresponding flag bits in the hints if any of the fields contain nondefault values. In addition, if a flag bit is set that refers to a field with the value XtUnspecifiedShellInt, the value of the field is modified as follows:

If the shell widget has a non-NULL parent, then the realize and set_values procedures replace the value XtUnspecifiedWindow in the window_group field with the window id of the root widget of the widget tree if the root widget is realized. The symbolic constant XtUnspecifiedWindowGroup may be used to indicate that the window_group hint flag bit is not to be set. If transient is True, the shell’s class is not a subclass of TransientShell, and window_group is not XtUnspecifiedWindowGroup, the WMShell realize and set_values procedures then store the WM_TRANSIENT_FOR property with the value of window_group.

Transient shells have the following additional resource:

The realize and set_values procedures of TransientShell store the WM_TRANSIENT_FOR property on the shell window if transient is True. If transient_for is non-NULL and the widget specified by transient_for is realized, then its window is used as the value of the WM_TRANSIENT_FOR property; otherwise, the value of window_group is used.

TopLevel shells have the the following additional resources:

The icon_name and icon_name_encoding fields are stored in the WM_ICON_NAME property on the shell’s window by the TopLevelShell realize procedure. If the icon_name_encoding field is None, the icon_name string is assumed to be in the encoding of the current locale and the encoding of the WM_ICON_NAME property is set to XStdICCTextStyle. If a language procedure has not been set, the default value of icon_name_encoding is XA_STRING, otherwise the default value is None. The iconic field may be used by a client to request that the window manager iconify or deiconify the shell; the TopLevelShell set_values procedure will send the appropriate WM_CHANGE_STATE message (as specified by the Inter-Client Communication Conventions Manual) if this resource is changed from False to True and will call XtPopup specifying grab_kind as XtGrabNone if iconic is changed from True to False. The XtNiconic resource is also an alternative way to set the XtNinitialState resource to indicate that a shell should be initially displayed as an icon; the TopLevelShell initialize procedure will set initial_state to IconicState if iconic is True.

Application shells have the following additional resources:

The argc and argv fields are used to initialize the standard property WM_COMMAND. See the Inter-Client Communication Conventions Manual for more information.

The default values for the SessionShell instance fields, which are filled in from the resource lists and by the initialize procedure, are

The connection field contains the session connection object or NULL if a session connection is not being managed by this widget.

The session_id is an identification assigned to the session participant by the session manager. The session_id will be passed to the session manager as the client identifier of the previous session. When a connection is established with the session manager, the client id assigned by the session manager is stored in the session_id field. When not NULL, the session_id of the Session shell widget that is at the root of the widget tree of the client leader widget will be used to create the SM_CLIENT_ID property on the client leader’s window.

If join_session is False, the widget will not attempt to establish a connection to the session manager at shell creation time. See Sections 4.2.1 and 4.2.4 for more information on the functionality of this resource.

The restart_command, clone_command, discard_command, resign_command, shutdown_command, environment, current_dir, program_path, and restart_style fields contain standard session properties.

When a session connection is established or newly managed by the shell, the shell initialize and set_values methods check the values of the restart_command, clone_command, and program_path resources. At that time, if restart_command is NULL, the value of the argv resource will be copied to restart_command. Whether or not restart_command was NULL, if "-xtsessionID" "<session id>" does not already appear in the restart_command, it will be added by the initialize and set_values methods at the beginning of the command arguments; if the "-xtsessionID" argument already appears with an incorrect session id in the following argument, that argument will be replaced with the current session id.

After this, the shell initialize and set_values procedures check the clone_command. If clone_command is NULL, restart_command will be copied to clone_command, except the "-xtsessionID" and following argument will not be copied.

Finally, the shell initialize and set_values procedures check the program_path. If program_path is NULL, the first element of restart_command is copied to program_path.

The possible values of restart_style are SmRestartIfRunning, SmRestartAnyway, SmRestartImmediately, and SmRestartNever. A resource converter is registered for this resource; for the strings that it recognizes, see Section 9.6.1.

The resource type EnvironmentArray is a NULL-terminated array of pointers to strings; each string has the format "name=value". The ‘=’ character may not appear in the name, and the string is terminated by a null character.

4.2. Session Participation

Applications can participate in a user’s session, exchanging messages with the session manager as described in the X Session Management Protocol and the X Session Management Library.

When a widget of sessionShellWidgetClass or a subclass is created, the widget provides support for the application as a session participant and continues to provide support until the widget is destroyed.

4.2.1. Joining a Session

When a Session shell is created, if connection is NULL, and if join_session is True, and if argv or restart_command is not NULL, and if in POSIX environments the SESSION_MANAGER environment variable is defined, the shell will attempt to establish a new connection with the session manager.

To transfer management of an existing session connection from an application to the shell at widget creation time, pass the existing session connection ID as the connection resource value when creating the Session shell, and if the other creation-time conditions on session participation are met, the widget will maintain the connection with the session manager. The application must ensure that only one Session shell manages the connection.

In the Session shell set_values procedure, if join_session changes from False to True and connection is NULL and when in POSIX environments the SESSION_MANAGER environment variable is defined, the shell will attempt to open a connection to the session manager. If connection changes from NULL to non-NULL, the Session shell will take over management of that session connection and will set join_session to True. If join_session changes from False to True and connection is not NULL, the Session shell will take over management of the session connection.

When a successful connection has been established, connection contains the session connection ID for the session participant. When the shell begins to manage the connection, it will call XtAppAddInput to register the handler which watches for protocol messages from the session manager. When the attempt to connect fails, a warning message is issued and connection is set to NULL.

While the connection is being managed, if a SaveYourself, SaveYourselfPhase2, Interact, ShutdownCancelled, SaveComplete, or Die message is received from the session manager, the Session shell will call out to application callback procedures registered on the respective callback list of the Session shell and will send SaveYourselfPhase2Request, InteractRequest, InteractDone, SaveYourselfDone, and ConnectionClosed messages as appropriate. Initially, all of the client’s session properties are undefined. When any of the session property resource values are defined or change, the Session shell initialize and set_values procedures will update the client’s session property value by a SetProperties or a DeleteProperties message, as appropriate. The session ProcessID and UserID properties are always set by the shell when it is possible to determine the value of these properties.

4.2.2. Saving Application State

The session manager instigates an application checkpoint by sending a SaveYourself request. Applications are responsible for saving their state in response to the request.

When the SaveYourself request arrives, the procedures registered on the Session shell’s save callback list are called. If the application does not register any save callback procedures on the save callback list, the shell will report to the session manager that the application failed to save its state. Each procedure on the save callback list receives a token in the call_data parameter.

The checkpoint token in the call_data parameter is of type XtCheckpointToken.

__ │

typedef struct {

int

save_type;

int

interact_style;

Boolean

shutdown;

Boolean

fast;

Boolean

cancel_shutdown

int

phase;

int

interact_dialog_type;/* return */

Boolean

request_cancel;

/* return */

Boolean

request_next_phase;

/* return */

Boolean

save_success;

/* return */

} XtCheckpointTokenRec, *XtCheckpointToken;

│__

The save_type, interact_style, shutdown, and fast fields of the token contain the parameters of the SaveYourself message. The possible values of save_type are SmSaveLocal, SmSaveGlobal, and SmSaveBoth; these indicate the type of information to be saved. The possible values of interact_style are SmInteractStyleNone, SmInteractStyleErrors, and SmInteractStyleAny; these indicate whether user interaction would be permitted and, if so, what kind of interaction. If shutdown is True, the checkpoint is being performed in preparation for the end of the session. If fast is True, the client should perform the checkpoint as quickly as possible. If cancel_shutdown is True, a ShutdownCancelled message has been received for the current save operation. (See Section 4.4.4.) The phase is used by manager clients, such as a window manager, to distinguish between the first and second phase of a save operation. The phase will be either 1 or 2. The remaining fields in the checkpoint token structure are provided for the application to communicate with the shell.

Upon entry to the first application save callback procedure, the return fields in the token have the following initial values: interact_dialog_type is SmDialogNormal; request_cancel is False; request_next_phase is False; and save_success is True. When a token is returned with any of the four return fields containing a noninitial value, and when the field is applicable, subsequent tokens passed to the application during the current save operation will always contain the noninitial value.

The purpose of the token’s save_success field is to indicate the outcome of the entire operation to the session manager and ultimately, to the user. Returning False indicates some portion of the application state could not be successfully saved. If any token is returned to the shell with save_success False, tokens subsequently received by the application for the current save operation will show save_success as False. When the shell sends the final status of the checkpoint to the session manager, it will indicate failure to save application state if any token was returned with save_success False.

Session participants that manage and save the state of other clients should structure their save or interact callbacks to set request_next_phase to True when phase is 1, which will cause the shell to send the SaveYourselfPhase2Request when the first phase is complete. When the SaveYourselfPhase2 message is received, the shell will invoke the save callbacks a second time with phase equal to 2. Manager clients should save the state of other clients when the callbacks are invoked the second time and phase equal to 2.

The application may request additional tokens while a checkpoint is under way, and these additional tokens must be returned by an explicit call.

To request an additional token for a save callback response that has a deferred outcome, use XtSessionGetToken.

__ │

XtCheckpointToken XtSessionGetToken(widget)
      Widget widget;

widget

Specifies the Session shell widget which manages session participation.

│__

The XtSessionGetToken function will return NULL if no checkpoint operation is currently under way.

To indicate the completion of checkpoint processing including user interaction, the application must signal the Session shell by returning all tokens. (See Sections 4.2.2.2 and 4.2.2.4). To return a token, use XtSessionReturnToken.

__ │

void XtSessionReturnToken(token)
      XtCheckpointToken token;

token

Specifies a token that was received as the call_data by a procedure on the interact callback list or a token that was received by a call to XtSessionGetToken.

│__

Tokens passed as call_data to save callbacks are implicitly returned when the save callback procedure returns. A save callback procedure should not call XtSessionReturnToken on the token passed in its call_data.

4.2.2.1. Requesting Interaction

When the token interact_style allows user interaction, the application may interact with the user during the checkpoint, but must wait for permission to interact. Applications request permission to interact with the user during the checkpointing operation by registering a procedure on the Session shell’s interact callback list. When all save callback procedures have returned, and each time a token that was granted by a call to XtSessionGetToken is returned, the Session shell examines the interact callback list. If interaction is permitted and the interact callback list is not empty, the shell will send an InteractRequest to the session manager when an interact request is not already outstanding for the application.

The type of interaction dialog that will be requested is specified by the interact_dialog_type field in the checkpoint token. The possible values for interact_dialog_type are SmDialogError and SmDialogNormal. If a token is returned with interact_dialog_type containing SmDialogError, the interact request and any subsequent interact requests will be for an error dialog; otherwise, the request will be for a normal dialog with the user.

When a token is returned with save_success False or interact_dialog_type SmDialogError, tokens subsequently passed to callbacks during the same active SaveYourself response will reflect these changed values, indicating that an error condition has occurred during the checkpoint.

The request_cancel field is a return value for interact callbacks only. Upon return from a procedure on the save callback list, the value of the token’s request_cancel field is not examined by the shell. This is also true of tokens received through a call to XtSessionGetToken.

4.2.2.2. Interacting with the User during a Checkpoint

When the session manager grants the application’s request for user interaction, the Session shell receives an Interact message. The procedures registered on the interact callback list are executed, but not as if executing a typical callback list. These procedures are individually executed in sequence, with a checkpoint token functioning as the sequencing mechanism. Each step in the sequence begins by removing a procedure from the interact callback list and executing it with a token passed in the call_data. The interact callback will typically pop up a dialog box and return. When the user interaction and associated application checkpointing has completed, the application must return the token by calling XtSessionReturnToken. Returning the token completes the current step and triggers the next step in the sequence.

During interaction the client may request cancellation of a shutdown. When a token passed as call_data to an interact procedure is returned, if shutdown is True and cancel_shutdown is False, request_cancel indicates whether the application requests that the pending shutdown be cancelled. If request_cancel is True, the field will also be True in any tokens subsequently granted during the checkpoint operation. When a token is returned requesting cancellation of the session shutdown, pending interact procedures will still be called by the Session shell. When all interact procedures have been removed from the interact callback list, executed, and the final interact token returned to the shell, an InteractDone message is sent to the session manager, indicating whether a pending session shutdown is requested to be cancelled.

4.2.2.3. Responding to a Shutdown Cancellation

Callbacks registered on the cancel callback list are invoked when the Session shell processes a ShutdownCancelled message from the session manager. This may occur during the processing of save callbacks, while waiting for interact permission, during user interaction, or after the save operation is complete and the application is expecting a SaveComplete or a Die message. The call_data for these callbacks is NULL.

When the shell notices that a pending shutdown has been cancelled, the token cancel_shutdown field will be True in tokens subsequently given to the application.

Receiving notice of a shutdown cancellation does not cancel the pending execution of save callbacks or interact callbacks. After the cancel callbacks execute, if interact_style is not SmInteractStyleNone and the interact list is not empty, the procedures on the interact callback list will be executed and passed a token with interact_style SmInteractStyleNone. The application should not interact with the user, and the Session shell will not send an InteractDone message.

4.2.2.4. Completing a Save

When there is no user interaction, the shell regards the application as having finished saving state when all callback procedures on the save callback list have returned, and any additional tokens passed out by XtSessionGetToken have been returned by corresponding calls to XtSessionReturnToken. If the save operation involved user interaction, the above completion conditions apply, and in addition, all requests for interaction have been granted or cancelled, and all tokens passed to interact callbacks have been returned through calls to XtSessionReturnToken. If the save operation involved a manager client that requested the second phase, the above conditions apply to both the first and second phase of the save operation.

When the application has finished saving state, the Session shell will report the result to the session manager by sending the SaveYourselfDone message. If the session is continuing, the shell will receive the SaveComplete message when all applications have completed saving state. This message indicates that applications may again allow changes to their state. The shell will execute the save_complete callbacks. The call_data for these callbacks is NULL.

4.2.3. Responding to a Shutdown

Callbacks registered on the die callback list are invoked when the session manager sends a Die message. The callbacks on this list should do whatever is appropriate to quit the application. Before executing procedures on the die callback list, the Session shell will close the connection to the session manager and will remove the handler that watches for protocol messages. The call_data for these callbacks is NULL.

4.2.4. Resigning from a Session

When the Session shell widget is destroyed, the destroy method will close the connection to the session manager by sending a ConnectionClosed protocol message and will remove the input callback that was watching for session protocol messages.

When XtSetValues is used to set join_session to False, the set_values method of the Session shell will close the connection to the session manager if one exists by sending a ConnectionClosed message, and connection will be set to NULL.

Applications that exit in response to user actions and that do not wait for phase 2 destroy to complete on the Session shell should set join_session to False before exiting.

When XtSetValues is used to set connection to NULL, the Session shell will stop managing the connection, if one exists. However, that session connection will not be closed.

Applications that wish to ensure continuation of a session connection beyond the destruction of the shell should first retrieve the connection resource value, then set the connection resource to NULL, and then they may safely destroy the widget without losing control of the session connection.

The error callback list will be called if an unrecoverable communications error occurs while the shell is managing the connection. The shell will close the connection, set connection to NULL, remove the input callback, and call the procedures registered on the error callback list. The call_data for these callbacks is NULL.

4

X Toolkit Intrinsics X11 Release 6.4

Chapter 5

Pop-Up Widgets

Pop-up widgets are used to create windows outside of the window hierarchy defined by the widget tree. Each pop-up child has a window that is a descendant of the root window, so that the pop-up window is not clipped by the pop-up widget’s parent window. Therefore, pop-ups are created and attached differently to their widget parent than normal widget children.

A parent of a pop-up widget does not actively manage its pop-up children; in fact, it usually does not operate upon them in any way. The popup_list field in the CorePart structure contains the list of its pop-up children. This pop-up list exists mainly to provide the proper place in the widget hierarchy for the pop-up to get resources and to provide a place for XtDestroyWidget to look for all extant children.

A composite widget can have both normal and pop-up children. A pop-up can be popped up from almost anywhere, not just by its parent. The term child always refers to a normal, geometry-managed widget on the composite widget’s list of children, and the term pop-up child always refers to a widget on the pop-up list.

5.1. Pop-Up Widget Types

There are three kinds of pop-up widgets:

Modeless pop-ups

A modeless pop-up (for example, a dialog box that does not prevent continued interaction with the rest of the application) can usually be manipulated by the window manager and looks like any other application window from the user’s point of view. The application main window itself is a special case of a modeless pop-up.

Modal pop-ups

A modal pop-up (for example, a dialog box that requires user input to continue) can sometimes be manipulated by the window manager, and except for events that occur in the dialog box, it disables user-event distribution to the rest of the application.

Spring-loaded pop-ups

A spring-loaded pop-up (for example, a menu) can seldom be manipulated by the window manager, and except for events that occur in the pop-up or its descendants, it disables user-event distribution to all other applications.

Modal pop-ups and spring-loaded pop-ups are very similar and should be coded as if they were the same. In fact, the same widget (for example, a ButtonBox or Menu widget) can be used both as a modal pop-up and as a spring-loaded pop-up within the same application. The main difference is that spring-loaded pop-ups are brought up with the pointer and, because of the grab that the pointer button causes, require different processing by the Intrinsics. Furthermore, all user input remap events occurring outside the spring-loaded pop-up (e.g., in a descendant) are also delivered to the spring-loaded pop-up after they have been dispatched to the appropriate descendant, so that, for example, button-up can take down a spring-loaded pop-up no matter where the button-up occurs.

Any kind of pop-up, in turn, can pop up other widgets. Modal and spring-loaded pop-ups can constrain user events to the most recent such pop-up or allow user events to be dispatched to any of the modal or spring-loaded pop-ups currently mapped.

Regardless of their type, all pop-up widget classes are responsible for communicating with the X window manager and therefore are subclasses of one of the Shell widget classes.

5.2. Creating a Pop-Up Shell

For a widget to be popped up, it must be the child of a pop-up shell widget. None of the Intrinsics-supplied shells will simultaneously manage more than one child. Both the shell and child taken together are referred to as the pop-up. When you need to use a pop-up, you always refer to the pop-up by the pop-up shell, not the child.

To create a pop-up shell, use XtCreatePopupShell.

__ │

Widget XtCreatePopupShell(name, widget_class, parent, args, num_args)
      String name;
      WidgetClass widget_class;
      Widget parent;
      ArgList args;
      Cardinal num_args;

name

Specifies the instance name for the created shell widget.

widget_class Specifies the widget class pointer for the created shell widget.

parent

Specifies the parent widget. Must be of class Core or any subclass thereof.

args

Specifies the argument list to override any other resource specifications.

num_args

Specifies the number of entries in the argument list.

│__

The XtCreatePopupShell function ensures that the specified class is a subclass of Shell and, rather than using insert_child to attach the widget to the parent’s children list, attaches the shell to the parent’s popup_list directly.

The screen resource for this widget is determined by first scanning args for the XtNscreen argument. If no XtNscreen argument is found, the resource database associated with the parent’s screen is queried for the resource name.screen, class Class.Screen where Class is the class_name field from the CoreClassPart of the specified widget_class. If this query fails, the parent’s screen is used. Once the screen is determined, the resource database associated with that screen is used to retrieve all remaining resources for the widget not specified in args.

A spring-loaded pop-up invoked from a translation table via XtMenuPopup must already exist at the time that the translation is invoked, so the translation manager can find the shell by name. Pop-ups invoked in other ways can be created when the pop-up actually is needed. This delayed creation of the shell is particularly useful when you pop up an unspecified number of pop-ups. You can look to see if an appropriate unused shell (that is, not currently popped up) exists and create a new shell if needed.

To create a pop-up shell using varargs lists, use XtVaCreatePopupShell.

__ │

Widget XtVaCreatePopupShell(name, widget_class, parent, ...)
      String name;
      WidgetClass widget_class;
      Widget parent;

name

Specifies the instance name for the created shell widget.

widget_class Specifies the widget class pointer for the created shell widget.

parent

Specifies the parent widget. Must be of class Core or any subclass thereof.

Specifies the variable argument list to override any other resource specifications.

│__

XtVaCreatePopupShell is identical in function to XtCreatePopupShell with the args and num_args parameters replaced by a varargs list as described in Section 2.5.1.

5.3. Creating Pop-Up Children

Once a pop-up shell is created, the single child of the pop-up shell can be created either statically or dynamically.

At startup, an application can create the child of the pop-up shell, which is appropriate for pop-up children composed of a fixed set of widgets. The application can change the state of the subparts of the pop-up child as the application state changes. For example, if an application creates a static menu, it can call XtSetSensitive (or, in general, XtSetValues) on any of the buttons that make up the menu. Creating the pop-up child early means that pop-up time is minimized, especially if the application calls XtRealizeWidget on the pop-up shell at startup. When the menu is needed, all the widgets that make up the menu already exist and need only be mapped. The menu should pop up as quickly as the X server can respond.

Alternatively, an application can postpone the creation of the child until it is needed, which minimizes application startup time and allows the pop-up child to reconfigure itself each time it is popped up. In this case, the pop-up child creation routine might poll the application to find out if it should change the sensitivity of any of its subparts.

Pop-up child creation does not map the pop-up, even if you create the child and call XtRealizeWidget on the pop-up shell.

All shells have pop-up and pop-down callbacks, which provide the opportunity either to make last-minute changes to a pop-up child before it is popped up or to change it after it is popped down. Note that excessive use of pop-up callbacks can make popping up occur more slowly.

5.4. Mapping a Pop-Up Widget

Pop-ups can be popped up through several mechanisms:

A call to XtPopup or XtPopupSpringLoaded.

One of the supplied callback procedures XtCallbackNone, XtCallbackNonexclusive, or XtCallbackExclusive.

The standard translation action XtMenuPopup.

Some of these routines take an argument of type XtGrabKind, which is defined as

__ │

typedef enum {XtGrabNone, XtGrabNonexclusive, XtGrabExclusive} XtGrabKind;


│__

The create_popup_child_proc procedure pointer in the shell widget instance record is of type XtCreatePopupChildProc.

__ │

typedef void (*XtCreatePopupChildProc)(Widget);
      Widget w;

w

Specifies the shell widget being popped up.

│__

To map a pop-up from within an application, use XtPopup.

__ │

void XtPopup(popup_shell, grab_kind)
      Widget popup_shell;
      XtGrabKind grab_kind;

popup_shell Specifies the shell widget.

grab_kind

Specifies the way in which user events should be constrained.

│__

The XtPopup function performs the following:

Calls XtCheckSubclass to ensure popup_shell’s class is a subclass of shellWidgetClass.

Raises the window and returns if the shell’s popped_up field is already True.

Calls the callback procedures on the shell’s popup_callback list, specifying a pointer to the value of grab_kind as the call_data argument.

Sets the shell popped_up field to True, the shell spring_loaded field to False, and the shell grab_kind field from grab_kind.

If the shell’s create_popup_child_proc field is non-NULL, XtPopup calls it with popup_shell as the parameter.

If grab_kind is either XtGrabNonexclusive or XtGrabExclusive, it calls

     XtAddGrab(popup_shell, (grab_kind == XtGrabExclusive), False)

Calls XtRealizeWidget with popup_shell specified.

Calls XMapRaised with the window of popup_shell.

To map a spring-loaded pop-up from within an application, use XtPopupSpringLoaded.

__ │

void XtPopupSpringLoaded(popup_shell)
      Widget popup_shell;

popup_shell Specifies the shell widget to be popped up.

│__

The XtPopupSpringLoaded function performs exactly as XtPopup except that it sets the shell spring_loaded field to True and always calls XtAddGrab with exclusive True and spring-loaded True.

To map a pop-up from a given widget’s callback list, you also can register one of the XtCallbackNone, XtCallbackNonexclusive, or XtCallbackExclusive convenience routines as callbacks, using the pop-up shell widget as the client data.

__ │

void XtCallbackNone(w, client_data, call_data)
      Widget w;
      XtPointer client_data;
      XtPointer call_data;

w

Specifies the widget.

client_data Specifies the pop-up shell.

call_data

Specifies the callback data argument, which is not used by this procedure.

void XtCallbackNonexclusive(w, client_data, call_data)
      Widget w;
      XtPointer client_data;
      XtPointer call_data;

w

Specifies the widget.

client_data Specifies the pop-up shell.

call_data

Specifies the callback data argument, which is not used by this procedure.

void XtCallbackExclusive(w, client_data, call_data)
      Widget w;
      XtPointer client_data;
      XtPointer call_data;

w

Specifies the widget.

client_data Specifies the pop-up shell.

call_data

Specifies the callback data argument, which is not used by this procedure.

│__

The XtCallbackNone, XtCallbackNonexclusive, and XtCallbackExclusive functions call XtPopup with the shell specified by the client_data argument and grab_kind set as the name specifies. XtCallbackNone, XtCallbackNonexclusive, and XtCallbackExclusive specify XtGrabNone, XtGrabNonexclusive, and XtGrabExclusive, respectively. Each function then sets the widget that executed the callback list to be insensitive by calling XtSetSensitive. Using these functions in callbacks is not required. In particular, an application must provide customized code for callbacks that create pop-up shells dynamically or that must do more than desensitizing the button.

Within a translation table, to pop up a menu when a key or pointer button is pressed or when the pointer is moved into a widget, use XtMenuPopup, or its synonym, MenuPopup. From a translation writer’s point of view, the definition for this translation action is

__ │

void XtMenuPopup(shell_name)
      String shell_name;

shell_name Specifies the name of the shell widget to pop up.

│__

XtMenuPopup is known to the translation manager, which registers the corresponding built-in action procedure XtMenuPopupAction using XtRegisterGrabAction specifying owner_events True, event_mask ButtonPressMask | ButtonReleaseMask, and pointer_mode and keyboard_mode GrabModeAsync.

If XtMenuPopup is invoked on ButtonPress, it calls XtPopupSpringLoaded on the specified shell widget. If XtMenuPopup is invoked on KeyPress or EnterWindow, it calls XtPopup on the specified shell widget with grab_kind set to XtGrabNonexclusive. Otherwise, the translation manager generates a warning message and ignores the action.

XtMenuPopup tries to find the shell by searching the widget tree starting at the widget in which it is invoked. If it finds a shell with the specified name in the pop-up children of that widget, it pops up the shell with the appropriate parameters. Otherwise, it moves up the parent chain to find a pop-up child with the specified name. If XtMenuPopup gets to the application top-level shell widget and has not found a matching shell, it generates a warning and returns immediately.

5.5. Unmapping a Pop-Up Widget

Pop-ups can be popped down through several mechanisms:

A call to XtPopdown

The supplied callback procedure XtCallbackPopdown

The standard translation action XtMenuPopdown

To unmap a pop-up from within an application, use XtPopdown.

__ │

void XtPopdown(popup_shell)
      Widget popup_shell;

popup_shell Specifies the shell widget to pop down.

│__

The XtPopdown function performs the following:

Calls XtCheckSubclass to ensure popup_shell’s class is a subclass of shellWidgetClass.

Checks that the popped_up field of popup_shell is True; otherwise, it returns immediately.

Unmaps popup_shell’s window and, if override_redirect is False, sends a synthetic UnmapNotify event as specified by the Inter-Client Communication Conventions Manual.

If popup_shell’s grab_kind is either XtGrabNonexclusive or XtGrabExclusive, it calls XtRemoveGrab.

Sets popup_shell’s popped_up field to False.

Calls the callback procedures on the shell’s popdown_callback list, specifying a pointer to the value of the shell’s grab_kind field as the call_data argument.

To pop down a pop-up from a callback list, you may use the callback XtCallbackPopdown.

__ │

void XtCallbackPopdown(w, client_data, call_data)
      Widget w;
      XtPointer client_data;
      XtPointer call_data;

w

Specifies the widget.

client_data Specifies a pointer to the XtPopdownID structure.

call_data

Specifies the callback data argument, which is not used by this procedure.

│__

The XtCallbackPopdown function casts the client_data parameter to a pointer of type XtPopdownID.

__ │

typedef struct {

Widget shell_widget;

Widget enable_widget;

} XtPopdownIDRec, *XtPopdownID;

│__

The shell_widget is the pop-up shell to pop down, and the enable_widget is usually the widget that was used to pop it up in one of the pop-up callback convenience procedures.

XtCallbackPopdown calls XtPopdown with the specified shell_widget and then calls XtSetSensitive to resensitize enable_widget.

Within a translation table, to pop down a spring-loaded menu when a key or pointer button is released or when the pointer is moved into a widget, use XtMenuPopdown or its synonym, MenuPopdown. From a translation writer’s point of view, the definition for this translation action is

__ │

void XtMenuPopdown(shell_name)
      String shell_name;

shell_name Specifies the name of the shell widget to pop down.

│__

If a shell name is not given, XtMenuPopdown calls XtPopdown with the widget for which the translation is specified. If shell_name is specified in the translation table, XtMenuPopdown tries to find the shell by looking up the widget tree starting at the widget in which it is invoked. If it finds a shell with the specified name in the pop-up children of that widget, it pops down the shell; otherwise, it moves up the parent chain to find a pop-up child with the specified name. If XtMenuPopdown gets to the application top-level shell widget and cannot find a matching shell, it generates a warning and returns immediately.

5

X Toolkit Intrinsics X11 Release 6.4

Chapter 6

Geometry Management

A widget does not directly control its size and location; rather, its parent is responsible for controlling them. Although the position of children is usually left up to their parent, the widgets themselves often have the best idea of their optimal sizes and, possibly, preferred locations.

To resolve physical layout conflicts between sibling widgets and between a widget and its parent, the Intrinsics provide the geometry management mechanism. Almost all composite widgets have a geometry manager specified in the geometry_manager field in the widget class record that is responsible for the size, position, and stacking order of the widget’s children. The only exception is fixed boxes, which create their children themselves and can ensure that their children will never make a geometry request.

6.1. Initiating Geometry Changes

Parents, children, and clients each initiate geometry changes differently. Because a parent has absolute control of its children’s geometry, it changes the geometry directly by calling XtMoveWidget, XtResizeWidget, or XtConfigureWidget. A child must ask its parent for a geometry change by calling XtMakeGeometryRequest or XtMakeResizeRequest. An application or other client code initiates a geometry change by calling XtSetValues on the appropriate geometry fields, thereby giving the widget the opportunity to modify or reject the client request before it gets propagated to the parent and the opportunity to respond appropriately to the parent’s reply.

When a widget that needs to change its size, position, border width, or stacking depth asks its parent’s geometry manager to make the desired changes, the geometry manager can allow the request, disallow the request, or suggest a compromise.

When the geometry manager is asked to change the geometry of a child, the geometry manager may also rearrange and resize any or all of the other children that it controls. The geometry manager can move children around freely using XtMoveWidget. When it resizes a child (that is, changes the width, height, or border width) other than the one making the request, it should do so by calling XtResizeWidget. The requesting child may be given special treatment; see Section 6.5. It can simultaneously move and resize a child with a single call to XtConfigureWidget.

Often, geometry managers find that they can satisfy a request only if they can reconfigure a widget that they are not in control of; in particular, the composite widget may want to change its own size. In this case, the geometry manager makes a request to its parent’s geometry manager. Geometry requests can cascade this way to arbitrary depth.

Because such cascaded arbitration of widget geometry can involve extended negotiation, windows are not actually allocated to widgets at application startup until all widgets are satisfied with their geometry; see Sections 2.5 and 2.6.

Notes

1.

The Intrinsics treatment of stacking requests is deficient in several areas. Stacking requests for unrealized widgets are granted but will have no effect. In addition, there is no way to do an XtSetValues that will generate a stacking geometry request.

2.

After a successful geometry request (one that returned XtGeometryYes), a widget does not know whether its resize procedure has been called. Widgets should have resize procedures that can be called more than once without ill effects.

6.2. General Geometry Manager Requests

When making a geometry request, the child specifies an XtWidgetGeometry structure.

__ │

typedef unsigned long XtGeometryMask;


typedef struct {

XtGeometryMask request_mode;

Position x, y;

Dimension width, height;

Dimension border_width;

Widget sibling;

int stack_mode;

} XtWidgetGeometry;

│__

To make a general geometry manager request from a widget, use XtMakeGeometryRequest.

__ │

XtGeometryResult XtMakeGeometryRequest(w, request, reply_return)
      Widget w;
      XtWidgetGeometry *request;
      XtWidgetGeometry *reply_return;

w

Specifies the widget making the request. Must be of class RectObj or any subclass thereof.

request

Specifies the desired widget geometry (size, position, border width, and stacking order).

reply_return Returns the allowed widget size, or may be NULL if the requesting widget is not interested in handling XtGeometryAlmost.

│__

Depending on the condition, XtMakeGeometryRequest performs the following:

If the widget is unmanaged or the widget’s parent is not realized, it makes the changes and returns XtGeometryYes.

If the parent’s class is not a subclass of compositeWidgetClass or the parent’s geometry_manager field is NULL, it issues an error.

If the widget’s being_destroyed field is True, it returns XtGeometryNo.

If the widget x, y, width, height, and border_width fields are all equal to the requested values, it returns XtGeometryYes; otherwise, it calls the parent’s geometry_manager procedure with the given parameters.

If the parent’s geometry manager returns XtGeometryYes and if XtCWQueryOnly is not set in request->request_mode and if the widget is realized, XtMakeGeometryRequest calls the XConfigureWindow Xlib function to reconfigure the widget’s window (set its size, location, and stacking order as appropriate).

If the geometry manager returns XtGeometryDone, the change has been approved and actually has been done. In this case, XtMakeGeometryRequest does no configuring and returns XtGeometryYes. XtMakeGeometryRequest never returns XtGeometryDone.

Otherwise, XtMakeGeometryRequest just returns the resulting value from the parent’s geometry manager.

Children of primitive widgets are always unmanaged; therefore, XtMakeGeometryRequest always returns XtGeometryYes when called by a child of a primitive widget.

The return codes from geometry managers are

__ │

typedef enum {

XtGeometryYes,

XtGeometryNo,

XtGeometryAlmost,

XtGeometryDone

} XtGeometryResult;

│__

The request_mode definitions are from <X11/X.h>.

__ │

│__

The Intrinsics also support the following value.

__ │

│__

XtCWQueryOnly indicates that the corresponding geometry request is only a query as to what would happen if this geometry request were made and that no widgets should actually be changed.

XtMakeGeometryRequest, like the XConfigureWindow Xlib function, uses request_mode to determine which fields in the XtWidgetGeometry structure the caller wants to specify.

The stack_mode definitions are from <X11/X.h>:

__ │

│__

The Intrinsics also support the following value.

__ │

│__

For definition and behavior of Above, Below, TopIf, BottomIf, and Opposite, see Section 3.7 in Xlib — C Language X Interface. XtSMDontChange indicates that the widget wants its current stacking order preserved.

6.3. Resize Requests

To make a simple resize request from a widget, you can use XtMakeResizeRequest as an alternative to XtMakeGeometryRequest.

__ │

XtGeometryResult XtMakeResizeRequest(w, width, height, width_return, height_return)
      Widget w;
      Dimension width, height;
      Dimension *width_return, *height_return;

w

Specifies the widget making the request. Must be of class RectObj or any subclass thereof.

width

Specify the desired widget width and height.

height

width_return Return the allowed widget width and height.

height_return

│__

The XtMakeResizeRequest function, a simple interface to XtMakeGeometryRequest, creates an XtWidgetGeometry structure and specifies that width and height should change by setting request_mode to CWWidth | CWHeight. The geometry manager is free to modify any of the other window attributes (position or stacking order) to satisfy the resize request. If the return value is XtGeometryAlmost, width_return and height_return contain a compromise width and height. If these are acceptable, the widget should immediately call XtMakeResizeRequest again and request that the compromise width and height be applied. If the widget is not interested in XtGeometryAlmost replies, it can pass NULL for width_return and height_return.

6.4. Potential Geometry Changes

Sometimes a geometry manager cannot respond to a geometry request from a child without first making a geometry request to the widget’s own parent (the original requestor’s grandparent). If the request to the grandparent would allow the parent to satisfy the original request, the geometry manager can make the intermediate geometry request as if it were the originator. On the other hand, if the geometry manager already has determined that the original request cannot be completely satisfied (for example, if it always denies position changes), it needs to tell the grandparent to respond to the intermediate request without actually changing the geometry because it does not know if the child will accept the compromise. To accomplish this, the geometry manager uses XtCWQueryOnly in the intermediate request.

When XtCWQueryOnly is used, the geometry manager needs to cache enough information to exactly reconstruct the intermediate request. If the grandparent’s response to the intermediate query was XtGeometryAlmost, the geometry manager needs to cache the entire reply geometry in the event the child accepts the parent’s compromise.

If the grandparent’s response was XtGeometryAlmost, it may also be necessary to cache the entire reply geometry from the grandparent when XtCWQueryOnly is not used. If the geometry manager is still able to satisfy the original request, it may immediately accept the grandparent’s compromise and then act on the child’s request. If the grandparent’s compromise geometry is insufficient to allow the child’s request and if the geometry manager is willing to offer a different compromise to the child, the grandparent’s compromise should not be accepted until the child has accepted the new compromise.

Note that a compromise geometry returned with XtGeometryAlmost is guaranteed only for the next call to the same widget; therefore, a cache of size 1 is sufficient.

6.5. Child Geometry Management: The geometry_manager Procedure

The geometry_manager procedure pointer in a composite widget class is of type XtGeometryHandler.

__ │

typedef XtGeometryResult (*XtGeometryHandler)(Widget, XtWidgetGeometry*, XtWidgetGeometry*);
      Widget w;
      XtWidgetGeometry *request;
      XtWidgetGeometry *geometry_return;

w

Passes the widget making the request.

request

Passes the new geometry the child desires.

geometry_return Passes a geometry structure in which the geometry manager may store a compromise.

│__

A class can inherit its superclass’s geometry manager during class initialization.

A bit set to zero in the request’s request_mode field means that the child widget does not care about the value of the corresponding field, so the geometry manager can change this field as it wishes. A bit set to 1 means that the child wants that geometry element set to the value in the corresponding field.

If the geometry manager can satisfy all changes requested and if XtCWQueryOnly is not specified, it updates the widget’s x, y, width, height, and border_width fields appropriately. Then, it returns XtGeometryYes, and the values pointed to by the geometry_return argument are undefined. The widget’s window is moved and resized automatically by XtMakeGeometryRequest.

Homogeneous composite widgets often find it convenient to treat the widget making the request the same as any other widget, including reconfiguring it using XtConfigureWidget or XtResizeWidget as part of its layout process, unless XtCWQueryOnly is specified. If it does this, it should return XtGeometryDone to inform XtMakeGeometryRequest that it does not need to do the configuration itself.

Note

To remain compatible with layout techniques used in older widgets (before XtGeometryDone was added to the Intrinsics), a geometry manager should avoid using XtResizeWidget or XtConfigureWidget on the child making the request because the layout process of the child may be in an intermediate state in which it is not prepared to handle a call to its resize procedure. A self-contained widget set may choose this alternative geometry management scheme, however, provided that it clearly warns widget developers of the compatibility consequences.

Although XtMakeGeometryRequest resizes the widget’s window (if the geometry manager returns XtGeometryYes), it does not call the widget class’s resize procedure. The requesting widget must perform whatever resizing calculations are needed explicitly.

If the geometry manager disallows the request, the widget cannot change its geometry. The values pointed to by geometry_return are undefined, and the geometry manager returns XtGeometryNo.

Sometimes the geometry manager cannot satisfy the request exactly but may be able to satisfy a similar request. That is, it could satisfy only a subset of the requests (for example, size but not position) or a lesser request (for example, it cannot make the child as big as the request but it can make the child bigger than its current size). In such cases, the geometry manager fills in the structure pointed to by geometry_return with the actual changes it is willing to make, including an appropriate request_mode mask, and returns XtGeometryAlmost. If a bit in geometry_return->request_mode is zero, the geometry manager agrees not to change the corresponding value if geometry_return is used immediately in a new request. If a bit is 1, the geometry manager does change that element to the corresponding value in geometry_return. More bits may be set in geometry_return->request_mode than in the original request if the geometry manager intends to change other fields should the child accept the compromise.

When XtGeometryAlmost is returned, the widget must decide if the compromise suggested in geometry_return is acceptable. If it is, the widget must not change its geometry directly; rather, it must make another call to XtMakeGeometryRequest.

If the next geometry request from this child uses the geometry_return values filled in by the geometry manager with an XtGeometryAlmost return and if there have been no intervening geometry requests on either its parent or any of its other children, the geometry manager must grant the request, if possible. That is, if the child asks immediately with the returned geometry, it should get an answer of XtGeometryYes. However, dynamic behavior in the user’s window manager may affect the final outcome.

To return XtGeometryYes, the geometry manager frequently rearranges the position of other managed children by calling XtMoveWidget. However, a few geometry managers may sometimes change the size of other managed children by calling XtResizeWidget or XtConfigureWidget. If XtCWQueryOnly is specified, the geometry manager must return data describing how it would react to this geometry request without actually moving or resizing any widgets.

Geometry managers must not assume that the request and geometry_return arguments point to independent storage. The caller is permitted to use the same field for both, and the geometry manager must allocate its own temporary storage, if necessary.

6.6. Widget Placement and Sizing

To move a sibling widget of the child making the geometry request, the parent uses XtMoveWidget.

__ │

void XtMoveWidget(w, x, y)
      Widget w;
      Position x;
      Position y;

w

Specifies the widget. Must be of class RectObj or any subclass thereof.

x

y

Specify the new widget x and y coordinates.

│__

The XtMoveWidget function returns immediately if the specified geometry fields are the same as the old values. Otherwise, XtMoveWidget writes the new x and y values into the object and, if the object is a widget and is realized, issues an Xlib XMoveWindow call on the widget’s window.

To resize a sibling widget of the child making the geometry request, the parent uses XtResizeWidget.

__ │

void XtResizeWidget(w, width, height, border_width)
      Widget w;
      Dimension width;
      Dimension height;
      Dimension border_width;

w

Specifies the widget. Must be of class RectObj or any subclass thereof.

width

height

border_width Specify the new widget size.

│__

The XtResizeWidget function returns immediately if the specified geometry fields are the same as the old values. Otherwise, XtResizeWidget writes the new width, height, and border_width values into the object and, if the object is a widget and is realized, issues an XConfigureWindow call on the widget’s window.

If the new width or height is different from the old values, XtResizeWidget calls the object’s resize procedure to notify it of the size change.

To move and resize the sibling widget of the child making the geometry request, the parent uses XtConfigureWidget.

__ │

void XtConfigureWidget(w, x, y, width, height, border_width)
      Widget w;
      Position x;
      Position y;
      Dimension width;
      Dimension height;
      Dimension border_width;

w

Specifies the widget. Must be of class RectObj or any subclass thereof.

x

y

Specify the new widget x and y coordinates.

width

height

border_width Specify the new widget size.

│__

The XtConfigureWidget function returns immediately if the specified new geometry fields are all equal to the current values. Otherwise, XtConfigureWidget writes the new x, y, width, height, and border_width values into the object and, if the object is a widget and is realized, makes an Xlib XConfigureWindow call on the widget’s window.

If the new width or height is different from its old value, XtConfigureWidget calls the object’s resize procedure to notify it of the size change; otherwise, it simply returns.

To resize a child widget that already has the new values of its width, height, and border width, the parent uses XtResizeWindow.

__ │

void XtResizeWindow(w)
      Widget w;

w

Specifies the widget. Must be of class Core or any subclass thereof.

│__

The XtResizeWindow function calls the XConfigureWindow Xlib function to make the window of the specified widget match its width, height, and border width. This request is done unconditionally because there is no inexpensive way to tell if these values match the current values. Note that the widget’s resize procedure is not called.

There are very few times to use XtResizeWindow; instead, the parent should use XtResizeWidget.

6.7. Preferred Geometry

Some parents may be willing to adjust their layouts to accommodate the preferred geometries of their children. They can use XtQueryGeometry to obtain the preferred geometry and, as they see fit, can use or ignore any portion of the response.

To query a child widget’s preferred geometry, use XtQueryGeometry.

__ │

XtGeometryResult XtQueryGeometry(w, intended, preferred_return)
     Widget w;
     XtWidgetGeometry *intended;
     XtWidgetGeometry *preferred_return;

w

Specifies the widget. Must be of class RectObj or any subclass thereof.

intended

Specifies the new geometry the parent plans to give to the child, or NULL.

preferred_return Returns the child widget’s preferred geometry.

│__

To discover a child’s preferred geometry, the child’s parent stores the new geometry in the corresponding fields of the intended structure, sets the corresponding bits in intended.request_mode, and calls XtQueryGeometry. The parent should set only those fields that are important to it so that the child can determine whether it may be able to attempt changes to other fields.

XtQueryGeometry clears all bits in the preferred_return->request_mode field and checks the query_geometry field of the specified widget’s class record. If query_geometry is not NULL, XtQueryGeometry calls the query_geometry procedure and passes as arguments the specified widget, intended, and preferred_return structures. If the intended argument is NULL, XtQueryGeometry replaces it with a pointer to an XtWidgetGeometry structure with request_mode equal to zero before calling the query_geometry procedure.

Note

If XtQueryGeometry is called from within a geometry_manager procedure for the widget that issued XtMakeGeometryRequest or XtMakeResizeRequest, the results are not guaranteed to be consistent with the requested changes. The change request passed to the geometry manager takes precedence over the preferred geometry.

The query_geometry procedure pointer is of type XtGeometryHandler.

__ │

typedef XtGeometryResult (*XtGeometryHandler)(Widget, XtWidgetGeometry*, XtWidgetGeometry*);
      Widget w;
      XtWidgetGeometry *request;
      XtWidgetGeometry *preferred_return;

w

Passes the child widget whose preferred geometry is required.

request

Passes the geometry changes that the parent plans to make.

preferred_return Passes a structure in which the child returns its preferred geometry.

│__

The query_geometry procedure is expected to examine the bits set in request->request_mode, evaluate the preferred geometry of the widget, and store the result in preferred_return (setting the bits in preferred_return->request_mode corresponding to those geometry fields that it cares about). If the proposed geometry change is acceptable without modification, the query_geometry procedure should return XtGeometryYes. If at least one field in preferred_return with a bit set in preferred_return->request_mode is different from the corresponding field in request or if a bit was set in preferred_return->request_mode that was not set in the request, the query_geometry procedure should return XtGeometryAlmost. If the preferred geometry is identical to the current geometry, the query_geometry procedure should return XtGeometryNo.

Note

The query_geometry procedure may assume that no XtMakeResizeRequest or XtMakeGeometryRequest is in progress for the specified widget; that is, it is not required to construct a reply consistent with the requested geometry if such a request were actually outstanding.

After calling the query_geometry procedure or if the query_geometry field is NULL, XtQueryGeometry examines all the unset bits in preferred_return->request_mode and sets the corresponding fields in preferred_return to the current values from the widget instance. If CWStackMode is not set, the stack_mode field is set to XtSMDontChange. XtQueryGeometry returns the value returned by the query_geometry procedure or XtGeometryYes if the query_geometry field is NULL.

Therefore, the caller can interpret a return of XtGeometryYes as not needing to evaluate the contents of the reply and, more important, not needing to modify its layout plans. A return of XtGeometryAlmost means either that both the parent and the child expressed interest in at least one common field and the child’s preference does not match the parent’s intentions or that the child expressed interest in a field that the parent might need to consider. A return value of XtGeometryNo means that both the parent and the child expressed interest in a field and that the child suggests that the field’s current value in the widget instance is its preferred value. In addition, whether or not the caller ignores the return value or the reply mask, it is guaranteed that the preferred_return structure contains complete geometry information for the child.

Parents are expected to call XtQueryGeometry in their layout routine and wherever else the information is significant after change_managed has been called. The first time it is invoked, the changed_managed procedure may assume that the child’s current geometry is its preferred geometry. Thus, the child is still responsible for storing values into its own geometry during its initialize procedure.

6.8. Size Change Management: The resize Procedure

A child can be resized by its parent at any time. Widgets usually need to know when they have changed size so that they can lay out their displayed data again to match the new size. When a parent resizes a child, it calls XtResizeWidget, which updates the geometry fields in the widget, configures the window if the widget is realized, and calls the child’s resize procedure to notify the child. The resize procedure pointer is of type XtWidgetProc.

If a class need not recalculate anything when a widget is resized, it can specify NULL for the resize field in its class record. This is an unusual case and should occur only for widgets with very trivial display semantics. The resize procedure takes a widget as its only argument. The x, y, width, height, and border_width fields of the widget contain the new values. The resize procedure should recalculate the layout of internal data as needed. (For example, a centered Label in a window that changes size should recalculate the starting position of the text.) The widget must obey resize as a command and must not treat it as a request. A widget must not issue an XtMakeGeometryRequest or XtMakeResizeRequest call from its resize procedure.

6

X Toolkit Intrinsics X11 Release 6.4

Chapter 7

Event Management

While Xlib allows the reading and processing of events anywhere in an application, widgets in the X Toolkit neither directly read events nor grab the server or pointer. Widgets register procedures that are to be called when an event or class of events occurs in that widget.

A typical application consists of startup code followed by an event loop that reads events and dispatches them by calling the procedures that widgets have registered. The default event loop provided by the Intrinsics is XtAppMainLoop.

The event manager is a collection of functions to perform the following tasks:

Add or remove event sources other than X server events (in particular, timer interrupts, file input, or POSIX signals).

Query the status of event sources.

Add or remove procedures to be called when an event occurs for a particular widget.

Enable and disable the dispatching of user-initiated events (keyboard and pointer events) for a particular widget.

Constrain the dispatching of events to a cascade of pop-up widgets.

Register procedures to be called when specific events arrive.

Register procedures to be called when the Intrinsics will block.

Enable safe operation in a multi-threaded environment.

Most widgets do not need to call any of the event handler functions explicitly. The normal interface to X events is through the higher-level translation manager, which maps sequences of X events, with modifiers, into procedure calls. Applications rarely use any of the event manager routines besides XtAppMainLoop.

7.1. Adding and Deleting Additional Event Sources

While most applications are driven only by X events, some applications need to incorporate other sources of input into the Intrinsics event-handling mechanism. The event manager provides routines to integrate notification of timer events and file data pending into this mechanism.

The next section describes functions that provide input gathering from files. The application registers the files with the Intrinsics read routine. When input is pending on one of the files, the registered callback procedures are invoked.

7.1.1. Adding and Removing Input Sources

To register a new file as an input source for a given application context, use XtAppAddInput.

__ │

XtInputId XtAppAddInput(app_context, source, condition, proc, client_data)
      XtAppContext app_context;
      int source;
      XtPointer condition;
      XtInputCallbackProc proc;
      XtPointer client_data;

app_context Specifies the application context that identifies the application.

source

Specifies the source file descriptor on a POSIX-based system or other operating-system-dependent device specification.

condition

Specifies the mask that indicates a read, write, or exception condition or some other operating-system-dependent condition.

proc

Specifies the procedure to be called when the condition is found.

client_data Specifies an argument passed to the specified procedure when it is called.

│__

The XtAppAddInput function registers with the Intrinsics read routine a new source of events, which is usually file input but can also be file output. Note that file should be loosely interpreted to mean any sink or source of data. XtAppAddInput also specifies the conditions under which the source can generate events. When an event is pending on this source, the callback procedure is called.

The legal values for the condition argument are operating-system-dependent. On a POSIX-based system, source is a file number and the condition is some union of the following:

XtInputReadMask

Specifies that proc is to be called when source has data to be read.

XtInputWriteMask

Specifies that proc is to be called when source is ready for writing.

XtInputExceptMask

Specifies that proc is to be called when source has exception data.

Callback procedure pointers used to handle file events are of type XtInputCallbackProc.

__ │

typedef void (*XtInputCallbackProc)(XtPointer, int*, XtInputId*);
      XtPointer client_data;
      int *source;
      XtInputId *id;

client_data Passes the client data argument that was registered for this procedure in XtAppAddInput.

source

Passes the source file descriptor generating the event.

id

Passes the id returned from the corresponding XtAppAddInput call.

│__

See Section 7.12 for information regarding the use of XtAppAddInput in multiple threads.

To discontinue a source of input, use XtRemoveInput.

__ │

void XtRemoveInput(id)
      XtInputId id;

id

Specifies the id returned from the corresponding XtAppAddInput call.

│__

The XtRemoveInput function causes the Intrinsics read routine to stop watching for events from the file source specified by id.

See Section 7.12 for information regarding the use of XtRemoveInput in multiple threads.

7.1.2. Adding and Removing Blocking Notifications

Occasionally it is desirable for an application to receive notification when the Intrinsics event manager detects no pending input from file sources and no pending input from X server event sources and is about to block in an operating system call.

To register a hook that is called immediately prior to event blocking, use XtAppAddBlockHook.

__ │

XtBlockHookId XtAppAddBlockHook(app_context, proc, client_data)
      XtAppContext app_context;
      XtBlockHookProc proc;
      XtPointer client_data;

app_context Specifies the application context that identifies the application.

proc

Specifies the procedure to be called before blocking.

client_data Specifies an argument passed to the specified procedure when it is called.

│__

The XtAppAddBlockHook function registers the specified procedure and returns an identifier for it. The hook procedure proc is called at any time in the future when the Intrinsics are about to block pending some input.

The procedure pointers used to provide notification of event blocking are of type XtBlockHookProc.

__ │

typedef void (*XtBlockHookProc)(XtPointer);
      XtPointer client_data;

client_data Passes the client data argument that was registered for this procedure in XtApp- AddBlockHook.

│__

To discontinue the use of a procedure for blocking notification, use XtRemoveBlockHook.

__ │

void XtRemoveBlockHook(id)
      XtBlockHookId id;

id

Specifies the identifier returned from the corresponding call to XtAppAddBlockHook.

│__

The XtRemoveBlockHook function removes the specified procedure from the list of procedures that are called by the Intrinsics read routine before blocking on event sources.

7.1.3. Adding and Removing Timeouts

The timeout facility notifies the application or the widget through a callback procedure that a specified time interval has elapsed. Timeout values are uniquely identified by an interval id.

To register a timeout callback, use XtAppAddTimeOut.

__ │

XtIntervalId XtAppAddTimeOut(app_context, interval, proc, client_data)
      XtAppContext app_context;
      unsigned long interval;
      XtTimerCallbackProc proc;
      XtPointer client_data;

app_context Specifies the application context for which the timer is to be set.

interval

Specifies the time interval in milliseconds.

proc

Specifies the procedure to be called when the time expires.

client_data Specifies an argument passed to the specified procedure when it is called.

│__

The XtAppAddTimeOut function creates a timeout and returns an identifier for it. The timeout value is set to interval. The callback procedure proc is called when XtAppNextEvent or XtAppProcessEvent is next called after the time interval elapses, and then the timeout is removed.

Callback procedure pointers used with timeouts are of type XtTimerCallbackProc.

__ │

typedef void (*XtTimerCallbackProc)(XtPointer, XtIntervalId*);
      XtPointer client_data;
      XtIntervalId *timer;

client_data Passes the client data argument that was registered for this procedure in XtAppAddTimeOut.

timer

Passes the id returned from the corresponding XtAppAddTimeOut call.

│__

See Section 7.12 for information regarding the use of XtAppAddTimeOut in multiple threads.

To clear a timeout value, use XtRemoveTimeOut.

__ │

void XtRemoveTimeOut(timer)
      XtIntervalId timer;

timer

Specifies the id for the timeout request to be cleared.

│__

The XtRemoveTimeOut function removes the pending timeout. Note that timeouts are automatically removed once they trigger.

Please refer to Section 7.12 for information regarding the use of XtRemoveTimeOut in multiple threads.

7.1.4. Adding and Removing Signal Callbacks

The signal facility notifies the application or the widget through a callback procedure that a signal or other external asynchronous event has occurred. The registered callback procedures are uniquely identified by a signal id.

Prior to establishing a signal handler, the application or widget should call XtAppAddSignal and store the resulting identifier in a place accessible to the signal handler. When a signal arrives, the signal handler should call XtNoticeSignal to notify the Intrinsics that a signal has occured. To register a signal callback use XtAppAddSignal.

__ │

XtSignalId XtAppAddSignal(app_context, proc, client_data)
      XtAppContext app_context;
      XtSignalCallbackProc proc;
      XtPointer client_data;

app_context Specifies the application context that identifies the application.

proc

Specifies the procedure to be called when the signal is noticed.

client_data Specifies an argument passed to the specified procedure when it is called.

│__

The callback procedure pointers used to handle signal events are of type XtSignalCallbackProc.

__ │

typedef void (*XtSignalCallbackProc)(XtPointer, XtSignalId*);

XtPointer client_data;

XtSignalId *id;

client_data Passes the client data argument that was registered for this procedure in XtAppAddSignal.

id

Passes the id returned from the corresponding XtAppAddSignal call.

│__

To notify the Intrinsics that a signal has occured, use XtNoticeSignal.

__ │

void XtNoticeSignal(id)
      XtSignalId id;

id

Specifies the id returned from the corresponding XtAppAddSignal call.

│__

On a POSIX-based system, XtNoticeSignal is the only Intrinsics function that can safely be called from a signal handler. If XtNoticeSignal is invoked multiple times before the Intrinsics are able to invoke the registered callback, the callback is only called once. Logically, the Intrinsics maintain ‘‘pending’’ flag for each registered callback. This flag is initially False and is set to True by XtNoticeSignal. When XtAppNextEvent or XtAppProcessEvent (with a mask including XtIMSignal) is called, all registered callbacks with ‘‘pending’’ True are invoked and the flags are reset to False.

If the signal handler wants to track how many times the signal has been raised, it can keep its own private counter. Typically the handler would not do any other work; the callback does the actual processing for the signal. The Intrinsics never block signals from being raised, so if a given signal can be raised multiple times before the Intrinsics can invoke the callback for that signal, the callback must be designed to deal with this. In another case, a signal might be raised just after the Intrinsics sets the pending flag to False but before the callback can get control, in which case the pending flag will still be True after the callback returns, and the Intrinsics will invoke the callback again, even though all of the signal raises have been handled. The callback must also be prepared to handle this case.

To remove a registered signal callback, call XtRemoveSignal.

__ │

void XtRemoveSignal(id)
      XtSignalId id;

id

Specifies the id returned by the corresponding call to XtAppAddSignal.

│__

The client should typically disable the source of the signal before calling XtRemoveSignal. If the signal could have been raised again before the source was disabled and the client wants to process it, then after disabling the source but before calling XtRemoveSignal the client can test for signals with XtAppPending and process them by calling XtAppProcessEvent with the mask XtIMSignal.

7.2. Constraining Events to a Cascade of Widgets

Modal widgets are widgets that, except for the input directed to them, lock out user input to the application.

When a modal menu or modal dialog box is popped up using XtPopup, user events (keyboard and pointer events) that occur outside the modal widget should be delivered to the modal widget or ignored. In no case will user events be delivered to a widget outside the modal widget.

Menus can pop up submenus, and dialog boxes can pop up further dialog boxes to create a pop-up cascade. In this case, user events may be delivered to one of several modal widgets in the cascade.

Display-related events should be delivered outside the modal cascade so that exposure events and the like keep the application’s display up-to-date. Any event that occurs within the cascade is delivered as usual. The user events delivered to the most recent spring-loaded shell in the cascade when they occur outside the cascade are called remap events and are KeyPress, KeyRelease, ButtonPress, and ButtonRelease. The user events ignored when they occur outside the cascade are MotionNotify and EnterNotify. All other events are delivered normally. In particular, note that this is one way in which widgets can receive LeaveNotify events without first receiving EnterNotify events; they should be prepared to deal with this, typically by ignoring any unmatched LeaveNotify events.

XtPopup uses the XtAddGrab and XtRemoveGrab functions to constrain user events to a modal cascade and subsequently to remove a grab when the modal widget is popped down.

To constrain or redirect user input to a modal widget, use XtAddGrab.

__ │

void XtAddGrab(w, exclusive, spring_loaded)
      Widget w;
      Boolean exclusive;
      Boolean spring_loaded;

w

Specifies the widget to add to the modal cascade. Must be of class Core or any subclass thereof.

exclusive

Specifies whether user events should be dispatched exclusively to this widget or also to previous widgets in the cascade.

spring_loaded Specifies whether this widget was popped up because the user pressed a pointer button.

│__

The XtAddGrab function appends the widget to the modal cascade and checks that exclusive is True if spring_loaded is True. If this condition is not met, XtAddGrab generates a warning message.

The modal cascade is used by XtDispatchEvent when it tries to dispatch a user event. When at least one modal widget is in the widget cascade, XtDispatchEvent first determines if the event should be delivered. It starts at the most recent cascade entry and follows the cascade up to and including the most recent cascade entry added with the exclusive parameter True.

This subset of the modal cascade along with all descendants of these widgets comprise the active subset. User events that occur outside the widgets in this subset are ignored or remapped. Modal menus with submenus generally add a submenu widget to the cascade with exclusive False. Modal dialog boxes that need to restrict user input to the most deeply nested dialog box add a subdialog widget to the cascade with exclusive True. User events that occur within the active subset are delivered to the appropriate widget, which is usually a child or further descendant of the modal widget.

Regardless of where in the application they occur, remap events are always delivered to the most recent widget in the active subset of the cascade registered with spring_loaded True, if any such widget exists. If the event occurred in the active subset of the cascade but outside the spring-loaded widget, it is delivered normally before being delivered also to the spring-loaded widget. Regardless of where it is dispatched, the Intrinsics do not modify the contents of the event.

To remove the redirection of user input to a modal widget, use XtRemoveGrab.

__ │

void XtRemoveGrab(w)
      Widget w;

w

Specifies the widget to remove from the modal cascade.

│__

The XtRemoveGrab function removes widgets from the modal cascade starting at the most recent widget up to and including the specified widget. It issues a warning if the specified widget is not on the modal cascade.

7.2.1. Requesting Key and Button Grabs

The Intrinsics provide a set of key and button grab interfaces that are parallel to those provided by Xlib and that allow the Intrinsics to modify event dispatching when necessary. X Toolkit applications and widgets that need to passively grab keys or buttons or actively grab the keyboard or pointer should use the following Intrinsics routines rather than the corresponding Xlib routines.

To passively grab a single key of the keyboard, use XtGrabKey.

__ │

void XtGrabKey(widget, keycode, modifiers, owner_events, pointer_mode, keyboard_mode)
      Widget widget;
      KeyCode keycode;
      Modifiers modifiers;
      Boolean owner_events;
      int pointer_mode, keyboard_mode;

widget

Specifies the widget in whose window the key is to be grabbed. Must be of class Core or any subclass thereof.

keycode

modifiers

owner_events

pointer_mode

keyboard_mode Specify arguments to XGrabKey; see Section 12.2 in Xlib — C Language X Interface.

│__

XtGrabKey calls XGrabKey specifying the widget’s window as the grab window if the widget is realized. The remaining arguments are exactly as for XGrabKey. If the widget is not realized, or is later unrealized, the call to XGrabKey is performed (again) when the widget is realized and its window becomes mapped. In the future, if XtDispatchEvent is called with a KeyPress event matching the specified keycode and modifiers (which may be AnyKey or AnyModifier, respectively) for the widget’s window, the Intrinsics will call XtUngrabKeyboard with the timestamp from the KeyPress event if either of the following conditions is true:

There is a modal cascade and the widget is not in the active subset of the cascade and the keyboard was not previously grabbed, or

XFilterEvent returns True.

To cancel a passive key grab, use XtUngrabKey.

__ │

void XtUngrabKey(widget, keycode, modifiers)
      Widget widget;
      KeyCode keycode;
      Modifiers modifiers;

widget

Specifies the widget in whose window the key was grabbed.

keycode

modifiers

Specify arguments to XUngrabKey; see Section 12.2 in Xlib — C Language X Interface.

│__

The XtUngrabKey procedure calls XUngrabKey specifying the widget’s window as the ungrab window if the widget is realized. The remaining arguments are exactly as for XUngrabKey. If the widget is not realized, XtUngrabKey removes a deferred XtGrabKey request, if any, for the specified widget, keycode, and modifiers.

To actively grab the keyboard, use XtGrabKeyboard.

__ │

int XtGrabKeyboard(widget, owner_events, pointer_mode, keyboard_mode, time)
      Widget widget;
      Boolean owner_events;
      int pointer_mode, keyboard_mode;
      Time time;

widget

Specifies the widget for whose window the keyboard is to be grabbed. Must be of class Core or any subclass thereof.

owner_events

pointer_mode

keyboard_mode

time

Specify arguments to XGrabKeyboard; see Section 12.2 in Xlib — C Language X Interface.

│__

If the specified widget is realized, XtGrabKeyboard calls XGrabKeyboard specifying the widget’s window as the grab window. The remaining arguments and return value are exactly as for XGrabKeyboard. If the widget is not realized, XtGrabKeyboard immediately returns GrabNotViewable. No future automatic ungrab is implied by XtGrabKeyboard.

To cancel an active keyboard grab, use XtUngrabKeyboard.

__ │

void XtUngrabKeyboard(widget, time)
      Widget widget;
      Time time;

widget

Specifies the widget that has the active keyboard grab.

time

Specifies the additional argument to XUngrabKeyboard; see Section 12.2 in Xlib — C Language X Interface.

│__

XtUngrabKeyboard calls XUngrabKeyboard with the specified time.

To passively grab a single pointer button, use XtGrabButton.

__ │

void XtGrabButton(widget, button, modifiers, owner_events, event_mask, pointer_mode,
                  keyboard_mode, confine_to, cursor)
      Widget widget;
      int button;
      Modifiers modifiers;
      Boolean owner_events;
      unsigned int event_mask;
      int pointer_mode, keyboard_mode;
      Window confine_to;
      Cursor cursor;

widget

Specifies the widget in whose window the button is to be grabbed. Must be of class Core or any subclass thereof.

button

modifiers

owner_events

event_mask

pointer_mode

keyboard_mode

confine_to

cursor

Specify arguments to XGrabButton; see Section 12.1 in Xlib — C Language X Interface.

│__

XtGrabButton calls XGrabButton specifying the widget’s window as the grab window if the widget is realized. The remaining arguments are exactly as for XGrabButton. If the widget is not realized, or is later unrealized, the call to XGrabButton is performed (again) when the widget is realized and its window becomes mapped. In the future, if XtDispatchEvent is called with a ButtonPress event matching the specified button and modifiers (which may be AnyButton or AnyModifier, respectively) for the widget’s window, the Intrinsics will call XtUngrabPointer with the timestamp from the ButtonPress event if either of the following conditions is true:

There is a modal cascade and the widget is not in the active subset of the cascade and the pointer was not previously grabbed, or

XFilterEvent returns True.

To cancel a passive button grab, use XtUngrabButton.

__ │

void XtUngrabButton(widget, button, modifiers)
      Widget widget;
      unsigned int button;
      Modifiers modifiers;

widget

Specifies the widget in whose window the button was grabbed.

button

modifiers

Specify arguments to XUngrabButton; see Section 12.1 in Xlib — C Language X Interface.

│__

The XtUngrabButton procedure calls XUngrabButton specifying the widget’s window as the ungrab window if the widget is realized. The remaining arguments are exactly as for XUngrabButton. If the widget is not realized, XtUngrabButton removes a deferred XtGrabButton request, if any, for the specified widget, button, and modifiers.

To actively grab the pointer, use XtGrabPointer.

__ │

int XtGrabPointer(widget, owner_events, event_mask, pointer_mode, keyboard_mode,
                  confine_to, cursor, time)
      Widget widget;
      Boolean owner_events;
      unsigned int event_mask;
      int pointer_mode, keyboard_mode;
      Window confine_to;
      Cursor cursor;
      Time time;

widget

Specifies the widget for whose window the pointer is to be grabbed. Must be of class Core or any subclass thereof.

owner_events

event_mask

pointer_mode

keyboard_mode

confine_to

cursor

time

Specify arguments to XGrabPointer; see Section 12.1 in Xlib — C Language X Interface.

│__

If the specified widget is realized, XtGrabPointer calls XGrabPointer, specifying the widget’s window as the grab window. The remaining arguments and return value are exactly as for XGrabPointer. If the widget is not realized, XtGrabPointer immediately returns GrabNotViewable. No future automatic ungrab is implied by XtGrabPointer.

To cancel an active pointer grab, use XtUngrabPointer.

__ │

void XtUngrabPointer(widget, time)
      Widget widget;
      Time time;

widget

Specifies the widget that has the active pointer grab.

time

Specifies the time argument to XUngrabPointer; see Section 12.1 in Xlib — C Language X Interface.

│__

XtUngrabPointer calls XUngrabPointer with the specified time.

7.3. Focusing Events on a Child

To redirect keyboard input to a normal descendant of a widget without calling