📄 unx47.htm
字号:
<HTML>
<HEAD>
<TITLE>UNIX Unleashed unx47.htm</TITLE>
<LINK REL="ToC" HREF="index.htm">
<LINK REL="Next" HREF="unxwotcd.htm">
<LINK REL="Previous" HREF="unx46.htm"></HEAD>
<BODY TEXT="#000000" LINK="#0000FF" VLINK="#800080" bgcolor=white>
<P><A HREF="unx46.htm"><IMG SRC="bluprev.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Previous Page"></A>
<A HREF="index.htm"><IMG SRC="blutoc.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="TOC"></A>
<A HREF="unxwotcd.htm"><IMG SRC="blunext.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Next Page"></A>
<A HREF="index.htm"><IMG SRC="bluprev.gif" WIDTH = 32 HEIGHT = 32 BORDER = 0 ALT="Home"></A>
</P><UL>
<UL>
<LI>
<A HREF="#I1">47 — UNIX Graphical User Interfaces for Programmers</A></LI>
<UL>
<UL>
<UL>
<LI>
<A HREF="#I2">By Karman Husain</A></LI></UL></UL>
<LI>
<A HREF="#I3">Writing Motif Applications</A></LI>
<LI>
<A HREF="#I4">Naming Conventions</A></LI>
<LI>
<A HREF="#I5">Writing Your First Motif Application</A></LI>
<LI>
<A HREF="#I6">Compiling This Application</A></LI>
<LI>
<A HREF="#I7">The Widget Hierarchy</A></LI>
<UL>
<LI>
<A HREF="#I8">Core</A></LI>
<LI>
<A HREF="#I9">XmPrimitive</A></LI>
<LI>
<A HREF="#I10">XmManager</A></LI></UL>
<LI>
<A HREF="#I11">The Label Widget</A></LI>
<LI>
<A HREF="#I12">Strings in Motif Compound Strings</A></LI>
<LI>
<A HREF="#I13">The PushButton Widget</A></LI>
<UL>
<LI>
<A HREF="#I14">The Toggle Button Widget</A></LI></UL>
<LI>
<A HREF="#I15">Convenience Functions</A></LI>
<LI>
<A HREF="#I16">The List Widget</A></LI>
<LI>
<A HREF="#I17">The Scrollbar Widget</A></LI>
<LI>
<A HREF="#I18">The Text Widget</A></LI>
<LI>
<A HREF="#I19">The Bulletin Board Widget</A></LI>
<LI>
<A HREF="#I20">The RowColumn Widget</A></LI>
<LI>
<A HREF="#I21">The Form Widget</A></LI>
<LI>
<A HREF="#I22">Designing Layouts</A></LI>
<LI>
<A HREF="#I23">Menus</A></LI>
<UL>
<LI>
<A HREF="#I24">Popup</A></LI>
<LI>
<A HREF="#I25">The Menu Bar</A></LI>
<LI>
<A HREF="#I26">The Options Menu</A></LI>
<LI>
<A HREF="#I27">Accelerators and Mnemonics</A></LI></UL>
<LI>
<A HREF="#I28">Dialog Boxes</A></LI>
<UL>
<LI>
<A HREF="#I29">Modes of a Dialog Box</A></LI></UL>
<LI>
<A HREF="#I30">Events</A></LI>
<LI>
<A HREF="#I31">Pointer Events</A></LI>
<LI>
<A HREF="#I32">Keyboard Events</A></LI>
<LI>
<A HREF="#I33">Window Crossing Events</A></LI>
<UL>
<LI>
<A HREF="#I34">Event Masks</A></LI>
<LI>
<A HREF="#I35">Managing the Queue</A></LI>
<LI>
<A HREF="#I36">Work Procedures</A></LI>
<LI>
<A HREF="#I37">Using Timeouts</A></LI>
<LI>
<A HREF="#I38">Other Sources</A></LI></UL>
<LI>
<A HREF="#I39">Handling Output</A></LI>
<UL>
<LI>
<A HREF="#I40">The Graphics Context</A></LI></UL>
<LI>
<A HREF="#I41">Drawing Lines, Points, Arcs, and Polygons</A></LI>
<UL>
<LI>
<A HREF="#I42">Drawing a Line</A></LI>
<LI>
<A HREF="#I43">Drawing a Point</A></LI>
<LI>
<A HREF="#I44">Drawing Arcs</A></LI>
<LI>
<A HREF="#I45">Using Fonts and Fontlists</A></LI></UL>
<LI>
<A HREF="#I46">The X Color Model</A></LI>
<UL>
<LI>
<A HREF="#I47">Pixmaps, Bitmaps, and Images</A></LI></UL>
<LI>
<A HREF="#I48">GUI Builders and Management Tools</A></LI>
<LI>
<A HREF="#I49">A Few Commercial GUI Builders</A></LI>
<LI>
<A HREF="#I50">What You Have Learned in this Chapter</A></LI>
<LI>
<A HREF="#I51">Acknowledgements</A></LI>
<LI>
<A HREF="#I52">References</A></LI></UL></UL></UL>
<H2 ALIGN="CENTER">
<CENTER><A ID="I1" NAME="I1">
<FONT SIZE=5><B>47 — UNIX Graphical User Interfaces for Programmers</B>
<BR></FONT></A></CENTER></H2>
<H5 ALIGN="CENTER">
<CENTER><A ID="I2" NAME="I2">
<FONT SIZE=3><B>By Karman Husain</B>
<BR></FONT></A></CENTER></H5>
<H3 ALIGN="CENTER">
<CENTER><A ID="I3" NAME="I3">
<FONT SIZE=4><B>Writing Motif Applications</B>
<BR></FONT></A></CENTER></H3>
<P>This chapter will serve as an introduction to event-driven programming. After reading this chapter, you will have enough information to write your own application. Keep in mind, though, that writing Motif applications is perhaps not the easiest task in
the world, nor is it the most complex. As with any other system, you will learn new ways of doing things. In Motif, you have to get used to programming in an event-driven environment. A typical C application runs from start to finish at its own pace. When
it needs information, it looks for it from a source such as a file or the keyboard, and gets the information almost as soon as it asks for it. However, in event-driven programming, applications are executed on an asynchronous basis. That is, the order and
time of arrival of each event is not deterministic. The application waits for an event to occur and then proceeds based on that event. Thus the term "event-driven programming."
<BR></P>
<P>In the case of X Window programming, an application must wait for events on the input queue. Similarly, a server waits for an event from a client and then responds based on the type of event received. This event handling and other aspects of X
programming are handled by a toolkit called the Xt ToolkitIntrinsics, or Xt for short.
<BR></P>
<P>In Xt, an application typically runs in a loop forever. This loop is called an event loop, and an application enters it by calling the function XtAppMainLoop. While in this event loop, the application will always wait for an event, and will either
handle it itself or more likely "dispatch" the event to a window or widget.
<BR></P>
<P>A widget registers functions that it wants called when a type of event is received. This function is called a callback function. In most cases, a callback function is independent of the entire application. For example, some widgets will redraw
themselves when a Pointer button is clicked in their display area. In this case, they would register a redraw callback function on a button click. Xt also supports "actions," which allow applications to register a function with Xt. An action is
called when one or more sequences of specific event types are received. For example, Ctrl+X would call the exit function. The mapping of the action to an event is handled through a translation table within Xt. Functions which handle specific events are
referred to as "event handlers."
<BR></P>
<H3 ALIGN="CENTER">
<CENTER><A ID="I4" NAME="I4">
<FONT SIZE=4><B>Naming Conventions</B>
<BR></FONT></A></CENTER></H3>
<P>By default, most X lib functions begin with the letter "X", but sadly this is not a rule to rely on. Several macros and functions do not begin with X, such as BlackColor, WhiteColor, etc. In general, if a name in Xlibrary begins with X, it's a
function. If a name begins with any other capital letter, it's a macro.
<BR></P>
<P>With Xt, the naming conventions get better, but only slightly. In Xt, macros are not differentiated from functions.
<BR></P>
<HR ALIGN=CENTER>
<NOTE>
<IMG SRC="imp.gif" WIDTH = 68 HEIGHT = 35><B>TIP:</B> Do not rely on the name of a toolkit function to tell you whether it's a macro or not. Read the manual.
<BR></NOTE>
<HR ALIGN=CENTER>
<P>In Motif, almost all declarations begin with Xm. XmC refers to a class. XmR refers to a resource. XmN refers to a name. XtN refers to Xt resources used by Motif.
<BR></P>
<P>In Motif, declarations ending with the words WidgetClass define the base class for a type of widget. Other conventions to remember about parameters passed in most X library function calls are: Width is always to the left of height. x is to the left of
y. Source is to the left of destination. Display is usually the first parameter.
<BR></P>
<P>With practice, you will be able to identify the types of parameters to pass and which toolkit a function belongs to, and you'll be able to "guess" what parameters an unknown function might expect.
<BR></P>
<H3 ALIGN="CENTER">
<CENTER><A ID="I5" NAME="I5">
<FONT SIZE=4><B>Writing Your First Motif Application</B>
<BR></FONT></A></CENTER></H3>
<P>See 47_1.c on the CD-ROM for a complete listing showing the basic format for a Motif application.
<BR></P>
<P>The listing shows an application in which a button attaches itself to the bottom of a form. No matter how you resize the window, the button will always be on the bottom. The application does the following things:
<BR></P>
<UL>
<LI>Initializes the toolkit to get a Shell widget.
<BR>
<BR></LI>
<LI>Makes a Form widget.
<BR>
<BR></LI>
<LI>Manages all widgets as they are created.
<BR>
<BR></LI>
<LI>Makes a Button widget and puts it on top of the Form widget.
<BR>
<BR></LI>
<LI>Attaches a callback function to the button.
<BR>
<BR></LI>
<LI>Realizes the widget (that is, makes the hierarchy visible).
<BR>
<BR></LI>
<LI>Goes into its event loop.
<BR>
<BR></LI></UL>
<P>Let's look at the application in more detail. The #include files in the beginning of the file are required for most applications. Note the following files:
<BR></P>
<PRE>#include <X11/Intrinsic.h>
#include <Xm/Xm.h></PRE>
<P>These declare the definitions for XtIntrinsics and Motif, respectively. Some systems may not require the first inclusion, but it's harmless to put it in there because multiple inclusions of Intrinsic.h are permitted. In addition, each Motif widget
requires its own header file. In Listing 47.1, the two widgets Form and PushButton require the following header files:
<BR></P>
<PRE>#include <Xm/Form.h>
#include <Xm/PushB.h></PRE>
<P>The variables in the program are declared in the following lines:
<BR></P>
<PRE>Widget top;
XtAppContext app;
Widget aForm;
Widget aButton;
int n;</PRE>
<P>The top, aForm, and aButton represent widgets. Even though their widget types are different, they can all be referred to as widgets.
<BR></P>
<P>The XtAppContext type is an "opaque" type, which means that a Motif programmer does not have to be concerned about how the type is set up. Widgets are opaque types as well, because only the items that are required by the programmer are
visible.
<BR></P>
<P>The first executable line of the program calls the XtAppInitialize() function. This will initialize the Xt toolkit and create an application shell and context for the rest of the application. This value is returned to the widget "top" (for top
level shell). This widget will provide the interface between the window manager and the rest of the widgets in this application.
<BR></P>
<P>The application then creates a Form widget on this top-level widget. A Form widget places other widgets on top of itself. It is a Manager widget because it "manages" other widgets.
<BR></P>
<P>There are two steps for displaying a widget: Managing it and realizing it.
<BR></P>
<P>Managing a widget allows it to be visible. If a widget is unmanaged, it will never be visible. By managing a widget, the program gives the viewing control over to the windowing system so it can display it. If the parent widget is unmanaged, any child
widgets remain invisible even if managed.
<BR></P>
<P>Realizing a widget actually creates all the subwindows under an application and displays them. Normally only the top-level widget is realized after all the widgets are managed. This call will realize all the children of this widget.
<BR></P>
<P>Note that realizing a widget takes time. A typical program will manage all the widgets except the topmost widget. This way the application will only call XtRealizeWidget on the topmost parent when the entire tree has to be displayed. You have to realize
a widget at least once, but you can manage and unmanage widgets as you want to display or hide them.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -