/* © Copyright 2005 Hewlett-Packard Development Company, L.P. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license. */ /* PROGRAM NAME: FORMS$DEMO_TIMER_C.C PROGRAM DESCRIPTION: This program is an example that shows how to asynchronously (ast) update a field with DECforms. In this program, we update a field with the current time. However, the method is generally applicable to updating a field on the screen with any information -- asynchronously. AUTHOR: Hewlett-Packard Development Company, L.P. CREATION DATE: May-1995 History: * * Begin Itanium port. * This is the first phase of the Itanium port. System is * updated to compile/link with latest versions of the * compilers. The next phase of the Itanium port will be * to cross-compile on Alpha. * 16-Jul-2003 AFL Changes to use current compilers and libraries, refer to note conference * CAMINO::SYS$SYSDEVICE:[NOTES$LIBRARY]DECFORMS-IPF-PORT.NOTE for more information. * (removed declaration of function "exit", see Note 56) ------ Instructions ------ If your system manager copied the Sample from the DECforms kit onto your system, you can run the DECforms Sample Timer Application by doing the following: $ RUN FORMS$EXAMPLES:FORMS$DEMO_TIMER_C The DECforms INTRODUCTORY Sample Checking Application in the C language consists of two files: FORMS$DEMO_TIMER_C.C The application itself FORMS$DEMO_TIMER_FORM.IFDL The IFDL source form Both files are copied from the DECforms kit to the FORMS$EXAMPLES directory. Putting the files in FORMS$EXAMPLES is an installation option; talk to your system manager if they aren't there. A working version of the application can be created in your own directory from these sources by doing the following: $! Set the default to your own directory: $ SET DEFAULT yourdirectory $ $! Copy all the sources files from FORMS$EXAMPLES to your own directory: $ COPY FORMS$EXAMPLES:FORMS$DEMO_TIMER_C.C, - FORMS$DEMO_TIMER_FORM.IFDL [] $! Compile the C source: $ CC FORMS$DEMO_TIMER_C.C $ $! Translate the IFDL source form: $ FORMS TRANSLATE FORMS$DEMO_TIMER_FORM.IFDL $ $! Extract an object module from the binary form: $ FORMS EXTRACT OBJECT FORMS$DEMO_TIMER_FORM.FORM $ $! Link the C and the Form objects: $! With VAX C: $ LINK FORMS$DEMO_TIMER_C.OBJ, FORMS$DEMO_TIMER_FORM.OBJ, - SYS$INPUT/OPTIONS SYS$LIBRARY:VAXCRTL.OLB/LIB $! With DEC C: $ LINK FORMS$DEMO_TIMER_C.OBJ, FORMS$DEMO_TIMER_FORM.OBJ ! ! note that FORMS$AR_FORM_TABLE must be specified in the FORMS$ENABLE call ! to locate the form in memory You can then run the executable in your own directory by simply typing: $ RUN FORMS$DEMO_TIMER_C How It Works ------------ The method used is to enable TWO sessions to the same form - one for the normal non-ast form work and the other for the ast work. Once the two sessions are enabled a single SEND is performed at non-ast level for the ast session and a timer is started to invoke an ast-routine after a period of time. The normal non-ast work is then started. In this example a simple RECEIVE loop is used. Related form file: forms$demo_timer_form.ifdl The form DEMO_TIMER_FORM is here. It has two form records: AST - for AST send and NAST for non-ast receive. */ /* * The DECforms definitions */ #include #include #include #include /* * A simple macro to construct a string descriptor for a structure */ #define $STRUCTURE_DESCRIPTOR(name,rec) struct dsc$descriptor_s name = {sizeof(rec), DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&rec} /* A session desc must be used on every call to the FORMS$... subroutines. forms_status is returned from every call on the FORMS$... subroutines. */ char session_buffer[] = " "; char main_session_buffer[] = " "; $DESCRIPTOR (session_desc, session_buffer); $DESCRIPTOR (main_session_desc, main_session_buffer); $DESCRIPTOR (term_desc, "SYS$INPUT"); $DESCRIPTOR (form_name_desc, "DEMO_TIMER_FORM"); $DESCRIPTOR (watch_desc, " -Watch this space- "); int forms_status; typedef struct _Item_List { short buff_length; short code; char *buff_addr; int length_returned; } Item_List; struct ast_time_struct { char ast_time_field[23]; } ast_time; struct nast_record_struct { char f1[8]; char f2[8]; } nast_record; char empty_field[] = " "; $STRUCTURE_DESCRIPTOR (nast_record_desc, nast_record); $STRUCTURE_DESCRIPTOR (ast_time_desc, ast_time); $DESCRIPTOR (nast_name_desc, "NAST"); $DESCRIPTOR (ast_name_desc, "AST"); /* Commented out to solve the information that triggered with the new complier as the returned type of the extrnal */ /* function (exit) defined as int but the compiler expected it as void. */ /* Refer to Note 56 for more details. */ /*extern exit();*/ extern lib$date_time(); extern lib$signal(); extern sys$setimr(); void forms_demo_timer_set_timer (); void check_forms_status () { /* Check the parameter for success. If not success, print error message and stop. */ if ((forms_status % 2)==0) { /* if even */ lib$signal (forms_status); exit (1); } } void forms_demo_timer_ast_routine () { Item_List request_options[2]; /* Get the current date/time */ forms_status = lib$date_time (&ast_time_desc); check_forms_status(); /* Set up the request options for the completion routine */ request_options[0].code = FORMS$K_ASTADR; request_options[0].buff_addr = (char *)forms_demo_timer_set_timer; request_options[1].code = 0; /* SEND to the AST session at ast level */ forms_status = forms$send ( &session_desc, /* session id */ &ast_name_desc, /* record name in form */ &1, /* Number of records sent */ 0,0, /* Receive ctl text msg/count */ 0,0, /* Send ctl text msg/count */ 0, /* timeout */ 0, /* parent request id */ request_options, /* request options item list*/ &ast_time_desc, /* the record */ 0); /* shadow record */ check_forms_status(); } void forms_demo_timer_set_timer () { int delay[2]; delay[0] = -10000000; delay[1] = -1; /* Set the timer */ forms_status = sys$setimr (0, &delay, forms_demo_timer_ast_routine, 0, 0); check_forms_status(); } int main (int argc, char *argv[]) { /* Start the two sessions... */ /* Start the non-ast session */ forms_status = forms$enable ( &forms$ar_form_table, /* Vector address */ &term_desc, /* Device name */ &main_session_desc, /* session id returned */ 0, /* Name of form file */ &form_name_desc, /* Name of form */ /* The following trailing pars can be omitted */ 0, /* Receive ctl msg */ 0, /* Receive ctl ct */ 0, /* Send ctl msg */ 0, /* Send ctl ct */ 0, /* Timeout */ 0, /* Parent request id */ 0); /* request options item list */ check_forms_status(); /* Start the AST session */ forms_status = forms$enable ( &forms$ar_form_table, /* Vector address */ &term_desc, /* Device name */ &session_desc, /* session id returned */ 0, /* Name of form file */ &form_name_desc, /* Name of form */ /* The following trailing pars can be omitted */ 0, /* Receive ctl msg */ 0, /* Receive ctl ct */ 0, /* Send ctl msg */ 0, /* Send ctl ct */ 0, /* Timeout */ 0, /* Parent request id */ 0); /* request options item list */ check_forms_status(); /* SEND to the AST session at non-ast level */ forms_status = forms$send ( &session_desc, /* session id */ &ast_name_desc, /* record name in form */ &1, /* Number of records sent */ 0,0, /* Receive ctl text msg/count */ 0,0, /* Send ctl text msg/count */ 0, /* timeout */ 0, /* parent request id */ 0, /* request options item list*/ &watch_desc, /* the record */ 0); /* shadow record */ check_forms_status(); /* Start a timer for the AST SEND */ forms_demo_timer_set_timer (); /* Non-ast RECEIVE loop */ while (1) { /* RECEIVE the non-ast record */ forms_status = forms$receive ( &main_session_desc, &nast_name_desc, &1, 0,0, 0,0, 0, 0, 0, &nast_record_desc, 0); check_forms_status(); /* Check for quitting */ /* Quit if both blank */ if (strncmp(nast_record.f1, empty_field, 8) == strncmp(nast_record.f2, empty_field, 8)) { forms_status = forms$disable (&session_desc); check_forms_status(); forms_status = forms$disable (&main_session_desc); check_forms_status(); exit (1); } } }