DECwindows Motif Guide to Application Programming


Previous Contents Index

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; 

  1. Because the example lets the user determine the XmNwidth and XmNheight defaults, the XmNwidth and XmNheight values are not hardcoded.
  2. Declare a "Save Settings" XmCascadeButton.
  3. Declare a "Save Width and Height" XmPushButton. The activate callback for this push-button calls the save defaults routine.
  4. Declare an "Exit" XmPushButton. The activate callback for this push-button calls the exit routine.
  5. 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);                    
}                       
   .
   .
   .

  1. Define a constant to specify the defaults file name in calls to the Xrm resource manager routines.
  2. 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.
  3. The save-the-defaults routine invoked by the push_me push-button callback.
  4. Get the defaults file from disk.
  5. Get the current XmNwidth and XmNheight values.
  6. 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".
  7. Store the defaults file to disk.
  8. 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:

  1. XtToolkitInitialize (once)
  2. XtCreateApplicationContext (once)
  3. XtOpenDisplay (multiple times)
  4. XtAppCreateShell (multiple times)
  5. XtAppMainLoop (once)
  6. MrmFetchWidget (multiple times to fetch multiple main widgets)
  7. XtManageChild (multiple times to manage multiple main widgets)
  8. 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);       
                    
}                                         
   .
   .
   .


Previous Next Contents Index