home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
desqview
/
api_exam.arc
/
WASHER_P.C
< prev
next >
Wrap
Text File
|
1988-10-05
|
12KB
|
370 lines
/****************************************************************
*
* Name: WASHER
*
* Function: Emulate a washing machine control panel.
*
* Shows how to: 1. construct complex menus (dialogues) including
* select, input, output, and inactive fields.
* 2. change field types dynamically.
* 3. implement "radio button" select fields.
* 4. use a timer object to measure time intervals.
* 5. use an objectq to wait for multiple events.
*
****************************************************************/
#include <stdio.h>
#include "dvapi.h"
/* minimum API version required */
#define required 0x201
/* possible values of the "temperature" variable */
#define HOT 0
#define WARM 1
#define COLD 2
/* possible values of the "state" variable */
#define IDLE 0
#define WASHING 1
#define FIRST_RINSE 2
#define FIRST_SPIN 3
#define FINAL_RINSE 4
#define FINAL_SPIN 5
/* actual API version number */
int version;
/* object handles */
ulong winme,pan,win,kbd,tim,obj;
/* variables used when reading from the menu */
char *kptr,*kend,field,field1[3];
int klng,kstatus,fsize;
/* variables set according to menu input */
int wash_time,temperature,second_rinse,bell;
/* state related variables */
int state,indicator,done;
/* variables for saving the cursor position */
int row,col;
/* panel library filename in ASCIIZ string format */
char lib[] = "examples.plb\x00";
/* name of panel within panel library */
char name[] = "washer";
/* status of last pan_open and pan_apply operation */
int status;
/**********************************************************************
* main - check for DESQview present and enable required extensions.
***********************************************************************/
main () {
/* initialize C interfaces and get API version number */
version = api_init();
/* if DESQview is not running or version is too low, display a message */
if (version < required) {
printf ("This program requires DESQview version %d.02%d or later.\n",
required/256,required%256);
}
/* tell DESQview what extensions to enable and start application */
else {
api_level (required);
program_body();
}
/* disable C interfaces and return from program */
api_exit();
}
/**********************************************************************
* program_body - initialize application and loop processing events.
***********************************************************************/
program_body () {
/* get task window handle and open objectq */
winme = win_me();
obq_open();
/* create timer object */
tim = tim_new();
/* create and open panel object, and associate it with panel library */
pan = pan_new();
status = pan_open (pan,lib,sizeof (lib));
/* apply named panel, and return window & keyboard handles */
status = pan_apply (pan,winme,name,strlen (name),&win,&kbd);
/* preselect "hot water". Jump cursor to field 1. Set "state" to idle */
radio_button (win,2,4,2);
fld_cursor (win,1);
change_state (IDLE,0);
done = 0;
/* position menu, mark as displayable, and make topmost in application. */
win_top (win);
/* loop until "done" becomes TRUE */
while (!done) {
/* wait for input from any open object and return its handle */
obj = obq_read();
/* determine which object it is and process accordingly */
if (obj == kbd)
process_menu_event();
else
if (obj == tim)
process_timer_event();
};
/* free all allocated objects and return */
key_free (kbd);
win_free (win);
pan_free (pan);
tim_free (tim);
}
/**********************************************************************
* process_menu_event - process data returned from the menu.
***********************************************************************/
process_menu_event () {
/* get menu data and determine what event caused data to be returned */
key_read (kbd,&kptr,&klng);
kstatus = key_status (kbd);
/* beep and return if anything but a field selection */
if (kstatus != 1) {
api_sound (1000,5);
return;
};
/* point just past returned data. Save current cursor position. */
kend = kptr+klng;
qry_cursor (win,&row,&col);
/* loop once for each field returned */
while (kptr < kend) {
/* get field # and length. Log field info to task window. */
field = *kptr;
fsize = *(int *)(kptr+1);
win_printf (winme,"field = %d length = %d contents = ",field,fsize);
win_write (winme,kptr+3,fsize);
win_printf (winme,"\n");
/* dispatch based on field number */
switch (field) {
case 1: /* wash time changed */
/* copy returned data to string variable and zero terminate */
memcpy (field1,kptr+3,2);
field1[2] = 0;
/* convert to integer, clip at zero, and set state to IDLE */
wash_time = atoi (field1);
if (wash_time < 0)
wash_time = 0;
change_state (IDLE,0);
break;
case 2: /* Hot water selected - Select field 2. Deselect fields
3 and 4. Log temperature. */
radio_button (win,2,4,2);
temperature = HOT;
break;
case 3: /* Warm water selected - Select field 3. Deselect fields
2 and 4. Log temperature. */
radio_button (win,2,4,3);
temperature = WARM;
break;
case 4: /* Cold water selected - Select field 4. Deselect fields
2 and 3. Log temperature. */
radio_button (win,2,4,4);
temperature = COLD;
break;
case 5: /* Second rinse - if the field data is "Y", the field is
selected. Otherwise, the data will be "N". */
second_rinse = (*(kptr+3) == 'Y');
break;
case 6: /* Beep when done - if the field data is "Y", the field is
selected. Otherwise, the data will be "N". */
bell = (*(kptr+3) == 'Y');
break;
case 7: /* Start button */
/* deselect field so it does not remain highlighted */
fld_type (win,7,FLT_DESELECT);
/* ignore if no wash time has been selected. Otherwise ... */
if (wash_time != 0) {
/* convert field 1 to an output field. Disable the start button
and enable the stop button */
fld_type (win,1,FLT_OUTPUT);
fld_type (win,7,FLT_INACTIVE);
fld_type (win,8,FLT_DESELECT);
/* set timer to run 1 second. If IDLE, set state to WASHING. */
tim_addto (tim,100L);
if (state == IDLE)
change_state (WASHING,10);
}
break;
case 8: /* Stop button - stop cycle and reset field types. */
stop_cycle();
break;
case 9: /* Exit button - stop cycle, reset fields, and set "done". */
stop_cycle();
done = 1;
break;
default: /* unknown field number - should never happen. */
win_printf (winme,"impossible!\n");
}
/* bump pointer to next field and loop */
kptr += (fsize+3);
}
/* restore original cursor position */
win_cursor (win,row,col);
}
/**********************************************************************
* process_timer_event - process timer expiration
***********************************************************************/
process_timer_event () {
long time;
/* read the timer object to clear the event */
time = tim_read(tim);
/* save cursor position. Decrement time remaining and display. */
wash_time -= 1;
qry_cursor (win,&row,&col);
fld_cursor (win,1);
win_printf (win,"%2d",wash_time);
/* if the clock has expired, dispatch based on current state.
In each case, switch to the next state and light the appropriate
indicator. */
if (wash_time == 0) {
switch (state) {
case WASHING:
change_state ((second_rinse) ? FIRST_RINSE:FINAL_RINSE, 11);
break;
case FIRST_RINSE:
change_state (FIRST_SPIN,12);
break;
case FIRST_SPIN:
change_state (FINAL_RINSE,11);
break;
case FINAL_RINSE:
change_state (FINAL_SPIN,12);
break;
case FINAL_SPIN: /* Cycle complete - switch to IDLE state, beep if
requested. Restore original field types. */
change_state (IDLE,0);
if (bell == 1) api_sound (2000,18);
stop_cycle();
break;
}
/* unless we are now IDLE, we need to start a rinse or spin cycle.
do so by setting the clock to 3 seconds and setting the timer to
expire in 1 second. */
if (state != IDLE) {
wash_time = 3;
tim_addto (tim,100L);
}
}
/* if clock is still counting, simply set timer for another second */
else
tim_addto (tim,100L);
/* restore cursor to its original position */
win_cursor (win,row,col);
}
/**********************************************************************
* radio_button - select a specified field and deselect all others in
* the given range.
***********************************************************************/
radio_button (win,first,last,chosen) ulong win; int first,last,chosen; {
int i;
/* loop for each field in range "first" through "last" */
for (i=first; i<=last; i++)
/* change "chosen" field type to SELECTed, others to DESELECTed */
fld_type (win,i,(i==chosen) ? FLT_SELECT : FLT_DESELECT);
}
/**********************************************************************
* change_state - changes the current state of the wash cycle and
* lights the specified indicator. The previously
* lighted indicator, if any, is turned off.
***********************************************************************/
change_state (newstate,field) int newstate,field; {
/* log new state */
state = newstate;
/* if an indicator is ON, turn it OFF */
if (indicator != 0) fld_attr (win,indicator,1);
/* turn ON the requested indicator and remember it */
if (field != 0) fld_attr (win,field,5);
indicator = field;
}
/**********************************************************************
* stop_cycle - stops the current timer, if any. Changes field 1 back
* to an input field, enables the start button, and
* disables the stop button.
***********************************************************************/
stop_cycle () {
tim_erase (tim);
fld_type (win,1,FLT_INPUT);
fld_type (win,7,FLT_DESELECT);
fld_type (win,8,FLT_INACTIVE);
}