|
DECwindows Motif Guide to Application
Programming
3.3 Using Default Files
As described in the OSF/Motif Programmer's Guide, your application can use
application-specific default files to specify resources that are not
explicitly set in the C or UIL modules. You specify the file that
contains the application defaults in the
application_class argument of the XtAppInitialize
routine, as follows:
toplevel = XtAppInitialize(&app_context, "example", NULL, 0,
&argc, argv, NULL, NULL, 0);
|
The application_class argument, in this case
"example", specifies a defaults file named example.dat on Digital UNIX
systems and eXcursion for Windows NT systems, or EXAMPLE.DAT on OpenVMS
systems. (The file extension is .dat or .DAT by default.) The
XtAppInitialize routine automatically uses the defaults file if it is
present.
The following is an example of a defaults file. On OpenVMS systems,
this file is located in DECW$USER_DEFAULTS (the user's SYS$LOGIN
directory). On UNIX and Windows NT systems, the file is located in the
user's home directory.
!
example*allowShellResize: true
example*borderWidth: 0
example*highlightThickness: 1
example*traversalOn: true
example*fontList: fixed
example*background: LightBlue
!
|
To determine how the resource is used in a defaults file, check the
include file for the widget to see how the resource is defined. For
example, the DXmSvnNfontListLevel resources are defined as follows in
DXmSvn.h (UNIX and Windows NT) or DXMSVN.H (OpenVMS):
#define DXmSvnNfontListLevel0 "DXmfontListLevel0"
#define DXmSvnNfontListLevel1 "DXmfontListLevel1"
#define DXmSvnNfontListLevel2 "DXmfontListLevel2"
#define DXmSvnNfontListLevel3 "DXmfontListLevel3"
|
Note that widgets provided by Digital have the resource name prefix
DXmN for resources that are unique to the widget. In the case of the
SVN widget, the prefix is DXmSvnN.
You use the string value of the resource as the value in the defaults
file, in this case DXmfontListLevel0, DXmfontListLevel1, and so forth.
Note that the names are case sensitive.
example*main_svn.background: LightBlue
example*DXmfontListLevel2: -ADOBE-Courier-Book-R-Normal--14-100-*-*-P-80-*"
|
Resources that are common with other widgets or part of the widget's
superclass use the XmN prefix. The resource names are in Xm.h (UNIX and
Windows NT) or XM.H (OpenVMS), and the string used in the defaults file
is in parentheses following the X_GBLS. For example, you use the string
value of background to specify the XmNbackground
resource in a defaults file.
#define XmNbackground X_GBLS(background)
|
3.4 Using Default Files to Save Customized Settings
Many applications give the user the option to customize application
settings and then save these settings for subsequent invocations of the
application. Example 3-6 and Example 3-7 implement an application
that lets the user set and save the XmNwidth and XmNheight resources of
its main window.
Example 3-6 Saving Application Defaults---UIL
Module |
.
.
.
module form
version = 'v1.0'
names = case_sensitive
procedure
save_create ();
all_done ();
object
(1)main_window : XmMainWindow {
controls {
XmMenuBar menu_bar;
XmForm form_main;
};
};
object
menu_bar : XmMenuBar {
arguments {
XmNorientation = XmHORIZONTAL;
XmNspacing = 15;
};
controls {
XmCascadeButton cust_entry;
};
};
object
(2)cust_entry : XmCascadeButton {
arguments {
XmNlabelString = compound_string("Save Settings");
XmNmnemonic = keysym("S");
};
controls {
XmPulldownMenu cust_menu;
};
};
object
cust_menu : XmPulldownMenu {
controls {
XmPushButton push_me;
XmPushButton done;
};
};
object
(3)push_me : XmPushButton {
arguments {
XmNlabelString = compound_string("Save Width and Height");
};
callbacks {
XmNactivateCallback = procedure save_create ();
};
};
object
(4)done : XmPushButton {
arguments {
XmNlabelString = compound_string("Exit");
};
callbacks {
XmNactivateCallback = procedure all_done ();
};
};
(5)object
form_main : XmForm{
arguments
{
XmNdialogTitle = compound_string("XmForm");
XmNwidth = 300;
XmNheight = 300;
};
controls
{
XmRowColumn align_a;
XmRowColumn align_b;
};
};
object
align_a : XmRowColumn {
arguments {
XmNunitType = XmPIXELS;
XmNtopAttachment = XmATTACH_FORM;
XmNtopOffset = 25;
XmNleftAttachment = XmATTACH_FORM;
XmNleftOffset = 25;
XmNbottomAttachment = XmATTACH_NONE;
XmNrightAttachment = XmATTACH_NONE;
XmNorientation = XmVERTICAL;
XmNborderWidth = 0;
};
controls
{
XmPushButton a_button;
XmPushButton b_button;
XmPushButton c_button;
XmPushButton d_button;
XmPushButton e_button;
};
};
object
align_b : XmRowColumn {
arguments {
XmNunitType = XmPIXELS;
XmNtopAttachment = XmATTACH_FORM;
XmNtopOffset = 25;
XmNleftAttachment = XmATTACH_WIDGET;
XmNleftWidget = align_a;
XmNleftOffset = 25;
XmNbottomAttachment = XmATTACH_NONE;
XmNrightAttachment = XmATTACH_NONE;
XmNorientation = XmVERTICAL;
XmNborderWidth = 0;
};
controls
{
XmPushButton f_button;
XmPushButton g_button;
XmPushButton h_button;
XmPushButton i_button;
XmPushButton j_button;
};
};
object
a_button : XmPushButton {
arguments {
XmNlabelString = compound_string("a button");
};
};
object
b_button : XmPushButton {
arguments {
XmNlabelString = compound_string("b button");
};
};
object
c_button : XmPushButton {
arguments {
XmNlabelString = compound_string("Long Button Title");
};
};
object
d_button : XmPushButton {
arguments {
XmNlabelString = compound_string("d button");
};
};
object
e_button : XmPushButton {
arguments {
XmNlabelString = compound_string("Long Button Title");
};
};
object
f_button : XmPushButton {
arguments {
XmNlabelString = compound_string("f button");
};
};
object
g_button : XmPushButton {
arguments {
XmNlabelString = compound_string("g button");
};
};
object
h_button : XmPushButton {
arguments {
XmNlabelString = compound_string("h button");
};
};
object
i_button : XmPushButton {
arguments {
XmNlabelString = compound_string("i button");
};
};
object
j_button : XmPushButton {
arguments {
XmNlabelString = compound_string("j button");
};
};
end module;
|
- Because the example lets the user determine
the XmNwidth and XmNheight defaults, the XmNwidth and XmNheight values
are not hardcoded.
- Declare a "Save Settings" XmCascadeButton.
- Declare a "Save Width and Height"
XmPushButton. The activate callback for this push-button calls the save
defaults routine.
- Declare an "Exit" XmPushButton. The activate
callback for this push-button calls the exit routine.
- Declare XmForm, XmRowColumn, and XmPushButton
widgets to complete the application.
Example 3-7 Saving Application Defaults---C
Module |
.
.
.
/* The example uses these defaults:
* example*main_window.width: 334
* example*main_window.height: 246
* example*allowShellResize: true
* example*highlightThickness: 1
* example*borderWidth: 0
* example*background: LightBlue
* example*fontList: fixed
* example*traversalOn: true
*/
#include <stdio>
#include <Mrm/MrmAppl.h>
#include <DXm/DXmCSText.h>
#include <X11/Xresource.h>
Widget toplevel, main_win, form_w;
XrmDatabase database = 0;
int save_width;
int save_height;
(1)
#ifdef VMS
/* Use this definition for OpenVMS systems. */
#define resourceFileName "decw$user_defaults:example.dat"
#else
/* Use this definition for UNIX and Windows NT systems. */
#define resourceFileName "~/example.dat"
#endif
static MrmHierarchy s_MrmHierarchy;
static MrmType *dummy_class;
static char *db_filename_vec[] =
{"defaults_file.uid"
};
/* Forward declarations */
static void save_create();
static void all_done();
static void update_database( );
/* The names and addresses of things that Mrm has to bind. The names do
* not have to be in alphabetical order. */
static MrmRegisterArg reglist[] = {
{"save_create", (caddr_t) save_create},
{"all_done", (caddr_t) all_done}
};
static int reglist_num = (sizeof reglist / sizeof reglist [0]);
int main(argc, argv)
unsigned int argc;
char **argv;
{
XtAppContext app_context;
MrmInitialize();
DXmInitialize();
(2)toplevel = XtAppInitialize(&app_context, "example", "Example", 0, &argc,
argv, NULL, NULL, 0);
/* Open the UID files (the output of the UIL compiler) in the hierarchy*/
if (MrmOpenHierarchy(1,
db_filename_vec,
NULL,
&s_MrmHierarchy)
!=MrmSUCCESS)
printf("can't open hierarchy");
MrmRegisterNames(reglist, reglist_num);
if (MrmFetchWidget(s_MrmHierarchy, "main_window", toplevel,
&main_win, &dummy_class) != MrmSUCCESS)
printf("can't fetch widget");
XtManageChild(main_win);
XtRealizeWidget(toplevel);
XtAppMainLoop(app_context);
}
(3)static void save_create(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
Arg arglist[10];
int ac;
(4)if (!(database = XrmGetFileDatabase (resourceFileName)))
printf("Resource Database Not found");
(5)ac = 0;
XtSetArg(arglist[ac], XmNwidth, &save_width); ac++;
XtSetArg(arglist[ac], XmNheight, &save_height); ac++;
XtGetValues(main_win, arglist, ac);
(6)update_database ("example*main_window.width", save_width);
update_database ("example*main_window.height", save_height);
(7)XrmPutFileDatabase (database, resourceFileName);
}
static void update_database(resourceNameP, number)
char *resourceNameP;
int number;
{
XrmValue value;
char valueA[256];
sprintf (valueA, "%d", number);
value.addr = valueA;
value.size = strlen (valueA) + 1;
(8)XrmPutResource (&database, resourceNameP, XtRString, &value);
}
static void all_done(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
exit(1);
}
.
.
.
|
- Define a constant to specify the defaults
file name in calls to the Xrm resource manager routines.
- The application_class
argument, in this case "example", specifies a defaults file named
"example". (The file extension is .dat by default.) The XtAppInitialize
routine automatically uses the defaults file (if it is present) when
the application is run.
- The save-the-defaults routine invoked by the
push_me push-button callback.
- Get the defaults file from disk.
- Get the current XmNwidth and XmNheight values.
- Call the update_database routine to convert
the save_height and save_width integer values into character strings
and store them in XrmValue data structures, which is the format
required by the XrmPutResource routine.
Resources must be
specified according to the format described in the X Window System, for
example "example*main_window.width".
- Store the defaults file to disk.
- The XrmValue data structures are initialized
with the strings and their length. The addresses of the XrmValue data
structures are then passed as arguments to the XrmPutResource routine.
3.5 Using Multiple Displays
The Toolkit allows your application to open multiple displays. You can
open multiple displays to run independent instances of an application
on more than one workstation or to interconnect instances of the
application. You use the following sequence of commands to open
multiple displays:
- XtToolkitInitialize (once)
- XtCreateApplicationContext (once)
- XtOpenDisplay (multiple times)
- XtAppCreateShell (multiple times)
- XtAppMainLoop (once)
- MrmFetchWidget (multiple times to fetch multiple main widgets)
- XtManageChild (multiple times to manage multiple main widgets)
- XtRealizeWidget (multiple times for multiple application shells)
You do not need to hard code multiple display names. Instead, on
OpenVMS systems, you can use the SET DISPLAY command to set multiple
display names for your application:
$ SET DISPLAY DPY1/CREATE/NODE="DPY1"
$ SET DISPLAY DPY2/CREATE/NODE="DPY2"
|
DPY1 and DPY2 are logical names that equate to workstation devices. The
following calls to XtOpenDisplay pass logical names instead of display
names:
display = XtOpenDisplay(app_context, "dpy1", "two_heads", "demo",
NULL, 0, &argc, argv);
display_b = XtOpenDisplay(app_context, "dpy2", "two_heads", "demo",
NULL, 0, &argc, argv);
|
On UNIX systems, the ability to use multiple displays depends on which
shell the user is running. If the user is running the C shell, use the
following setenv commands:
setenv dpy1 dpy1:0.0
setenv dpy2 dpy2:0.2
|
For users running either the Bourne shell or Korn shell, use the
following export commands:
export dpy1=dpy1:0.0
export dpy2=dpy2:0.1
|
Then, include the following code in your application:
char *dpy1;
char *dpy2;
dpy1=getenv("dpy1");
dpy2=getenv("dpy2");
display=XtOpenDisplay(app_context,
dpy1, "two_heads", "demo", NULL, 0, &argc, argv);
display_b=XtOpenDisplay(app_context,
dpy2, "two_heads", "demo", NULL, 0, &argc, argv);
|
On Windows NT systems, the command to set the display variables are as
follows:
set dpy1=dpy1:0.0
set dpy2=dpy2:0.0
|
3.5.1 Using Multiple Independent Displays
Example 3-8 and Example 3-9 implement a version of the
widget-centering example shown in Section 3.2.3, which opens two
displays and runs independent instances of the application. Note that
the UIL file is shared.
Example 3-8 Using Multiple Independent
Displays---UIL Module |
.
.
.
module form
version = 'v1.0'
names = case_sensitive
procedure
center_form ();
object
form_main : XmForm{
arguments
{
XmNdialogTitle = compound_string("XmForm");
XmNwidth = 400;
XmNheight = 400;
};
controls
{
XmPushButton a_arrow;
XmPushButton b_arrow;
XmPushButton c_arrow;
};
};
object
a_arrow : XmPushButton {
arguments {
XmNlabelString = compound_string("centered");
XmNtopAttachment = XmATTACH_POSITION;
XmNtopPosition = 50;
XmNbottomAttachment = XmATTACH_NONE;
XmNleftAttachment = XmATTACH_POSITION;
XmNleftPosition = 25;
XmNrightAttachment = XmATTACH_NONE;
};
callbacks {
MrmNcreateCallback = procedure center_form();
};
};
object
b_arrow : XmPushButton {
arguments {
XmNlabelString = compound_string("centered");
XmNtopAttachment = XmATTACH_POSITION;
XmNtopPosition = 50;
XmNbottomAttachment = XmATTACH_NONE;
XmNleftAttachment = XmATTACH_POSITION;
XmNleftPosition = 50;
XmNrightAttachment = XmATTACH_NONE;
};
callbacks {
MrmNcreateCallback = procedure center_form();
};
};
object
c_arrow : XmPushButton {
arguments {
XmNlabelString = compound_string("centered");
XmNtopAttachment = XmATTACH_POSITION;
XmNtopPosition = 50;
XmNbottomAttachment = XmATTACH_NONE;
XmNleftAttachment = XmATTACH_POSITION;
XmNleftPosition = 75;
XmNrightAttachment = XmATTACH_NONE;
};
callbacks {
MrmNcreateCallback = procedure center_form();
};
};
end module;
.
.
.
|
Example 3-9 Using Multiple Independent
Displays---C Module |
.
.
.
#include <stdio>
#include <Mrm/MrmAppl.h>
#include <DXm/DXmCSText.h>
(1)Widget toplevel, toplevel_b, form_w, form_w_b;
static MrmHierarchy s_MrmHierarchy;
static MrmType *dummy_class;
static char *db_filename_vec[] =
(2){"twin_form.uid"
};
/* Forward declarations */
static void center_form();
/* The names and addresses of things that Mrm has to bind. The names do
* not have to be in alphabetical order. */
static MrmRegisterArg reglist[] = {
{"center_form", (caddr_t) center_form}
};
static int reglist_num = (sizeof reglist / sizeof reglist [0]);
int main(argc, argv)
unsigned int argc;
char **argv;
{
XtAppContext app_context;
(3)Display *display, *display_b;
MrmInitialize();
DXmInitialize();
(4)XtToolkitInitialize();
(5)app_context = XtCreateApplicationContext();
(6)
#ifdef VMS
/* The two getenv lines apply to UNIX and Windows NT systems.
Do not include these lines in applications running on
OpenVMS systems. */
#else
/* These two lines apply only to application running on
UNIX and Windows NT systems. */
dpy1=getenv("dpy1");
dpy2=getenv("dpy2");
#endif
display = XtOpenDisplay(app_context, "dpy1", "two_heads", "demo",
NULL, 0, &argc, argv);
display_b = XtOpenDisplay(app_context, "dpy2", "two_heads", "demo",
NULL, 0, &argc, argv);
if (!display) {
XtWarning ("Can't open display one...exiting");
exit(0);
}
if (!display_b) {
XtWarning ("Can't open display two...exiting");
exit(0);
}
(7)toplevel = XtAppCreateShell ("two_heads", NULL,
applicationShellWidgetClass, display, NULL, 0);
toplevel_b = XtAppCreateShell ("two_heads", NULL,
applicationShellWidgetClass, display_b, NULL, 0);
/* Open the UID files (the output of the UIL compiler) in the hierarchy*/
if (MrmOpenHierarchy(1,
db_filename_vec,
NULL,
&s_MrmHierarchy)
!=MrmSUCCESS)
printf("can't open hierarchy");
MrmRegisterNames(reglist, reglist_num);
(8)if (MrmFetchWidget(s_MrmHierarchy, "form_main", toplevel,
&form_w, &dummy_class) != MrmSUCCESS)
printf("can't fetch widget");
if (MrmFetchWidget(s_MrmHierarchy, "form_main", toplevel_b,
&form_w_b, &dummy_class) != MrmSUCCESS)
printf("can't fetch widget");
(9)XtManageChild(form_w);
XtManageChild(form_w_b);
(10)XtRealizeWidget(toplevel);
XtRealizeWidget(toplevel_b);
(11)XtAppMainLoop(app_context);
}
static void center_form(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
Arg arglist[10];
int ac;
int calc_width = 0;
int width_b = 0;
int calc_height = 0;
int height_b = 0;
/* Calculate the button width */
ac = 0;
XtSetArg(arglist[ac], XmNwidth, &width_b);
XtGetValues(w, arglist, 1);
calc_width = width_b/2;
/* Calculate the button height */
ac = 0;
XtSetArg(arglist[ac], XmNheight, &height_b);
XtGetValues(w, arglist, 1);
calc_height = height_b/2;
ac = 0;
XtSetArg (arglist[ac], XmNleftOffset, -calc_width); ac++;
XtSetArg (arglist[ac], XmNtopOffset, -calc_height); ac++;
XtSetValues (w, arglist, ac);
}
.
.
.
|
|