Linux 版 (精华区)

发信人: netiscpu (说不如做), 信区: Linux
标  题: [B] Red Hat Linux Unleashed (33)
发信站: 紫 丁 香 (Sat Jul 25 05:00:07 1998), 转信

   Programming XView Applications
     _________________________________________________________________
                                      
               o A Note About CDE
               o Overview
               o Requirements
                    # Header Files
                    # Sample Application
                    # Initialization
                    # Creating Objects
                    # Exiting an Application
               o Frames
               o Command Frames
               o Setting Colors on Frames
               o Canvases
               o Buttons
               o List Items
               o Scale Bars
               o Text Windows
               o Where To Go from Here
               o Summary
       
     _________________________________________________________________
                                      
   33
   
   
   Programming XView Applications
   
   
   In this chapter you will learn how to program in an older, but still
   widely found, OPEN LOOK—based user interface manager called
   XView. You will find this distribution helpful when you work with
   older code or when you port code from the OPEN LOOK style to Motif.
   
   A Note About CDE
   
   
   In March 1993, the Common Open Software Environment (COSE) committees
   adopted the Common Desktop Environment (CDE). CDE is based on the
   Motif interface. Sun Microsystems Inc., the primary developer of OPEN
   LOOK applications, agreed to conform to CDE as well. In short, this
   means that OPEN LOOK interface—based applications will soon be
   out of style. However, applications with an OPEN LOOK interface still
   exist and have to be ported to Motif eventually. A good knowledge of
   how OPEN LOOK applications work will be very beneficial to you if you
   ever have to port old existing code to conform to CDE.
   
   Overview
   
   
   To a programmer, the XView toolkit is an object-oriented toolkit.
   Think of XView objects as building blocks from which the user can
   create complicated applications, and think of each block as part of a
   package. Each package provides properties that you can modify to
   configure the object.
   
   The XView toolkit consists of the objects shown in Figure 33.1. The
   subclasses are derived from the classes to their left. For example,
   Icon is a subclass of Window. Each class is also referred to as a
   package.
   
   Figure 33.1. XView class hierarchy.
   
   Some objects are visible and some are not. The visible objects provide
   the windows, scrollbars, and so on. The invisible objects, such as the
   font, display, or server, provide frameworks that aid in the display
   or layout of visible objects.
   
   When you create an object, you get a handle to the object back from
   the XView libraries. Handles are opaque pointers to structures. This
   means that you can pass information via functions to these objects via
   their handles but you cannot see their structures directly.
   
   The following functions enable you to manipulate all XView objects:
   xv_init() Establishes the connection to the server, initializes the
   notifier (message handler), and loads the resource databases
   xv_create() Creates an object
   xv_destroy() Destroys an object
   xv_find() Finds an object with given criteria; if not found, creates
   the object
   xv_get() Gets an attribute value
   xv_set() Sets an attribute value
   
   There are three categories of attributes: generic attributes apply to
   all objects; common attributes are shared by some, but not all,
   objects; and specific attributes belong to one class of objects only.
   Attributes that are specific to a type of object are prefixed with the
   name of the object; for example, FRAME_*, ICON_*, MENU_*, and so on.
   Common and generic attributes are prefixed by XV_. For example,
   XV_HEIGHT applies to all objects, but FRAME_HEIGHT applies only to
   frame objects.
   
   Each attribute may have different types of values. For example, the
   following code sets a panel_item.

panel_item = (Panel_item) xv_create( masterpanel, PANEL_CYCLE,
XV_HEIGHT, 100,
XV_WIDTH, 50,
PANEL_LABEL_X, 100,
PANEL_LABEL_Y, 100,
PANEL_LABEL_STRING, "Help",
PANEL_CHOICE_STRINGS, "About ... ",
"How to use Help",
"Search Index",
NULL,
NULL);

   Note how the types of values are mixed in this function call. All
   attributes except PANEL_CHOICE_STRINGS take a single argument. The
   PANEL_CHOICE_STRINGS attribute takes a list of arguments. The list is
   terminated with a NULL value.
   
   We will go over the details of each object in this chapter.
   
   Requirements
   
   
   To create an XView program you must link in the XView and OPEN LOOK
   graphics library, which includes all the toolkit functions for you.
   You will also need the X11 library. The command line to use the gcc
   compiler for a simple XView application is
   
$ gcc sample.c -lxview -lolgx -lX11 -o sample

   However, this compile command relies on the fact that your libraries
   are located in /usr/lib or you have links to this location. The XView
   libraries are located in the /usr/openwin/lib directories.
   
   See the sample makefile in Listing 33.1 that you can use with the
   applications in this chapter. To compile a listing from this book,
   type make filename. For example, type make list33_2.
   
   Listing 33.1. Sample makefile for creating XView applications.

CC=gcc
LIBPATH=-L/usr/openwin/lib -L/usr/X11/lib
INCPATH=/usr/openwin/include
LIBS= -lxview -lolgx -lX11
list33_2: list 33_2.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_3: list 33_3.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_4: list 33_4.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_5: list 33_5.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_6: list 33_6.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_7: list 33_7.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_8: list 33_8.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_9: list 33_9.c
$(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@
list33_10: list 33_10.c
 $(CC) $< -I$(INCPATH) $(LIBPATH) $(LIBS) -o $@

   The -lxview in LIBS refers to the libxview.a library. The libxview.a
   library contains the code for all the windows manipulation and
   libolgx.a contains the OPENLOOK graphics library. The libX11.a is
   required by the libxview.a library, and libolgx.a is required by the
   libxview.a library.
   
   Header Files
   
   
   The basic definitions you must use for XView are located in two files:
   xview/generic.h and xview/xview.h in the /usr/openwin/include
   directory tree. The header files required by other packages, such as
   FONT or FRAME, are declared in files of the same name as the package.
   For example, for the FONT package you must use the xview/font.h header
   file. You can include these files more than once.
   
       ______________________________________________________________
                                      
     
     NOTE: In some source distributions, the file generic.h is not
     explicitly called out in the source files. In order to compile
     source files under Linux, you will need the generic.h file.
     
     
       ______________________________________________________________
                                      
   
   Sample Application
   
   
   Take a look at the simple application shown in Listing 33.2, which
   places a window with a Quit button on it.
   
   Listing 33.2. A simple application.

/*
** A sample program to show you how to present items for
** selection to the user.
**
*/
#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/cms.h>
Frame frame;
#define FORE 0
#define BACK 2
int main(int argc, char *argv[])
{
Cms cms;
Panel panel;
void quit();
printf("\n 0\n");
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
cms = (Cms ) xv_create((int)NULL,CMS, /* NULL -> use the default Frame*/
CMS_SIZE, CMS_CONTROL_COLORS + 4,
CMS_CONTROL_CMS, True,
CMS_NAMED_COLORS, "LightBlue", "Blue", "Red", "Green", NULL,
NULL);
frame = (Frame)xv_create((int)NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 200,
XV_HEIGHT, 100,
NULL);
xv_set(frame,
WIN_CMS, cms,
WIN_FOREGROUND_COLOR, CMS_CONTROL_COLORS + FORE,
WIN_BACKGROUND_COLOR, CMS_CONTROL_COLORS + BACK,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}

       ______________________________________________________________
                                      
     
     NOTE: At the chance of being too literal, don't forget to run the
     applications in this chapter from an X terminal. The programs will
     not run without the X server.
     
     
       ______________________________________________________________
                                      
   The output from this application is shown in Figure 33.2. There are
   several things that you should note about this sample application.
   
   Figure 33.2. A sample XView application.
     * The XV toolkit is initialized as soon as possible in the
       application with the xv_init call.
       
     * All attribute values to the xv_create() function call are
       terminated with a NULL parameter.
       
     * The (Frame) cast is used to override the default returned value
       from xv_create().
       
     * The <xview/generic.h> header file is used to get all the required
       definitions for the file.
       
       ______________________________________________________________
                                      
     
     NOTE: The figures shown in this chapter depict the program being
     run from the dwm window manager.
     
     
       ______________________________________________________________
                                      
   
   Initialization
   
   
   You should initialize the XView system as soon as possible in any
   application. The xv_init() call does this for you. By default,
   xv_init() uses the DISPLAY environment variable for you. By pass-ing
   the argc and argv values you can override the default values for the
   application from the command line. You can use xv_init() only once in
   an application; the libraries ignore all other calls. Normally you'd
   override the DISPLAY variable if you wanted to display the window on a
   different machine.
   
   You can use two types of parameters for the first argument to
   xv_init(): XV_INIT_ARGS, which leaves the argc and argv unchanged, or
   XV_INIT_ARGC_PTR_ARGV, which modifies argc and argv to remove all
   XView-specific arguments. With XV_INIT_ARGS, you pass argc into
   xv_init and with XV_INIT_ARGC_PTR_ARGV you pass the address of argc to
   xv_init().
   
   Creating Objects
   
   
   The xv_create function is used to create all the objects in an
   application. The syntax for the xv_create function is
   
xv_object xv_create(xv_object owner, xv_package pkg, void *attr)

   where the owner is the parent of the object being created, and of type
   pkg given the attributes listed in variable length arguments starting
   with attr. Sometimes you can use a NULL value in place of the owner
   parameter to indicate that the owner value can be substituted for
   screen or server as appropriate. However, in some calls the owner
   parameter must point to a valid object, so the NULL value will
   generate an error.
   
   The attributes for the newly created object inherit their behavior
   from their parents. The attributes can be overridden by values
   included in the variable list specified in attr.
   
   The values of attributes are set in the following decreasing order of
   precedence:
     * A call to xv_set will override any other type of setting
       
     * Any command-line arguments
       
     * Values in the .Xdefaults file
       
     * Values in the attributes of an xv_create call
       
     * Window Manager defaults
       
   
   Exiting an Application
   
   
   The best way to get out of an XView application is to destroy the
   topmost object. Use the xv_destroy_safe() function call, which waits
   for the destruction of all derived objects and cleans up after itself.
   You can also use xv_destroy() to get out immediately with the risk of
   not giving up system resources but be able to exit very quickly. If
   you don't give up resources, they will not be freed for use by any
   other applications in the system and will use up valuable memory
   space.
   
   Frames
   
   
   A frame is a container for other windows. A frame manages the geometry
   of subwindows that do not overlap. Some examples include canvases,
   text windows, panels, and scrollbars. You saw a base frame in the
   output of LIST33_1.c (refer to Figure 33.2 and Listing 33.2).
   
   Frames enable you to specify three types of outputs on three areas.
   The topmost area is the name on the top of the frame called the
   header. The bottom of the frame is divided into two sections; one is
   left-justified and the other is right-justified. Figure 33.3 shows the
   output from Listing 33.3, which shows you how to write to these areas.
   
   Figure 33.3. Header and footer frames.
   
   Listing 33.3. Header and footer frames.

/*
**
** Listing to show headers and footers.
**
*/
#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
/*
**
*/
Frame frame;
/*
**
*/
int main(int argc, char *argv[])
{
Panel panel;
void quit();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, "Title Here",
FRAME_SHOW_FOOTER, TRUE,
FRAME_LEFT_FOOTER, "left side",
FRAME_RIGHT_FOOTER, "right side",
XV_WIDTH, 200,
XV_HEIGHT, 100,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}

   The parameters used to create these headers are shown in the following
   lines:

Frame frame;
frame = (Frame) xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
FRAME_SHOW_FOOTER, TRUE,
FRAME_LEFT_FOOTER, "left side",
FRAME_RIGHT_FOOTER, "right side",
FRAME_LABEL, "Title Here",
NULL);

   You have to turn the footer display on with the FRAME_SHOW_FOOTER
   attribute set to TRUE. The other values in this call actually set the
   values of the header and footer.
   
   Command Frames
   
   
   Command frames are usually used to perform a quick function and then
   disappear. These frames are usually pop-up frames like the pushpin
   dialog boxes you saw in Chapter 24, "OPEN LOOK and OpenWindows." If
   the pushpin is pressed in, the dialog box remains "pinned" to the
   screen; otherwise, the dialog box will go away after the user performs
   the section.
   
   Listing 33.4 shows you a program to create command frames.
   
   Listing 33.4. Using command frames.

/*
** Sample Application to show command frames.
**
*/
#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
/*
** Global Frames
*/
Frame frame;
Frame popup;
/*
**
** Declare the used functions here
**
*/
void show_greeting(Frame *fp);
int show_popup();
int push_it();
void quit();
/*
** The main function
*/
int main(int argc, char *argv[])
{
Panel panel;
Panel fpanel;
/*
** Initialize the toolkit
*/
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
/*
** Create top level frame.
*/
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, "Title Here",
FRAME_SHOW_FOOTER, TRUE,
FRAME_LEFT_FOOTER, "Popup",
FRAME_RIGHT_FOOTER, argv[0],
XV_WIDTH, 200,
XV_HEIGHT, 100,
NULL);
/*
** Create the popup Frame.
*/
popup = (Frame) xv_create(frame, FRAME_CMD,
FRAME_LABEL, "Popup",
XV_WIDTH, 100,
XV_HEIGHT, 100,
NULL);
/*
** Create panel for popup
*/
fpanel = (Panel)xv_get(popup, FRAME_CMD_PANEL,NULL);
/*
** Add buttons to popup
*/
(void) xv_create(fpanel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Greet",
PANEL_NOTIFY_PROC, show_greeting,
NULL);
(void) xv_create(fpanel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Push Me",
PANEL_NOTIFY_PROC, push_it,
NULL);
/*
** Create panel
*/
panel = (Panel)xv_create(frame, PANEL,NULL);
/*
** Add buttons to main application frame
*/
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Hello",
PANEL_NOTIFY_PROC, show_popup,
NULL);
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}
void show_greeting(Frame *fp)
{
printf ("\n Greet you? How?");
}
show_popup(Frame item, Event *ev)
{
xv_set(popup, XV_SHOW, TRUE, NULL);
}
push_it(Panel_item item, Event *ev)
{
int ret;
ret = (int)xv_get(popup, FRAME_CMD_PIN_STATE) ;
if (ret == FRAME_CMD_PIN_IN)
{
printf("Pin already in.. bye\n");
xv_set(popup, XV_SHOW, TRUE, NULL); /* refresh anyway */
}
else
{
printf("Pin out.. pushing it in\n");
xv_set(popup, FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_IN, NULL);
xv_set(popup, XV_SHOW, TRUE, NULL); /* refresh anyway */
}
}

   The output from Listing 33.4 is shown in Figure 33.4.
   
   Figure 33.4. Using command frames.
   
   Look at the important lines of the program in Listing 33.4 in detail.
   By examining these lines you will learn the following:
     * How to create pop-up menus
       
     * How to add buttons to a panel
       
     * How to handle callback functions for xview objects
       
   There are two frames in this application: frame and popup. These
   frames are declared at the top of the application with the statements

Frame frame;
Frame popup;

   We also declared the following functions in this application:
     * void show_greeting(Frame *fp); This function is called when the
       Greeting button is pressed.
       
     * int show_popup(); This function is called when the Hello button is
       pressed.
       
     * int push_it(); This function is called when the Push Me button is
       pressed.
       
     * void quit(); This function is called when the Quit button is
       pressed.
       
   The main xv_init() and frame creation for the program is as in Listing
   33.3. Let's concentrate on the pop-up menu examples.
   
   First, the pop-up frame is created with the following lines:

popup = (Frame) xv_create(frame, FRAME_CMD,
FRAME_LABEL, "Popup",
XV_WIDTH, 100,
XV_HEIGHT, 100,
NULL);

   This call will create the pop-up frame with frame as the owner. The
   pop-up frame is not displayed immediately. You can create several
   pop-up frames this way and display them only when they are needed.
   
       ______________________________________________________________
                                      
     
     NOTE: Note that if you do not set the XV_WIDTH and XV_HEIGHT
     parameters for this xv_create() call, the pop-up screen will occupy
     the entire screen.
     
     
       ______________________________________________________________
                                      
   Next we create a panel for this pop-up with the call
   
fpanel = (Panel)xv_get(popup, FRAME_CMD_PANEL,NULL);

   Then we add the Greet and Push Me buttons to this new fpanel. This is
   done by the xv_create calls, which are shown next:

 (void) xv_create(fpanel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Greet",
PANEL_NOTIFY_PROC, show_greeting,
NULL);
 (void) xv_create(fpanel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Push Me",
PANEL_NOTIFY_PROC, push_it,
NULL);

   At this point you are ready to create the main application frame, show
   it, and go into the main loop. The important call that does this is
   shown next. The function show_popup() is assigned to be called when
   the Hello button is pressed.

(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Hello",
PANEL_NOTIFY_PROC, show_popup,
NULL);

   Now look at the functions that are called when each button is pressed.
   The show_greeting function simply prints out a string. (You can use
   your imagination here for the contents of the string for your own
   application.) The show_popup() function will use the call to the
   xv_set() function to actually make the pop-up frame visible.
   
xv_set(popup, XV_SHOW, TRUE, NULL);

   Now for the function that will emulate the behavior of pushing in the
   pin. This is the push_it() function. The FRAME_CMD_PIN_STATE parameter
   requests the state of the pushpin on the dialog box. The state for the
   pin is defined as FRAME_CMD_PIN_IN if the pushpin is already pushed
   in. This is the state for which you check. If the pushpin is not in
   this state, it is pushed in with the xv_set(popup,
   FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_IN, NULL); function call.
   
       ______________________________________________________________
                                      
     
     NOTE: A command frame has no resize corners by default. To turn
     these corners on, set FRAME_SHOW_RESIZE_CORNERS to TRUE.
     
     
       ______________________________________________________________
                                      
   
   Setting Colors on Frames
   
   
   The colors on an XView frame object are defaulted to the
   OpenWindows.WindowColor resource. This resource is inherited by all
   subframes as well. You can override these colors with the CMS package.
   The CMS package is created by a call to xv_create():
   
cms = (Cms *) xv_create(parent, CMS, attrs, NULL);

   A CMS can contain as many colors as are allowed in the largest color
   map you can create. You can have several color maps referencing the
   same color; in fact, the system can share the location of colors
   between two independent applications. For this reason, you should
   allocate all your colors once, at cms creation, to allocate all the
   colors in your color map to prevent another application from changing
   the colors you absolutely need.
   
   For example, to create a cms with four named colors, you would use the
   following function call:

cms = (Cms *)xv_create(parent, CMS,
CMS_SIZE, 4,
CMS_NAMED_COLORS, "Violet", "Yellow", "Blue", "Orange",
NULL);

   The CMS_SIZE value asks for a four-entry color table that is indexed
   from 0 to 3, with the values of the named colors "Violet", "Yellow",
   "Blue", and "Orange". The foreground color for a frame is the first
   indexed color in a Cms and the background color for a frame is the
   last indexed (n-1) color in a Cms. Setting a CMS_SIZE will give you
   either an error or a monochromatic display. Of course, to avoid
   runtime errors you must know that the colors you just specified by
   name do exist in the /usr/lib/rgb.txt file.
   
   Listing 33.5 is an example of an application that sets the colors.
   This will let you set the foreground and background colors of a frame
   and all its children.
   
   Listing 33.5. Using CMS.

#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/cms.h>
Frame frame;
#define FORE 3
#define BACK 0
int main(int argc, char *argv[])
{
Cms cms;
Panel panel;
void quit();
printf("\n 0\n");
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
cms = (Cms ) xv_create((int)NULL,CMS, /* NULL -> use the default Frame*/
CMS_SIZE, CMS_CONTROL_COLORS + 4,
CMS_CONTROL_CMS, True,
CMS_NAMED_COLORS, "LightBlue", "Blue", "Red", "Green", NULL,
NULL);
frame = (Frame)xv_create((int)NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 200,
XV_HEIGHT, 100,
NULL);
xv_set(frame,
WIN_CMS, cms,
WIN_FOREGROUND_COLOR, CMS_CONTROL_COLORS + FORE,
WIN_BACKGROUND_COLOR, CMS_CONTROL_COLORS + BACK,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}

       ______________________________________________________________
                                      
     
     NOTE: You cannot use xv_get with the CMS_NAMED_COLORS attribute.
     
     
       ______________________________________________________________
                                      
       ______________________________________________________________
                                      
     
     NOTE: Use xv_set() to override the colors on a frame. Any color
     requests on a frame at the time of creation are overridden by
     values of the .Xdefaults resources values.
     
     
       ______________________________________________________________
                                      
   
   Canvases
   
   
   A canvas is an XView object that is used to display items that are too
   large to fit on a window. The viewable portion of the image is seen
   through a viewport or view window of the object. You can have multiple
   views of the same data that is stored on a canvas by splitting each
   scrollable portion into two or more views. The split views must all
   reside on the same canvas because you cannot have multiple views of
   canvas data that are not on the same frame.
   
   There are three components of a canvas object:
     * The Paint window, which contains the actual painted data
       
     * The View window, which has the scrollbars but no painted data
       
     * The canvas subwindow, which contains the union of the View window
       and Paint window
       
   Look at a simple example in Listing 33.6 of how to use scrollbars and
   how to paint on a paint window. (I have added line numbers for
   readability.)
   
   Listing 33.6. Using canvases and scrollbars.

1 /*
2 ** An example of a scrolled window
3 */
4 #include <X11/Xlib.h>
5 #include <xview/generic.h>
6 #include <xview/xview.h>
7 #include <xview/frame.h>
8 #include <xview/panel.h>
9 #include <xview/canvas.h>
10 #include <xview/scrollbar.h>
11 #include <xview/xv_xrect.h>
12 /*
13 ** Declare our callback functions for this application.
14 */
15 Frame frame;
16 void redraw(Canvas c, Xv_Window pw, Display *dp, Window xwin,
17 Xv_xrectlist *rp) ;
18 int main(int argc, char *argv[])
19 {
20 Canvas canvas;
21 Panel panel;
22 Scrollbar h_s, h_v;
23 void quit();
24 xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
25 frame = (Frame)xv_create(NULL, FRAME,
26 FRAME_LABEL, argv[0],
27 XV_WIDTH, 400,
28 XV_HEIGHT, 200,
29 (int)NULL);
30 /*
31 ** Create the canvas.
32 */
33 canvas = (Canvas) xv_create(frame, CANVAS,
34 CANVAS_REPAINT_PROC, redraw,
35 CANVAS_X_PAINT_WINDOW, TRUE,
36 CANVAS_AUTO_SHRINK, FALSE,
37 CANVAS_AUTO_EXPAND, TRUE,
38 CANVAS_WIDTH, 500,
39 CANVAS_HEIGHT, 500,
40 XV_WIDTH, 400,
41 XV_HEIGHT, 200,
42 NULL);
43 /*
44 ** Create the splittable scrollbars
45 */
46 h_s = (Scrollbar)xv_create(canvas, SCROLLBAR,
47 SCROLLBAR_DIRECTION, SCROLLBAR_HORIZONTAL,
48 SCROLLBAR_SPLITTABLE, TRUE,
49 NULL);
50 h_v = (Scrollbar)xv_create(canvas, SCROLLBAR,
51 SCROLLBAR_DIRECTION, SCROLLBAR_VERTICAL,
52 SCROLLBAR_SPLITTABLE, TRUE,
53 NULL);
54 xv_main_loop(frame);
55 exit(0);
56 }
57 void redraw(Canvas c, Xv_Window pw, Display *dp, Window xwin,
58 Xv_xrectlist *rp)
59 {
60 GC gc;
61 int wd, ht;
62 int i;
63 int j;
64 int dx;
65 int dy;
66 gc = DefaultGC(dp, DefaultScreen(dp));
67 wd = (int)xv_get(pw, XV_WIDTH);
68 ht = (int)xv_get(pw, XV_HEIGHT);
69 dx = ht / 10;
70 for (i = 0; i < ht; i += dx)
71 XDrawLine(dp,xwin,gc, i,0,i,ht);
72
73 dx = wd / 10;
74 for (i = 0; i < wd; i += dx)
75 XDrawLine(dp,xwin,gc, 0,i,wd,i);
76 /* XDrawLine(dp,xwin,gc, 0,0,wd,ht); */
77 }
78 void quit()
79 {
80 xv_destroy_safe(frame);
81 }

   Lines 33 through 42 create the canvas. The CANVAS_AUTO_EXPAND and
   CANVAS_AUTO_SHRINK parameters maintain the relation of the canvas
   subwindow and the paint subwindow. These values default to TRUE. When
   both values are TRUE, the canvas and paint subwindows will expand or
   shrink based on the size of the window on which they are being
   displayed.
   
   Setting the CANVAS_AUTO_EXPAND value to TRUE enables the paint
   subwindow to expand larger than the canvas subwindow. If the canvas
   subwindow expands to a bigger size than the paint subwindow, the paint
   subwindow is expanded to at least that size as well. If the canvas
   subwindow size shrinks, the paint subwindow does not shrink because it
   is already at the same size or bigger than canvas subwindows at that
   time.
   
   Setting the CANVAS_AUTO_SHRINK value to TRUE forces the canvas object
   to always confirm that the paint subwindow's height and width are
   never greater than the canvas subwindow. In other words, the size of
   the paint subwindow is always changed to be at least the same or less
   than the size of the canvas subwindow.
   
   You can explicitly set the size of the canvas window with the
   CANVAS_WIDTH and CANVAS_HEIGHT parameters. (See lines 38 and 39.)
   These canvas dimensions can be greater than the viewing window
   dimensions set with XV_WIDTH and XV_HEIGHT (lines 40 and 41).
   
   We have to add the include file <xview/scrollbar.h> to get the
   definitions for the scrollbar package. These are created in lines 46
   through 53. Note how we have to create two separate scrollbars, one
   vertical and one horizontal.
   
   The scrollbars in this example show how they can split to provide
   multiple, tiled views of the data in the canvas window. To split a
   view, press the right mouse button on a scrollbar and you will be
   presented with a pop-up menu. Choose the Split View option to split
   the view or the Join View option to join two views together. You will
   not see a Join View option if a scrollbar does not dissect a view.
   
   You can programmatically split a canvas view even if scrollbars are
   not present. Use the OPENWIN_SPLIT attribute in an xv_set() function
   call. For example:

xv_window xv;
xv = (xv_window)xv_get(canvas,OPENWIN_NTH_VIEW,0);
xv_set(canvas,
OPENWIN_SPLIT,
OPENWIN_SPLIT_VIEW, xv,
OPENWIN_SPLIT_DIRECTION,
OPENWIN_SPLIT_HORIZONTAL,
NULL);

       ______________________________________________________________
                                      
     
     NOTE: You may want to group your xv_set() function calls into
     distinct logical calls to set each type of parameter instead of one
     long convoluted list of parameters to one xv_set() function.
     Splitting the code into these groups makes the code easier to read
     and debug.
     
     
       ______________________________________________________________
                                      
   Note that only OPENWIN_* type of attributes are allowed in the
   xv_set() call with the OPENWIN_SPLIT parameter. Do not mix other types
   of attributes. To get the first view you can use a value of 0 to the
   OPENWIN_NTH_VIEW parameter. For the next view, use 1, and so on. To
   get an idea of how many views there are for this canvas use the call

int number;
number = (int)xv_get(canvas, OPENWIN_NVIEWS);

   To get the paint window to do your own drawing, perhaps in response to
   other user input, you can use the xv_get() function to get the paint
   window. For example,

xv_window xv_paint;
xv_paint = (xv_window)xv_get(canvas, CANVAS_VIEW_PAINT, null);

   Listing 33.6 shows how to use the standard Xlib function calls to draw
   on the canvas. (See Figure 33.5.) You must use the include file
   <X/Xlib.h> for all the definitions and declarations. The XDrawLine
   function used in this example is somewhat simple. However, this
   example shows you how to set up your Graphics Context and use the
   standard XDrawLine function to draw a grid. You can use other X
   drawing functions just as easily.
   
   Figure 33.5. The scrolled window example.
   
   Buttons
   
   
   A button item enables a user to select an action. Several types of
   buttons are available to you as a programmer. Figure 33.6 shows how
   various buttons are used. There are four distinct examples shown in
   Figure 33.6:
   
   Figure 33.6. Using buttons.
     * The Menu Item is shown as "Y/N/Q".
       
     * The 1 of N choice of items from four items.
       
     * The M of N choice of items from three items to match others.
       
     * Choosing via four checkboxes.
       
   The listing for generating Figure 33.6 is shown in Listing 33.7. We
   will go over this listing in detail.
   
   Listing 33.7. Using menus, buttons, and choices.

/*
** A sampler of some of the choices to present to a user
*/
#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/openmenu.h>
Frame frame;
int menuHandler( Menu item, Menu_item selection);
int selected( Panel_item item, Event *ev);
void quit();
int main(int argc, char *argv[])
{
Rect *rt;
Rect *qrt;
Panel panel;
Panel quitbtn;
Panel oneN;
Panel manyN;
Panel chooser;
Menu menu1;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 400,
XV_HEIGHT, 200,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
quitbtn = (Panel)xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
XV_X, 20,
NULL);
menu1 = (Menu) xv_create(NULL, MENU,
MENU_STRINGS, "Yes", "No", "Maybe", "Bye", NULL,
MENU_NOTIFY_PROC, menuHandler,
NULL);
xv_create (panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Y/N/Q",
PANEL_ITEM_MENU, menu1,
PANEL_NOTIFY_PROC, selected,
NULL);
qrt = (Rect *) xv_get(quitbtn, XV_RECT);
oneN = (Panel) xv_create(panel, PANEL_CHOICE,
PANEL_LABEL_STRING, "1 of N",
PANEL_CHOICE_STRINGS,
"extra", "large", "medium", "small", NULL,
XV_X, 20,
XV_Y, rect_bottom(qrt) + 20,
NULL);
rt = (Rect *) xv_get(oneN, XV_RECT);
manyN = (Panel) xv_create(panel, PANEL_CHOICE,
PANEL_LABEL_STRING, "M of N",
PANEL_CHOICE_STRINGS,
"tomato", "celery", "carrot" , NULL,
PANEL_CHOOSE_ONE, FALSE,
XV_X, 20,
XV_Y, rect_bottom(rt) + 20,
NULL);
rt = (Rect *) xv_get(manyN, XV_RECT);
chooser = (Panel) xv_create(panel, PANEL_CHECK_BOX,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "Extras",
PANEL_CHOICE_STRINGS,
"fries", "potato", "Q. potato", "salad" , NULL,
PANEL_CHOOSE_ONE, FALSE, /* Let 'em have it all */
XV_X, 20,
XV_Y, rect_bottom(rt) + 20,
NULL);
xv_main_loop(frame);
exit(0);
}
/*
** This function is called when you select an item
*/
int selected( Panel_item item, Event *ev)
{
printf(" %s .. \n ", xv_get(item, PANEL_LABEL_STRING));
}
/*
** This function handles the menu selection item.
** Shows you how to exit via menu item too.
*/
int menuHandler(Menu item, Menu_item thing)
{
printf("%s .. \n", xv_get(thing, MENU_STRING));
if (!strcmp((char *)xv_get(thing,MENU_STRING), "Bye")) quit();
}
/*
** Make a clean exit.
*/
void quit()
{
xv_destroy_safe(frame);
}

   Take a look at the part where the "Y/N/Q" menu button was created.
   First we created the menu items on the menu as menu1. Note that we did
   not display all of the choices in the menu, just its header.

menu1 = (Menu) xv_create(NULL, MENU,
MENU_STRINGS, "Yes", "No", "Maybe", "Bye", NULL,
MENU_NOTIFY_PROC, menuHandler,
NULL);

   Then we created the panel button that will house this menu with the
   following lines:

xv_create (panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Y/N/Q",
PANEL_ITEM_MENU, menu1,
PANEL_NOTIFY_PROC, selected,
NULL);

   That was it. Now you can click the right button on the "Y/N/Q" button
   to get the selection items as a pull-down menu. If you click the left
   button, the first item in the menu item will be displayed momentarily
   and selected. Two functions are assigned as callbacks in the previous
   code segments:
     * menuHandler(): This function will show on your terminal the menu
       item selected.
       
     * selected(): This function merely displays the menu item string.
       You could just as easily display another menu or other items
       instead of this simple example.
       
   Now look at the example for the "1 of N" selection. As the name of
   this item suggests, you can choose only one of a given number of
   items. This is called an exclusive selection.
   
   The following lines are used to create this exclusive selection item:

oneN = (Panel) xv_create(panel, PANEL_CHOICE,
PANEL_LABEL_STRING, "1 of N",
PANEL_CHOICE_STRINGS,
"extra", "large", "medium", "small", NULL,
XV_X, 20,
XV_Y, rect_bottom(qrt) + 20,
NULL);

   Note how we used the core class's XV_X and XV_Y attributes to position
   this box below the Quit button. We got the position as a rectangle
   (typedef Rect) of the Quit button via the xv_get call given the
   XV_RECT attribute:
   
qrt = (Rect *) xv_get(quitbtn, XV_RECT);

   The position given by XV_X and XV_Y was relative to the top-left
   position of the panel. This given position is known as absolute
   positioning because we are using hard-coded numbers to position items.
   
       ______________________________________________________________
                                      
     
     NOTE: To position items generally we can use two functions:
     xv_row() and xv_col(). These functions use the WIN_ROW_GAP and
     WIN_COLUMN_GAP to set the spaces between the items. The following
     example shows you how to position twelve items on a panel:
     #define ROW 3
     #define COL 4
     extern char *name[ROW][COL];
     int i, j;
     for (i = 0; i < ROW; i++)
     for (j = 0; j < COL; j++)
     {
     xv_create(panel, PANEL_BUTTON,
     XV_X, xv_col(panel,j),
     XV_Y, xv_row(panel,i),
     PANEL_LABEL_STRING, name[i][j],
     NULL);
     }
     
     
       ______________________________________________________________
                                      
   All items presented in this list are shown with the NULL-terminated
   list passed in with the PANEL_CHOICE_STRINGS attribute. The default
   function of PANEL_CHOICE is to enable only one selection. To get more
   than one selection if you have a list of choices, you can follow the
   same procedure you used for the exclusive selection panel. The
   difference between 1 of M and M of N lies in setting the value of the
   PANEL_CHOOSE_ONE to FALSE. This usage creates the M of N items shown
   in the following lines:

manyN = (Panel) xv_create(panel, PANEL_CHOICE,
PANEL_LABEL_STRING, "M of N",
PANEL_CHOICE_STRINGS,
"tomato", "celery", "carrot" , NULL,
PANEL_CHOOSE_ONE, FALSE,
XV_X, 20,
XV_Y, rect_bottom(rt) + 20,
NULL);

   With 1 of M, we use the XV_RECT call to position this choice of many
   item's button on the screen.
   
   Finally, this example showed you how to use check boxes to create the
   input items shown for our choices of a side order. Checkboxes are
   always non-exclusive. The text to do this is shown in the following
   lines:

chooser = (Panel) xv_create(panel, PANEL_CHECK_BOX,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_LABEL_STRING, "Extras",
PANEL_CHOICE_STRINGS,
"fries", "potato", "Q. potato", "salad" , NULL,
XV_X, 20,
XV_Y, rect_bottom(rt) + 20,
NULL);

   This set of checkboxes was also positioned to align with the qv_get
   and rect_bottom() calls.
   
   List Items
   
   
   Use the PANEL_LIST attribute to show lists of items. An example is
   shown in Figure 33.7. The corresponding listing is shown in Listing
   33.8. Lists enable you to insert text (and graphics as glyphs) in
   them. You can have duplicates in a list. If you do not want to allow
   duplicates, set the PANEL_LIST_INSERT_DUPLICATE to FALSE.
   
   Figure 33.7. Using lists to display data.
   
   Listing 33.8. Using lists to display data.

/*
** Using Lists
*/
#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
Frame frame;
int main(int argc, char *argv[])
{
Panel panel;
void quit();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 200,
XV_HEIGHT, 100,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
 (void) xv_create(panel, PANEL_LIST,
PANEL_LIST_STRINGS,
"Business", "Economics", "History",
"Literature", "TomFoolery", "Math",
"Computer Sci.", "Engineering", NULL,
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}

   Lists are ordered from 0 and up, so the first row is 0, the second row
   is 1, and so on. To delete the rows 7 through 9 from a long list, use
   the xv_set function:

xv_set(list_item,
PANEL_LIST_DELETE_ROWS, 6, 3
NULL);

   In the preceding example you are requesting that 3 rows be deleted
   starting from row index number 6 (which is the seventh row). All other
   rows are adjusted upward after these rows are deleted.
   
   To insert items into this list you can use PANEL_LIST_INSERT and
   PANEL_LIST_STRING calls. If you wanted to replace the third row with a
   string pointed to by a pointer called buffer, you would use the
   following function call:

xv_set(list_item,
PANEL_LIST_DELETE, 2,
PANEL_LIST_INSERT, 2,
PANEL_LIST_STRING, buffer,
NULL);

   The PANEL_NOTIFY_PROC function for a list is called when an item is
   selected, deselected, added, or deleted. The prototype for this
   function call is

listCallBack(
Panel_item item,
char *string,
Xv_opaque client_data,
Panel_list_op op,
Event *event,
int row);

   The item is the panel list itself in this function call. The string is
   the label for the row, or NULL if no item is defined in the list for
   the row. The opaque client_data is a user-specified value specified at
   list creation time with the PANEL_LIST_CLIENT_DATA parameter. For
   example, the line
   
PANEL_LIST_CLIENT_DATA, 2, "Hello",

   will assign the value of client_data to 2 for the row with the string
   "Hello" in it. Each client_data value must be assigned one line at a
   time.
   
   The op parameter can be one of the following values:
     * PANEL_LIST_OP_SELECT when the row is selected
       
     * PANEL_LIST_OP_DESELECT when the row is deselected
       
     * PANEL_LIST_OP_VALIDATE when a new row is added
       
     * PANEL_LIST_OP_DELETE when the row has been deleted
       
   You can take action based on the value of the op parameter in one
   handy function or have this function call other functions. For
   example, the following pseudocode illustrates how you could handle the
   op parameter:

switch (op)
{
case PANEL_LIST_OP_SELECT: selectHandler();
break;
case PANEL_LIST_OP_DESELECT: unSelectHandler();
break;
case PANEL_LIST_OP_VALIDATE: addRowHandler();
break;
case PANEL_LIST_OP_DELETE: deleteRowHandler();
break;
}

   
   Scale Bars
   
   
   Now look at how you create slider bars so the user can set the value
   of a variable. An example of this application is shown in Figure 33.8
   and a corresponding listing is given in Listing 33.9.
   
   Figure 33.8. Using sliders.
   
   Listing 33.9. Using slider control.

#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
Frame frame;
Panel_item stationName;
void display_setting(Panel_item, int value, Event *ev);
int main(int argc, char *argv[])
{
Panel panel;
Panel_item slider;
void quit();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 400,
XV_HEIGHT, 100,
NULL);
panel = (Panel)xv_create(frame, PANEL,
PANEL_LAYOUT, PANEL_VERTICAL,
NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
slider = xv_create (panel, PANEL_SLIDER,
PANEL_LABEL_STRING, "Radio Station",
PANEL_MIN_VALUE, 88,
PANEL_MAX_VALUE, 108,
PANEL_NOTIFY_PROC, display_setting,
PANEL_VALUE,99,
PANEL_NOTIFY_LEVEL, PANEL_ALL, /* not just at the end */
PANEL_SHOW_RANGE, TRUE,
PANEL_TICKS,10,
PANEL_SLIDER_WIDTH, 100,
NULL);
stationName = xv_create(panel, PANEL_MESSAGE,
PANEL_LABEL_STRING, "sample",
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}
/*
** This function is called when the slider value is changed.
*/
void display_setting(Panel_item item, int value, Event *ev)
{
switch (value)
{
case 89: xv_set(stationName,
PANEL_LABEL_STRING,"Classical", NULL); break;
case 91: xv_set(stationName,
PANEL_LABEL_STRING,"Industrial", NULL); break;
case 93: xv_set(stationName,
PANEL_LABEL_STRING,"Country", NULL); break;
case 95: xv_set(stationName,
PANEL_LABEL_STRING,"Soft Rock", NULL); break;
case 101: xv_set(stationName,
PANEL_LABEL_STRING,"Roll N Roll", NULL); break;
case 104: xv_set(stationName,
PANEL_LABEL_STRING,"Pop", NULL); break;
case 107: xv_set(stationName,
PANEL_LABEL_STRING,"Alternative", NULL); break;
default: xv_set(stationName,
PANEL_LABEL_STRING,"bzzz", NULL); break;
}
}

   To create a slider, assign the PANEL_SLIDER value to the xv_create()
   function call. How the slider is used and displayed is governed by the
   following attributes:
     * PANEL_MIN_VALUE and PANEL_MAX_VALUE: The range of values that this
       slider can take. These values have to be integers. For the example
       in this book we used 88 and 108.
       
     * PANEL_SHOW_RANGE: Sets the slider to show the value of the ranges
       allowed for the selection.
       
     * PANEL_NOTIFY_LEVEL: Can be set to one of two values: PANEL_ALL if
       the callback procedure is called while the slider is moving, or
       PANEL_DONE only when the pointer button is released.
       
     * PANEL_DIRECTION: Can be used to set the orientation of the slider
       to either horizontal or vertical.
       
     * PANEL_TICKS: The number of ticks that show on the display. Set it
       to 0 if you do not want ticks to be shown. The number of ticks are
       adjusted as you size the slider. You fix the width of the slider
       by setting the PANEL_SLIDER_WIDTH to 100 (refer to Listing 33.8).
       
   You can edit the selection value by clicking it and using the
   keyboard. This value will change the location of the slider as soon as
   you press the Enter key. Error values will be ignored.
   
   Note how a message label displays the station name as the slider is
   being moved. To set the value of this label, make a call to xv_set()
   and give the attribute PANEL_LABEL_STRING a string value. For example,
   if the value of the slider is 89, you can set the message to
   "Classical", as shown in the following lines:

case 89: xv_set(stationName,
PANEL_LABEL_STRING,"Classical", NULL); break;

       ______________________________________________________________
                                      
     
     NOTE: You can create a gauge by using the PANEL_GAUGE package
     instead of PANEL_SLIDER. The dimensions of the gauge are set by the
     PANEL_GAUGE_WIDTH and PANEL_GAUGE_HEIGHT attributes. A user cannot
     change the value of the slider on a gauge because a gauge can be
     used only as a feedback item.
     
     
       ______________________________________________________________
                                      
   
   Text Windows
   
   
   XView has a lot of options for displaying data. This section will only
   cover a few portions of this feature. Please refer to the man pages
   for Text in /usr/openwin/man. Let's get started with some of the
   basics, though. A sample application is shown in Listing 33.10 and its
   corresponding output is shown in Figure 33.9.
   
   Figure 33.9. Using text items.
   
   Listing 33.10. Using text items.

#include <xview/generic.h>
#include <xview/xview.h>
#include <xview/frame.h>
#include <xview/panel.h>
Frame frame;
int main(int argc, char *argv[])
{
Panel panel;
void quit();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 300,
XV_HEIGHT, 300,
NULL);
panel = (Panel)xv_create(frame, PANEL,NULL);
 (void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit,
NULL);
xv_create(panel, PANEL_TEXT,
PANEL_LABEL_STRING, "Single",
PANEL_VALUE, "Single Line of Text",
NULL);
xv_create(panel, PANEL_MULTILINE_TEXT,
PANEL_LABEL_STRING, "Multi",
PANEL_DISPLAY_ROWS, 3,
PANEL_VALUE_DISPLAY_LENGTH, 30,
PANEL_VALUE, "Multiple Lines of Text \
in this example \
This is a line 1\
This is a line 2\
This is a line 3\
of some long string",
NULL);
xv_main_loop(frame);
exit(0);
}
void quit()
{
xv_destroy_safe(frame);
}

   We created a single panel text entry item with the following lines
   using the PANEL_TEXT package:

xv_create(panel, PANEL_TEXT,
PANEL_LABEL_STRING, "Single",
PANEL_VALUE, "Single Line of Text",
NULL);

   If the PANEL_LAYOUT value is set to PANEL_VERTICAL, the value will be
   placed below the label. The default is PANEL_HORIZONTAL. The number of
   characters is set with the PANEL_VALUE_DISPLAY_LENGTH attribute. This
   value should not be less than 4. (This is not in the listing and is
   only for your information.)
   
   If you want the user to enter private data such as password
   information, you can set the PANEL_MASK_CHAR value to something like
   an asterisk. This setting displays an asterisk for each character that
   the user types in. The value of the text remains what the user typed
   in.
   
   You can have notification procedures for four types of input for a
   text item with the PANEL_NOTIFY_LEVEL. (See Table 33.1.)
   
   Table 33.1. Notification procedures.
   
                                      
                    Notification Action to take on input
                   PANEL_NONE Never inform this package.
            PANEL_NON_PRINTABLE On each non-printable character.
   PANEL_SPECIFIED If the input character is found in a string specified
                   by the attribute PANEL_NOTIFY_STRING.
                     PANEL_ALL On all characters input.
                                      
   You can also have multiple lines of text on a display. A sample of
   this is shown in Listing 33.10. Look at the following excerpted lines:
   
xv_create(panel, PANEL_MULTILINE_TEXT,
PANEL_LABEL_STRING, "Multi",
PANEL_DISPLAY_ROWS, 3,
PANEL_VALUE_DISPLAY_LENGTH, 30,
PANEL_VALUE, "Multiple Lines of Text \
in this example\
This is a line 1\
This is a line 2\
This is a line 3\
of some long string",
NULL);

   The PANEL_MULTILINE_TEXT package can have the following attributes set
   for it: PANEL_DISPLAY_ROWS sets the number of lines that the viewing
   window will display, and PANEL_VALUE_DISPLAY_LENGTH is the number of
   characters wide you want the display to be.
   
   Where To Go from Here
   
   
   This chapter is a very brief introduction to the XView packages
   available under Linux. In this section you have learned a little about
   putting user interface items together on a panel. You should now have
   enough knowledge to start creating your own interfaces in XView.
   
   Some cool binaries to look for in the /usr/openwin/bin directory are
   props for setting window parameters and textedit, a pretty good
   editor.
   
   Summary
   
   
   You use objects to build XView applications. Each object is a class
   and is referred to as a package. Each package has attributes that can
   have values. Attributes can be shared among other objects, be common
   to a few objects only, or be specific to one object.
   
   You can retrieve an attribute's values by calling xv_get() and set a
   value by calling xv_set. An attribute may be assigned more than one
   value. Each attribute can have a different type of value attached to
   it.
   
   You can use standard Xlib function calls to perform drawing
   operations. This gives you tremendous flexibility in rendering your
   custom graphics on screens and XView packages.
   
   The XView packages enable you to create and place objects on panels.
   You can place these objects using absolute positioning from the top
   left corner of a panel, relative to other objects, or in row/column
   order.
   
   The xv_create() call passes the type of object as a parameter to
   create XView objects. You can set other attributes by passing a
   NULL-terminated list to xv_create(). Default attribute values that are
   not explicitly set by xv_create() are inherited from the object's
   parent.
   

--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 修改:.netiscpu 于 Jul 25 05:59:11 修改本文.[FROM: mtlab.hit.edu.cn]
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: fengyun.hit.edu.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:618.552毫秒