DECwindows Motif Guide to Application Programming


Previous Contents Index

  1. Include the DXmSvn.h file.
  2. The bitmap data to use when creating the pixmap. On OpenVMS systems, you can use the DECW$EXAMPLES:XBITMAP.EXE program to create the bitmap.
  3. Declare data structures to be of type _Node and initialize the first two fields of all of the data structures needed to represent the data hierarchy. For example, for B, the level field is initialized to 1, and the number field is initialized to 7 to indicate that there are 7 children at level 1.
  4. This example uses entries with two components: a pixmap and text.
  5. Specify the svn.uid (UNIX) or SVN.UID (OpenVMS) file.
  6. Fetch the SVN widget, manage it, and realize the top-level widget.

Example 9-6 contains the SVN widget callbacks.

Example 9-6 SVN Callbacks

   .
   .
   .
                            
/* Svn Attach Callback */ 
               
(1)static void svn_attach_proc(svnw) 
                   
Widget svnw; 
{ 
/* 
**  Local data declarations 
*/      
    unsigned int entry_tags [1]; 
    
/* 
**  Announce the routine on the debugging terminal 
*/   
    printf ("AttachToSource handler\n"); 
 
 
/* 
**  Initialize the book data structure 
*/ 
    LclInitializeList ();  
 
 
/*      
**  Make room for the books entries.  I will pass the tag array here since I 
**  know that I have exactly one entry and it's easy to figure out the tag. 
*/ 
    entry_tags[0] = (unsigned int) &B; 
    DXmSvnAddEntries (svnw, 0, 1, 0, entry_tags, TRUE); 
            
 
/* 
**  Reflect this addition in the global count. 
*/                      
    SourceNumEntries = 1; 
}     
 
 
 
/* 
**  SelectAndConfirm callback routine.  This routine is called when one and 
**  only one Entry is selected.  The Entry number selected is provided in the 
**  callback structure. 
*/ 
 
(2)static void svn_confirm_proc(w, unused_tag, data) 
 
  Widget w;      
  int unused_tag; 
  DXmSvnCallbackStruct *data; 
            
{ 
/*     
**  Announce the routine on the debugging terminal 
*/ 
    printf ("SelectAndConfirm handler\n"); 
 
 
/* 
**  Determine if the Entry can be expanded.  If so, then tell the source module 
**  to deal with it.  
*/        
    if (SourceIsNodeParent (data->entry_number, data->entry_tag) == TRUE) 
       { 
         SourceToggleNode (data->entry_number, data->entry_tag); 
         DXmSvnClearSelection (w, data->entry_number); 
       };         
                  
} 
 
 
 
 
/* 
**  This routine is called when the widget wants the Source module to set 
**  the information associated with a particular entry. 
*/ 
 
(3)static void svn_get_entry_proc(svnw, unused_tag, data) 
 
  Widget svnw; 
  int unused_tag; 
  DXmSvnCallbackStruct *data; 
 
{          
/* 
**  Local data declarations 
*/ 
    int     i; 
    NodePtr node; 
    Arg     args[10]; 
    XmFontList fontlist; 
 
    fontlist = XmFontListCreate (XLoadQueryFont (XtDisplay(toplevel), 
                      "*helvetica-medium-r-*-14-*"), XmSTRING_DEFAULT_CHARSET); 
 
/* 
**  Announce the routine on the debugging terminal 
*/          
     printf ("GetEntry handler - entry_number = %d, entry_tag = %d\n", 
             data->entry_number, data->entry_tag); 
 
 
/* 
**  Get at the node (if needed) 
*/ 
    if (data->entry_tag == 0) 
         node = LclGetNodePtr (data->entry_number); 
    else node = (NodePtr) data->entry_tag; 
 
 
/*                     
**  Set up the pixmaps 
*/ 
    LclSetUpPixmap (svnw); 
                     
                 
/* 
**  Set the entry information that both children and parent nodes 
**  have in common. 
*/                                                        
    DXmSvnSetEntryNumComponents (svnw, data->entry_number, SourceNumComps); 
    DXmSvnSetEntryTag (svnw, data->entry_number, node); 
                            
 
 
/* 
 *  The first component is different in parent/child nodes and always present. 
 *  If there are no children, use the child pixmap.  Otherwise use the parent 
 *   pixmap. 
 */ 
 
    if (node->number == 0) 
 
       DXmSvnSetComponentPixmap (svnw, data->entry_number, 1, 0, 0, 
                                 child_pixmap,  pixmap_width, pixmap_height); 
 
    else DXmSvnSetComponentPixmap (svnw, data->entry_number, 1, 0, 0, 
                                   parent_pixmap, pixmap_width, pixmap_height); 
 
                                           
      (4)DXmSvnSetComponentText (svnw, data->entry_number, 2, pixmap_width+4, 
                            0, node->text, fontlist); 
 
}   
 
 
 
/* 
**  Global routine that opens a closed node or closes an open node. 
*/ 
 
void SourceToggleNode (node_number, entry_tag) 
 
  int node_number; 
  unsigned int entry_tag; 
 
{ 
/* 
**  Local data declarations 
*/ 
    NodePtr node; 
 
 
/*                     
**  Get at the node (if needed) 
*/ 
    if (entry_tag == 0) 
         node = LclGetNodePtr (node_number); 
    else node = (NodePtr) entry_tag; 
 
 
/*                         
**  If it is opened, then close it.  Otherwise open it. 
*/ 
    if (node->opened == TRUE) 
         SourceCloseNode (node_number, entry_tag); 
    else SourceOpenNode  (node_number, entry_tag); 
 
} 
 
 
/* 
**  Global routine that tells the caller if the given node has child nodes. 
*/ 
 
Boolean SourceIsNodeParent (node_number, entry_tag) 
 
  int node_number; 
  unsigned int entry_tag; 
 
{ 
/* 
**  Local data declarations 
*/ 
    NodePtr node; 
 
 
/* 
**  Get at the node (if needed) 
*/ 
    if (entry_tag == 0) 
         node = LclGetNodePtr (node_number); 
    else node = (NodePtr) entry_tag; 
 
 
/* 
**  Return TRUE or FALSE 
*/ 
    if (node->children == 0) 
         return FALSE; 
    else return TRUE; 
                 
}  
 
 
 
/* 
**  Global routine that opens a node, given the node number 
*/ 
 
static void SourceOpenNode(node_number, entry_tag) 
 
  int node_number; 
  unsigned int entry_tag; 
 
{ 
/* 
**  Local data declarations 
*/ 
    NodePtr node; 
    NodePtr child_node; 
    int i, x, y; 
 
 
/* 
**  Get at the node (if needed) 
*/ 
    if (entry_tag == 0) 
         node = LclGetNodePtr (node_number); 
    else node = (NodePtr) entry_tag; 
 
/*                                                          
**  If it is already opened, then return. 
*/ 
    if (node->opened == TRUE) 
       return; 
 
/* 
**  If it has no children, then return. 
*/ 
    if (node->number == 0) 
       return; 
 
/* 
**  Mark the node as being opened 
*/ 
    node->opened = TRUE; 
 
 
/* 
 *  Add the entries.  This code does not yet use the entry_tags array.  
 */                      
 
    DXmSvnAddEntries (svn_widget, node_number, node->number, 
                        node->level, NULL, FALSE); 
 
 
/* 
 *  Get to the first child of this node 
 */ 
    child_node = node->children; 
 
 
/* 
 *  For each child, call SetEntry if the child has children.  Also set their 
 *  positions in case we have a UserDefined Tree Style. 
 */ 
    DXmSvnGetEntryPosition(svn_widget, node_number, FALSE, &x, &y); 
    for (i = 1;  i <= node->number;  i++) 
        { 
          if (child_node->children != 0) 
             DXmSvnSetEntry (svn_widget, node_number+i, 0, 0, 2, 1, 0, FALSE); 
          child_node = child_node->sibling; 
          x += 30; 
          y += 30; 
          DXmSvnSetEntryPosition(svn_widget, node_number+i, FALSE, x, y); 
        }; 
                        
 
/* 
**  Reflect this addition in the global count. 
*/ 
    SourceNumEntries = SourceNumEntries + node->number; 
 
} 
 
 
 
/* 
**  Global routine that closes a node, given the node number 
*/ 
 
void SourceCloseNode (node_number, entry_tag) 
                       
  int node_number; 
  unsigned int entry_tag; 
 
{ 
/* 
**  Local data declarations 
*/ 
    NodePtr node; 
 
 
/* 
**  Get at the node (if needed) 
*/ 
    if (entry_tag == 0)             
         node = LclGetNodePtr (node_number); 
    else node = (NodePtr) entry_tag; 
 
 
/* 
**  Call the local recursive close routine. 
*/ 
    LclCloseNode(node, node_number); 
     
}       
 
 
 
/* 
**  Recursively close all nodes given a current node pointer 
**  and a current node number. 
*/ 
 
void LclCloseNode(node, node_number) 
                          
  NodePtr node; 
  int node_number; 
 
{ 
/* 
**  Local data declarations 
*/ 
    int i; 
    NodePtr child_node; 
 
 
/* 
**  If the current node is not opened, then return 
*/ 
    if (node->opened == FALSE) 
       return; 
 
 
/* 
**  Get to the first child of this node 
*/ 
    child_node = node->children; 
   
 
/* 
**  For each child, call CloseNode on each child 
*/ 
    for (i=1;  i<=node->number;  i++) 
        { 
          LclCloseNode (child_node, node_number); 
          child_node = child_node->sibling; 
        }; 
 
 
/* 
**  Tell SVN to remove its children 
*/ 
    DXmSvnDeleteEntries (svn_widget, node_number, node->number); 
          
                      
/* 
**  Mark the node closed 
*/ 
    node->opened = FALSE; 
    if (node->stext != NULL) XtUnmanageChild(node->stext); 
 
/* 
**  Reflect this removal in the global count. 
*/ 
    SourceNumEntries = SourceNumEntries - node->number; 
 
}                                  
 
 
 
 
/* 
**  Routine that maps a node_number into a node structure pointer. 
*/ 
 
NodePtr LclGetNodePtr (node_number) 
 
  int node_number; 
 
{ 
/* 
**  Local routine data 
*/ 
    int i; 
    NodePtr current_node = &B; 
 
 
/* 
**  Loop through until it's found.  If we hit the end of the list, then 
**  we'll return a null pointer. 
*/ 
    if (node_number != 1) 
       for (i = 2;  i <= node_number;  i++) 
            if (current_node == NULL) 
                 break; 
            else if (current_node->opened) 
                     current_node = current_node->children; 
                     else current_node = current_node->sibling; 
 
 
/* 
**  Return the node address 
*/    
    return current_node; 
 
} 
 
   .
   .
   .

  1. After you create an instance of the SVN widget, you must attach it to the data for the hierarchy. The attachment is done in the DXmSvnNattachToSourceCallback callback routine, which is invoked when the SVN widget is realized.
  2. The user has double clicked on a single entry. Your application is responsible for linking the data in the hierarchy to entries in the SVN widget. The entry selected can be determined by examining the entry_number and entry_tag fields of the callback data structure.
  3. Once the data is attached to the SVN widget, the SVN widget triggers the DXmSvnNgetEntryCallback to get information associated with the first entry, such as the number of components and the text from the data hierarchy to associate with the entry. Note that DXmSvnNgetEntryCallback is triggered to get information about any entry in the hierarchy, not just the first entry.
    In the case of the SVN demo application, the DXmSvnNgetEntryCallback callback routine performs the following functions:

Example 9-7 contains additional hierarchy data.

Example 9-7 SVN Hierarchy Data

   .
   .
   .
void LclInitializeList () 
{          
      B.text = XmStringCreate("OSF/Motif Style Guide V1.1", XmSTRING_DEFAULT_CHARSET); 
 
      P1.text = XmStringCreate("1. User Interface Design Principles", XmSTRING_DEFAULT_CHARSET); 
      P2.text = XmStringCreate("2. Input and Navigation Models", XmSTRING_DEFAULT_CHARSET); 
      P3.text = XmStringCreate("3. Selection and Component Activation", XmSTRING_DEFAULT_CHARSET); 
      P4.text = XmStringCreate("4. Application Design Principles", XmSTRING_DEFAULT_CHARSET); 
      P5.text = XmStringCreate("5. Window Manager Design Principles", XmSTRING_DEFAULT_CHARSET); 
      P6.text = XmStringCreate("6. Designing for International Markets", XmSTRING_DEFAULT_CHARSET); 
      P7.text = XmStringCreate("7. Controls, Groups, and Models Reference Pages", 
                                XmSTRING_DEFAULT_CHARSET); 
      C11 .text = XmStringCreate("1.1  Adopt the User's Perspective", XmSTRING_DEFAULT_CHARSET); 
      C12 .text = XmStringCreate("1.2  Give the User Control", XmSTRING_DEFAULT_CHARSET); 
      C13 .text = XmStringCreate("1.3  User Real-World Metaphors", XmSTRING_DEFAULT_CHARSET); 
      C14 .text = XmStringCreate("1.4  Keep Interfaces Natural", XmSTRING_DEFAULT_CHARSET); 
      C15 .text = XmStringCreate("1.5. Keep Interfaces Consistent", XmSTRING_DEFAULT_CHARSET); 
      C16 .text = XmStringCreate("1.6  Communicate Application Actions to the User", 
                                  XmSTRING_DEFAULT_CHARSET); 
      C17 .text = XmStringCreate("1.7  Avoid Common Design Pitfalls", XmSTRING_DEFAULT_CHARSET); 
      C21 .text = XmStringCreate("2.1 The Keyboard Focus Model", XmSTRING_DEFAULT_CHARSET); 
      C22 .text = XmStringCreate("2.2 The Input Device Model", XmSTRING_DEFAULT_CHARSET); 
      C23.text = XmStringCreate("2.3 The Navigation Model", XmSTRING_DEFAULT_CHARSET); 
      C31.text = XmStringCreate("3.1 Selection Models", XmSTRING_DEFAULT_CHARSET); 
      C32.text = XmStringCreate("3.2 Selection Actions", XmSTRING_DEFAULT_CHARSET); 
      C33.text = XmStringCreate("3.3 Component Activation", XmSTRING_DEFAULT_CHARSET); 
      C41.text = XmStringCreate("4.1 Choosing Components", XmSTRING_DEFAULT_CHARSET); 
      C42.text = XmStringCreate("4.2 Layout", XmSTRING_DEFAULT_CHARSET); 
      C43.text = XmStringCreate("4.3 Interaction", XmSTRING_DEFAULT_CHARSET); 
      C44.text = XmStringCreate("4.4 Component Design", XmSTRING_DEFAULT_CHARSET); 
      C51.text = XmStringCreate("5.1 Configurability", XmSTRING_DEFAULT_CHARSET); 
      C52.text = XmStringCreate("5.2 Window Support", XmSTRING_DEFAULT_CHARSET); 
      C53.text = XmStringCreate("5.3 Window Decorations", XmSTRING_DEFAULT_CHARSET); 
      C54.text = XmStringCreate("5.4 Window Navigation", XmSTRING_DEFAULT_CHARSET); 
      C55.text = XmStringCreate("5.5 Icons", XmSTRING_DEFAULT_CHARSET); 
      C61.text = XmStringCreate("6.1 Collating Sequences", XmSTRING_DEFAULT_CHARSET); 
 
   .
   .
   .
 
 
 
/* 
**  Fill in the child pointers for the book, parts, and chapters 
*/ 
    B.children   = &P1;          
    P1.children  = &C11;          
    P2.children  = &C21;          
    P3.children  = &C31;          
    P4.children  = &C41;         
    P5.children  = &C51;         
    P6.children  = &C61;         
    P7.children  = NULL;         
 
    C11.children  = NULL;         
    C12.children  = &C121;         
    C13.children  = &C131;         
    C14.children  = &C141;         
    C15.children  = NULL;         
    C16.children  = &C161;         
    C17.children  = NULL;         
    C21.children  = &C211;         
    C22.children  = &C221;         
    C23.children  = &C231;         
    C31.children  = &C311;         
    C32.children  = &C321;         
    C33.children  = &C331;         
    C41.children  = &C411;         
    C42.children  = &C421;         
    C43.children  = &C431;         
    C44.children  = NULL;         
    C51.children  = NULL;         
    C52.children  = &C521;         
    C53.children  = &C531;         
    C54.children  = NULL;         
    C55.children  = &C551;         
    C61.children  = NULL;         
    C62.children  = &C621;         
    C63.children  = NULL;         
    C64.children  = NULL;         
    C65.children  = NULL;         
    C66.children  = NULL;         
 
 
 
/* 
**  Fill in the sibling pointers for the book 
*/ 
    B.sibling     =  NULL; 
 
 
/* 
**  Fill in the sibling pointers for the parts 
*/ 
    P1.sibling    =  &P2;         
    P2.sibling    =  &P3;         
    P3.sibling    =  &P4;         
    P4.sibling    =  &P5;         
    P5.sibling    =  &P6;         
    P6.sibling    =  &P7;         
    P7.sibling    =  NULL;         
 
 
/* 
**  Fill in the sibling pointers for the chapters 
*/ 
    C11.sibling  = &C12;         
    C12.sibling  = &C13;         
    C13.sibling  = &C14;         
    C14.sibling  = &C15;         
    C15.sibling  = &C16;         
    C16.sibling  = &C17;         
    C17.sibling  = &P2;         
    C21.sibling  = &C22;         
    C22.sibling  = &C23;         
    C23.sibling  = &P3;         
    C31.sibling  = &C32;         
    C32.sibling  = &C33;         
    C33.sibling  = &P4;         
    C41.sibling  = &C42;         
    C42.sibling  = &C43;         
    C43.sibling  = &C44;         
    C44.sibling  = &P5;         
    C51.sibling  = &C52;         
    C52.sibling  = &C53;         
    C53.sibling  = &C54;         
    C54.sibling  = &C55;         
    C55.sibling  = &P6;         
    C61.sibling  = &C62;         
    C62.sibling  = &C63;         
    C63.sibling  = &C64;         
    C64.sibling  = &C65;         
    C65.sibling  = &C66;         
    C66.sibling  = &P7;         
 
 
 
/* 
**  Fill in the sibling pointers for the sections of chapter 1 
*/ 
    C121.sibling  =  &C122;       
    C122.sibling  =  &C13;       
    C131.sibling  =  &C132;       
    C132.sibling  =  &C133;       
    C133.sibling  =  &C14;       
    C141.sibling  =  &C142;       
    C142.sibling  =  &C15; 
    C161.sibling  =  &C162; 
    C162.sibling  =  &C163; 
    C163.sibling  =  &C17; 
 
/* 
**  Fill in the sibling pointers for the sections of chapter 2 
*/ 
    C211.sibling  =  &C212; 
    C212.sibling  =  &C22; 
    C221.sibling  =  &C222; 
    C222.sibling  =  &C223; 
    C223.sibling  =  &C23; 
    C231.sibling  =  &C232; 
    C232.sibling  =  &C233; 
    C233.sibling  =  &C234; 
    C234.sibling  =  &P3; 
 
   .
   .
   .
 
}              

Example 9-8 creates the pixmaps used as icons.

Example 9-8 Creating the SVN Pixmaps (Icons)

   .
   .
   .
 
void LclSetUpPixmap (svnw) 
 
  Widget svnw; 
 
{ 
/* 
**  Local data declarations 
*/                                 
    Screen  *screen  = XtScreen(toplevel);   
    Display *display = DisplayOfScreen (screen); 
    Pixel background_pixel; 
    Pixel foreground_pixel; 
    Arg args [2]; 
 
 
/* 
**  If we've already done this, then return. 
*/ 
    if (parent_pixmap != NULL) return; 
 
 
/* 
**  Get the foreground/background colors of Svn 
*/ 
    XtSetArg    (args[0], XmNforeground, &foreground_pixel); 
    XtSetArg    (args[1], XmNbackground, &background_pixel); 
    XtGetValues (svnw, args, 2); 
 
 
/* 
**  Create the pixmap. 
*/ 
    parent_pixmap = XCreatePixmapFromBitmapData ( 
         display,                               /* (IN) display */ 
         XDefaultRootWindow(display),           /* (IN) drawable */ 
         parent_pixmap_bits,                    /* (IN) bitmap data */ 
         pixmap_width,                          /* (IN) width */ 
         pixmap_height,                         /* (IN) height */ 
         foreground_pixel,                      /* (IN) foreground pixel */ 
         background_pixel,                      /* (IN) background pixel */ 
         DefaultDepthOfScreen(screen));         /* (IN) pixmap depth */ 
                 
    child_pixmap = XCreatePixmapFromBitmapData ( 
         display,                              /* (IN) display */ 
         XDefaultRootWindow(display),          /* (IN) drawable */ 
         child_pixmap_bits,                    /* (IN) bitmap data */ 
         pixmap_width,                         /* (IN) width */ 
         pixmap_height,                        /* (IN) height */ 
         foreground_pixel,                     /* (IN) foreground pixel */ 
         background_pixel,                     /* (IN) background pixel */ 
         DefaultDepthOfScreen(screen));        /* (IN) pixmap depth */ 
 
} 
 
   .
   .
   .


Previous Next Contents Index