DECwindows Motif Guide to Application Programming


Previous Contents Index

  1. The example needs two application shells and two XmForm widgets.
  2. One UID file is shared between instances of the application.
  3. Declare one Display data structure for each display you open.
  4. You need to initialize the toolkit only once.
  5. You need to create only one application context.
  6. Call XtOpenDisplay for each of the displays you want to open.
  7. Create a top-level shell for each instance of the application.
  8. Fetch an instance of the widget hierarchy for each instance of the application.
  9. Manage the main widgets for each instance of the application.
  10. Realize the top-level shells for each instance of the application.
  11. Because there is only one application context, you need to call XtAppMainLoop only once.

3.5.2 Using Multiple Interconnected Displays

Example 3-10 implements an application that interconnects two multiline CSText widgets. Text entered in one widget is also reflected in the other, as if both widgets were simultaneously editing the same file.

Example 3-10 Using Multiple Interconnected Displays

   .
   .
   .
#include <stdio> 
#include <Mrm/MrmAppl.h>      
#include <DXm/DXmCSText.h>      
        
static void change_cs(); 
 
(1)static Widget toplevel, toplevel_b, text_shell, 
       text_shell_b, text_w, text_w_b; 
 
static int ignoreValueChanged = 1; 
 
 
int main(argc, argv) 
    unsigned int argc; 
    char **argv;          
{ 
    XtAppContext    app_context;  
    Arg             arglist[15]; 
    int             ac = 0; 
    XtCallbackRec   callback_arg[2]; 
    (2)Display         *display, *display_b; 
    XmString        cstring; 
 
    (3)XtToolkitInitialize(); 
 
    (4)app_context = XtCreateApplicationContext(); 
 
  (5)
    #ifdef VMS 
    /* The two getenv lines only 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 applications 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...exiting"); 
                  exit(0); 
      } 
 
 
      if (!display_b) { 
                  XtWarning ("Can't open display...exiting"); 
                  exit(0); 
      } 
 
                   
    (6)toplevel = XtAppCreateShell ("two_heads", NULL, 
                              applicationShellWidgetClass, display, NULL, 0); 
 
    toplevel_b = XtAppCreateShell ("two_heads", NULL, 
                              applicationShellWidgetClass, display_b, NULL, 0); 
 
    ac = 0;  
    cstring = XmStringCreateLtoR("User Defined", XmSTRING_ISO8859_1);     
    XtSetArg( arglist[ac], XmNdialogTitle, cstring);ac++; 
    XtSetArg( arglist[ac], XmNallowOverlap, TRUE);ac++;         
    XtSetArg( arglist[ac], XmNheight, 300);ac++;  
    XtSetArg( arglist[ac], XmNwidth, 300);ac++;  
    XtSetArg( arglist[ac], XmNresizePolicy, XmRESIZE_GROW);ac++; 
 
    (7)text_shell = XmCreateBulletinBoard(toplevel, "CSText", arglist, ac ); 
 
    text_shell_b = XmCreateBulletinBoard(toplevel_b, "CSText", arglist, ac ); 
 
    XmStringFree(cstring);    
 
    callback_arg[0].callback = change_cs; 
    callback_arg[0].closure = 0; 
    callback_arg[1].callback = NULL; 
    callback_arg[1].closure = NULL; 
       
    
    ac = 0;  
    XtSetArg( arglist[ac], XmNx, 40);ac++; 
    XtSetArg( arglist[ac], XmNy, 50);ac++;    
    XtSetArg( arglist[ac], XmNrows, 20 ); ac++; 
    XtSetArg( arglist[ac], XmNcolumns, 45 ); ac++;   
    XtSetArg( arglist[ac], XmNvalueChangedCallback, callback_arg);ac++; 
    XtSetArg( arglist[ac], XmNscrollVertical, TRUE);ac++; 
    XtSetArg( arglist[ac], XmNeditMode, XmMULTI_LINE_EDIT);ac++;  
 
    (8)text_w = DXmCreateScrolledCSText(text_shell, "textwidget", 
                                           arglist, ac );  
                             
    text_w_b = DXmCreateScrolledCSText(text_shell_b, "textwidget", 
                                        arglist, ac );  
    
    (9)XtManageChild(text_w);                                    
    XtManageChild(text_w_b);                                    
 
 
    (10)XtManageChild(text_shell);                      
    XtManageChild(text_shell_b);                      
   
    (11)XtRealizeWidget(toplevel); 
    XtRealizeWidget(toplevel_b); 
 
    (12)ignoreValueChanged = 0; 
                          
    (13)XtAppMainLoop(app_context); 
 
 }                                    
 
 
 
 /* The user entered something*/ 
                                             
    
(14)static void change_cs(w, tag, reason) 
     Widget             w; 
     int               *tag;        
     unsigned long     *reason;    
{      
    XmString  new_text; 
    DXmCSTextPosition  last_pos; 
    Widget ww; 
 
    (15)if (ignoreValueChanged) return; 
    (16)ignoreValueChanged = 1; 
 
  
    (17)new_text = DXmCSTextGetString(w);    
    (18)last_pos = DXmCSTextGetLastPosition(text_w); 
 
    (19)if (w == text_w_b) ww = text_w; else ww = text_w_b;  
 
    DXmCSTextSetString(ww, new_text);    
    DXmCSTextSetInsertionPosition(ww, last_pos);  
    DXmCSTextSetInsertionPosition(text_w_b, last_pos);  
 
    XtFree(new_text); 
    ignoreValueChanged = 0;                
} 
   .
   .
   .

  1. The example uses multiple instances of the application shells and all widgets.
  2. Declare one Display data structure for each display you open.
  3. You need to initialize the toolkit only once.
  4. You need to create only one application context.
  5. Call XtOpenDisplay for each of the displays you want to open. The application opens the display identified by the last call to the SET DISPLAY command, and a second, hardcoded display name.
  6. Create a top-level shell for each instance of the application.
  7. Create an XmBulletinBoard widget for each instance of the application. The argument list is shared.
  8. Create a scrolled CSText widget for each instance of the application. The argument list is shared, including the XmNvalueChangedCallback routine to call.
  9. Manage both CSText widgets.
  10. Manage both XmBulletinBoard widgets.
  11. Realize both top-level shells.
  12. Make sure that the value changed callback is not invoked until everything is realized.
  13. Because there is only one application context, you need to call XtAppMainLoop only once.
  14. When the user enters text, this callback routine is called.
  15. Make sure that this callback is not invoked until the top-level shell is realized.
  16. Make sure the callback routine is not invoked until this invocation of the callback routine is complete.
  17. Get the new text entered by the user.
  18. Get the position of the last character of the string.
  19. Find out which of the two CSText widgets generated the callback and set the text and insertion position for the other.

3.6 Creating a Cursor

The Toolkit includes a routine, DXmCreateCursor, that you can call to create a cursor for your application. On UNIX and Windows NT systems, you specify one of the cursor constants defined in the decwcursor.h include file to identify the cursor. Your application must include the DECspecific.h and decwcursor.h include files to use the DXmCreateCursor routine. On OpenVMS systems, you specify one of the cursor constants defined in the DECw$Cursor.h include file to identify the cursor. Your application must include the DECspecific.h and DECw$Cursor.h include files to use the DXmCreateCursor routine.

Example 3-11 shows how to use the DXmCreateCursor routine to create a wait cursor, define this cursor to be used in a window of an application, and then restore the parent's (original) cursor. You need only create the cursor once; you can then define it and undefine it as necessary.

Example 3-11 The DXmCreateCursor Routine

   .
   .
   .
#include <DXm/DECspecific.h> 
 
#ifdef VMS 
/* On OpenVMS systems, use the following include file to identify 
   the cursor. */ 
#include <sys$library/DECw$Cursor.h> 
 
#else 
/* On UNIX and Windows NT systems, use the following include file to identify 
   the cursor. */ 
#include <X11/decwcursor.h> 
 
#endif 
 
   .
   .
   .
                
Widget  toplevel_widget, my_widget; 
Cursor  cursor; 
 
   cursor = DXmCreateCursor(toplevel_widget, decw$c_wait_cursor);   
      
   XDefineCursor(XtDisplay(toplevel_widget), XtWindow(my_widget), cursor); 
   .
   .
   .
   /* Perform some function */ 
 
   XUndefineCursor(XtDisplay(toplevel_widget), XtWindow(my_widget)); 

3.7 Using the XtAppAddInput Routine

As described in the X Window System Toolkit, you can use the XtAppAddInput routine to register an alternative source of input with the Toolkit. When input from this alternate source becomes available, the intrinsics call the supplied callback routine to notify it that input is available.

The XtAppAddInput routine has several operating-system-dependent arguments. The X Window System Toolkit describes all the arguments used for calling the XtAppAddInput routine on UNIX and Windows NT systems.

Note

The remainder of this section applies only to OpenVMS systems.

In the OpenVMS environment, the arguments used in calling the XtAppAddInput routine are as follows:

  1. Application context.
  2. An event flag to monitor. When the intrinsics notices that this flag is set, it calls the XtInputCallbackProc routine you specify. Event flag numbers are restricted to cluster 0, which contains event flag numbers 0 to 31. (See the OpenVMS System Services Reference Manual for more information.) Note that event flag 0 cannot be used as the XtAppAddInput event flag.
  3. An I/O status byte (IOSB) for the condition return code. This argument can be zero.
  4. An XtInputCallbackProc routine you want invoked when input is available; that is, when the event flag is set.
  5. Some data to pass to the XtInputCallbackProc routine.

Your application needs a way to set the event flag to indicate that input is available. The most common method of setting the event flag is by using an AST completion routine. For example, in Example 3-13, the START_READ routine starts a $QIO read and specifies CompletionAst as the AST completion routine. CompletionAst sets the event flag.

Example 3-12 and Example 3-13 implement a program that traps broadcast messages and displays them in an XmScrolledList widget. The program uses mailboxes to handle communications between the processes.

The AllocateAddInputRec routine allocates and initializes a data structure containing allocated space, an application (widget) callback, and tag. This data structure is passed to the CompletionAst routine at AST level and then to your XtInputCallbackProc routine. You can use this data structure as needed by your application.

By using the data structure allocated by AllocateAddInputRec and by replacing the ProcessMessageRec and AddInputCallback routines based on your application's needs, you can use this code to do a $QIO read into a buffer, set an event flag to notify the Toolkit that input is available, and start another $QIO read.

You can use the following commands to compile and link this program:


$ UIL/MOTIF BTRAP.UIL
$ CC/NOOPTIMIZE BTRAP
$ LINK BTRAP,SYS$INPUT/OPT 
SYS$SHARE:DECW$DXMLIBSHR/SHARE,SYS$SHARE:DECW$XLIBSHR/SHARE

Note

One way to test this program is to run it from a DECterm window, give the window input focus, and then press Ctrl/T to generate broadcast messages to be trapped.

Example 3-12 Using the XtAppAddInput Routine---UIL Module

module BTrap 
  names = case_sensitive 
 
 
procedure 
  LabelCreateCallback (); 
  QuitCallback        (); 
 
 
object bTrapMain : XmMainWindow { 
          
        arguments 
             { 
             XmNwidth = 650; 
             XmNheight = 150; 
             }; 
 
       controls 
             { 
             XmForm btrap_form; 
             }; 
 }; 
 
 
 
object 
    btrap_form : XmForm{ 
 
        controls 
             { 
             XmScrolledList bTrapLabel; 
             XmPushButton   bTrapQuitButton; 
             }; 
 }; 
 
 
(1)object bTrapLabel : XmScrolledList { 
 
    arguments 
      { 
      XmNvisibleItemCount = 5;   
      XmNunitType = XmPIXELS; 
      XmNlistSizePolicy = XmVARIABLE; 
      XmNscrollBarDisplayPolicy = XmSTATIC; 
      XmNleftAttachment = XmATTACH_FORM;   
      XmNleftOffset = 0; 
      XmNrightAttachment = XmATTACH_FORM;   
      XmNrightOffset = 0;    
      XmNtopAttachment = XmATTACH_FORM;   
      XmNtopOffset = 3; 
      XmNbottomAttachment = XmATTACH_NONE;    
      };                       
                       
    callbacks 
      { 
      MrmNcreateCallback = procedure LabelCreateCallback();   
      }; 
 }; 
 
 
 
object 
    bTrapQuitButton : XmPushButton { 
 
        arguments { 
              XmNlabelString = compound_string("Quit"); 
              XmNleftAttachment = XmATTACH_NONE;   
              XmNtopAttachment = XmATTACH_NONE; 
              XmNbottomAttachment = XmATTACH_FORM;    
              XmNbottomOffset = 5; 
              XmNrightAttachment = XmATTACH_FORM;    
              XmNrightOffset = 10; 
            }; 
        callbacks {   
         XmNactivateCallback = procedure QuitCallback(); 
        };                     
    };                                  
                                   
 
end module; 
   .
   .
   .

  1. Create an XmScrolledList widget to receive the broadcast messages and attach it to the XmForm widget.

Example 3-13 Using the XtAppAddInput Routine---C Module

  (1)#include <Mrm/MrmAppl.h> 
  #include <descrip.h> 
  #include <jpidef.h> 
  #include <ssdef.h> 
  #include <iodef.h> 
  #include <libdef.h> 
  #include <dvidef.h> 
  #include <psldef.h> 
  #include <prcdef.h> 
  #include <ttdef.h> 
  #include <tt2def.h> 
  #include <msgdef.h> 
                    
 
  /*    
   * Global Data 
   * 
   */ 
 
  static MrmHierarchy s_MrmHierarchy;     /* MRM database hierarchy ID */ 
  static MrmType *dummy_class;            /* and class variable. */   
  static char *db_filename_vec[] =        /* Mrm hierarchy file list. */ 
    {"btrap.uid"                          /* There is only one UID file for */ 
    };                                    /* this application. */ 
  static int db_filename_num = 
                  (sizeof db_filename_vec / sizeof db_filename_vec [0]);  
 
   
  (2)#define MISC_EFN      2             /* use for system service calls */ 
    
 
 
  (3)typedef struct { 
      unsigned short      type; 
      unsigned short      unit; 
      unsigned char       controllerNameLen; 
      char                controllerNameA[15]; 
      unsigned short      messageLen; 
      char                messageA[256]; 
  } VmsMailboxMessage; 
 
 
 
  /* Define a control block to contain information about the mailbox message. 
   * This control block will be passed to the I/O completion routine. */ 
 
  (4)typedef struct _MessageRec { 
      unsigned short      iosbA[4]; 
      VmsMailboxMessage   mailboxMessage; 
  } MessageRec; 
 
  static MessageRec messageRec; 
  static short devChan, mbChan; 
   
 
  /* Definitions for AST routines */ 
 
  #define LIB$_QUEWASEMP  1409772 
  (5)#define ADD_INPUT_EFN   3 
                 
  typedef struct { 
      unsigned long       queueEntryA[2];         /* must be first in struct */ 
      char                *mallocP;               /* address actually malloc-ed */ 
      void                (*routineP)();          /* thread resumption routine */ 
      Opaque              closure;                /* thread closure */ 
  } AddInputRec; 
 
  static _align(quadword) unsigned long addInputQueueHeaderA[2]; 
  static int initialized; 
            
 
  /* Application Context */ 
 
  (6)XtAppContext app_context; 
 
 
  /* Application Widgets */ 
 
  static Widget appW, mainW, labelW; 
 
 
 
 
 
  /* 
   * Forward declarations 
   */ 
 
  static unsigned long StartReadQIO(); 
  static void LabelCreateCallback(); 
  static void QuitCallback(); 
  static void AddInputCallback(); 
  extern void CompletionAst(); 
  extern Opaque AllocateAddInputRec(); 
 
 
  /* The names and addresses of things that Mrm has to bind.  The names do 
   * not have to be in alphabetical order.  */ 
 
  static MrmRegisterArg reglist[] = { 
      {"LabelCreateCallback", (caddr_t) LabelCreateCallback}, 
      {"QuitCallback", (caddr_t) QuitCallback} 
  };    
 
  static int reglist_num = (sizeof reglist / sizeof reglist [0]); 
 
                
 
                      
            
  (7)static void ProcessMessageRec(messageRecP) 
      MessageRec *messageRecP; 
  { 
      VmsMailboxMessage *mailboxMessageP = &messageRecP->mailboxMessage; 
      int bell = 0;      
      char c, bufA[256]; 
      char *fromBufP = mailboxMessageP->messageA; 
      int fromBufLen = mailboxMessageP->messageLen; 
      char *toBufP; 
      Arg al[1]; 
      XmString labelP; 
 
      /* If this is a non-null broadcast message, pass it to XmScrolledList. */ 
 
      if ((mailboxMessageP->type == MSG$_TRMBRDCST) && fromBufLen) { 
          if (fromBufP[fromBufLen-1] != '\n') fromBufP[fromBufLen++] = '\n'; 
    
          while (fromBufLen) { 
              toBufP = bufA; 
              bell = 0; 
    
              while (1) { 
                  c = *(fromBufP++); fromBufLen--; 
    
                  if (c == 7) bell++; 
                  else if (c == '\t') *(toBufP++) = ' '; 
                  else if (c == '\n') {*toBufP = 0; break;} 
                  else *(toBufP++) = c; 
              } 
    
              if (bufA[0]) {     
                  labelP = XmStringLtoRCreate(bufA,""); 
                          
                  XmListAddItem(labelW, labelP, 0); 
                  XtFree (labelP); 
              }   
 
              while (bell--) XBell (XtDisplay (labelW), 0); 
          } 
      } 
 
      /* Start another asynchronous read. */ 
 
      StartReadQIO (messageRecP); 
  } 
                     
 
         
  (8)static unsigned long StartReadQIO(messageRecP) 
      MessageRec *messageRecP; 
  { 
      unsigned long status; 
 
                         
      status = sys$qio ( 
          MISC_EFN,                     /* always use this EFN */ 
          mbChan,                       /* mailbox channel */ 
          IO$_READVBLK,                 /* function code */ 
          (9)messageRecP->iosbA,           /* IOSB (in message control block) */ 
          (10)CompletionAst,                /* always use this ASTADR */ 
          (11)AllocateAddInputRec(ProcessMessageRec, messageRecP), 
                                        /* callback and its argument */   
          &messageRecP->mailboxMessage, /* buffer address */ 
          sizeof(VmsMailboxMessage),    /* buffer length */ 
          0, 0, 0, 0);                  /* unused QIO parameters */ 
 
      return (status); 
 
 
  } 
 
  typedef struct {                       
      short               bufferLength; 
      short               itemCode; 
      char                *bufP; 
      unsigned short      *bufLenP; 
  } GetjpiItemList; 
 
 
  static unsigned long masterPid; 
  static GetjpiItemList masterPidItemListA[2] = { 
      {4, JPI$_MASTER_PID, &masterPid, 0}, 
      {0, 0, 0, 0}}; 
 
                     
  static char devNameBufA[64]; 
  static unsigned short devNameLen; 
  static GetjpiItemList devNameItemListA[2] = { 
      {sizeof(devNameBufA)-1, JPI$_TERMINAL, devNameBufA, &devNameLen}, 
      {0, 0, 0, 0}}; 
 
  #define Check(s)        if ((status = s) != SS$_NORMAL) return (status) 
        
 
  (12)static unsigned long StartTrappingMessages()  
  { 
      unsigned long status; 
      unsigned long modeBufA[3]; 
      unsigned short dviBufA[2]; 
      unsigned short iosbA[4]; 
   
      /* Get the terminal name owned by the master process of our job tree. */ 
 
      Check (sys$getjpiw (MISC_EFN, 0, 0, masterPidItemListA, 
          iosbA, 0, 0)); 
      Check (iosbA[0]); 
 
      Check (sys$getjpiw (MISC_EFN, &masterPid, 0, devNameItemListA, 
          iosbA, 0, 0)); 
      Check (iosbA[0]); 
 
      /* Assign a channel (with mailbox) to that terminal device, and enable 
       * the mailbox so that messages will be sent to it. */ 
 
      { 
      struct dsc$descriptor_s devNameDsc = 
          {devNameLen, DSC$K_DTYPE_T, DSC$K_CLASS_S, devNameBufA}; 
      int maximumMessageSize = sizeof(VmsMailboxMessage); 
      int bufferQuota = sizeof(VmsMailboxMessage)*32; 
    
      Check (lib$asn_wth_mbx (&devNameDsc, &maximumMessageSize, &bufferQuota, 
          &devChan, &mbChan)); 
      } 
 
      { 
      char dummyBufA[4]; 
 
      Check (sys$qiow (MISC_EFN, devChan, IO$_WRITEVBLK | IO$M_ENABLMBX, 
          iosbA, 0, 0, dummyBufA, 0, 0, 0, 0, 0)); 
      Check (iosbA[0]); 
      } 
 
      /* Set the terminal NOBROADCAST since messages will be displayed in 
       * our window. */ 
 
      Check (sys$qiow (MISC_EFN, devChan, IO$_SENSEMODE, iosbA, 0, 0, 
          modeBufA, sizeof(modeBufA), 0, 0, 0, 0)); 
      Check (iosbA[0]); 
 
 
      { 
      (13)modeBufA[1] |= TT$M_NOBRDCST; 
      modeBufA[2] |= TT2$M_BRDCSTMBX; 
      Check (sys$qiow (MISC_EFN, devChan, IO$_SETMODE, iosbA, 0, 0, modeBufA, 
          sizeof(modeBufA), 0, 0, 0, 0)); 
      Check (iosbA[0]); 
      } 
 
      /* Start the first asynchronous mailbox read. */ 
  
      (14)Check (StartReadQIO (&messageRec)); 
 
      printf("FYI - messages are being trapped\n"); 
 
      return (SS$_NORMAL); 
  } 
 
                      
 
 
 
  static int main(argc, argv) 
      int  argc; 
      char **argv; 
  { 
      unsigned long status; 
 
 
      MrmInitialize();                    /* Initialize MRM before initializing 
                                          /* the X Toolkit. */ 
 
      /* Initialize the application. */ 
                 
        appW = XtAppInitialize(&app_context, 
                                          /* App. context is returned */ 
        "btrap$defaults",                 /* Root class name. */ 
        NULL,                             /* No option list. */ 
        0,                                /* Number of options. */ 
        &argc,                            /* Address of argc */ 
        argv,                             /* argv */ 
        NULL,                             /* No fallback resources */ 
        NULL,                             /* No override resources */ 
        0);                               /* No override resources */ 
 
 
         /* Open the UID files (the output of the UIL compiler) in the hierarchy*/ 
 
      if (MrmOpenHierarchy(db_filename_num, /* Number of files. */ 
        db_filename_vec,                    /* Array of file names.  */ 
        NULL,                               /* Default OS extension. */ 
        &s_MrmHierarchy)                    /* Pointer to returned MRM ID */ 
        !=MrmSUCCESS) 
          printf("can't open hierarchy"); 
 
 
      /* Register the items MRM needs to bind for us. */ 
 
      MrmRegisterNames(reglist, reglist_num); 
 
        
    /* Start to trap messages and do the $QIO read of the mailbox */ 
 
      (15)if ((status = StartTrappingMessages ()) != SS$_NORMAL) { 
          printf ("BTrap - Unable to trap broadcast messages"); 
          return (status); 
      }; 
 
 
          /* Go get the main part of the application. */ 
 
      if (MrmFetchWidget(s_MrmHierarchy, "bTrapMain", appW, 
        &mainW, &dummy_class) != MrmSUCCESS) 
          printf("can't fetch main window"); 
 
      XtManageChild (mainW);                      /* manage the main window */ 
 
      XtRealizeWidget (appW);                     /* realize the widget tree */ 
 
 
    
      XtAppMainLoop(app_context);                 /* and go to work */ 
  } 
 
 
    
 
  /* The routine you want to be invoked by XtAppAddInput.  
   * AddInputCallback does not use the tag argument of XtAppAddInput.   
   */ 
  
 
  (16)static void AddInputCallback() 
  { 
      unsigned long status; 
      AddInputRec *addInputRecP; 
 
      sys$clref (ADD_INPUT_EFN);  /* clear flag so we can be called again */ 
                                              
      while (lib$remqhi (addInputQueueHeaderA, &addInputRecP, 0) != 
        LIB$_QUEWASEMP) { 
          (*addInputRecP->routineP) (addInputRecP->closure); 
          XtFree (addInputRecP->mallocP); 
      }          
  }                        
 
 
 
  /* Use CompletionAst as the ASTADR parameter on asynchronous system service 
   * calls.  This routine must not be called directly from the application. 
   * It adds an application callback to the pending callback list. */ 
 
  void CompletionAst(addInputRecP) 
      AddInputRec *addInputRecP; 
  {                         
      lib$insqti (addInputRecP, addInputQueueHeaderA, 0); 
      sys$setef (ADD_INPUT_EFN); 
  } 
             
  /* Use AllocateAddInputRec as the ASTPRM parameter on asynchronous system 
   * service calls.  Arguments to this routine are the application callback 
   * routine to be called when the system service completes and the parameter 
   * to be passed to that callback.  AllocateAddInputRec allocates and 
   * initializes an application callback record to be passed to the 
   * CompletionAst routine at AST level when the system service completes. */ 
                 
 
  Opaque AllocateAddInputRec(routineP, closure) 
      void (*routineP)(); 
      Opaque closure; 
  { 
      char *mallocP; 
      AddInputRec *addInputRecP; 
      
      if (!initialized) XtAppAddInput (app_context, ADD_INPUT_EFN, 
                                       0, AddInputCallback, 0); 
 
      mallocP = XtMalloc (sizeof (AddInputRec) + 7); 
      addInputRecP = (AddInputRec *)(((int)(mallocP) + 7) & (-8)); 
      addInputRecP->mallocP = mallocP; 
      addInputRecP->routineP = routineP; 
      addInputRecP->closure = closure; 
 
      return ((Opaque)addInputRecP); 
  } 
 
 
 
 
 
 
  /* Callback Routines */ 
 
    static void LabelCreateCallback(w, tag, reason) 
      Widget              w; 
      int                 *tag; 
      XmAnyCallbackStruct *reason; 
  { 
      labelW = w;    
  } 
 
 
 
  static void QuitCallback(w, tag, reason) 
      Widget              w; 
      int                 *tag; 
      XmAnyCallbackStruct *reason; 
 
  { 
      exit (1); 
  } 


Previous Next Contents Index