/* COPYRIGHT (c) 1995 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED. THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. */ /* 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: Digital Equipment Corporation CREATION DATE: May-1995 ------ 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"); 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); } } }