/* QUERY.C Written by DavidW Started on 28/11/91 */ #include #include #include #include #include #include #include LOCAL_D TEXT *cmds[]= { "iInches/Centimetres", "mMiles/Kilometres", "lPounds/Kilogrammes", "pPints/Litres", "fFahrenheit/Centigrade", "dDay of week", "cCombinations", "tTime difference", "hHoroscope", "nNow", "wPassword", "eEncrypt", "uDecrypt", "sSignificance", "zFile size", "xExit", NULL }; #define CONVERT_ITEMS 5 #define CALENDAR_ITEMS 5 #define SECRET_ITEMS 3 #define SPECIAL_ITEMS 3 #define ITEMS_BEFORE_CONVERT 0 #define ITEMS_BEFORE_CALENDAR CONVERT_ITEMS #define ITEMS_BEFORE_SECRET (ITEMS_BEFORE_CALENDAR+CALENDAR_ITEMS) #define ITEMS_BEFORE_SPECIAL (ITEMS_BEFORE_SECRET+SECRET_ITEMS) LOCAL_D H_MENU_DATA mdata[]= { "Conversions",CONVERT_ITEMS, "Calendar",CALENDAR_ITEMS, "Secret",SECRET_ITEMS, "Special",SPECIAL_ITEMS, NULL }; GLDEF_D TEXT ** _cmds=(&cmds[0]); GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]); LOCAL_D UINT MainWid; LOCAL_D WORD ndp=2; LOCAL_D DOUBLE small; LOCAL_D DOUBLE vsmall; LOCAL_D TEXT pass[10]; LOCAL_D VOID *ttH; LOCAL_D UWORD ttMonth=1; LOCAL_D UWORD ttSuffix=1; LOCAL_D UWORD ttDay=1; LOCAL_D UWORD ttCentury=2; LOCAL_D UWORD ttSeconds=2; LOCAL_C VOID CalcSmall(VOID) { DOUBLE dndp; DOUBLE ten; dndp=(-ndp); ten=10; p_pow(&small,&ten,&dndp); vsmall=small/2; } LOCAL_C VOID Clip(DOUBLE *pval) { DOUBLE remain; if (*pval>=0) (*pval)+=vsmall; else (*pval)-=vsmall; p_mod(&remain,pval,&small); (*pval)-=remain; } LOCAL_C VOID Temperatures(VOID) { DOUBLE fahr; DOUBLE cent; H_DI_FLOAT ffahr; H_DI_FLOAT fcent; INT index; fahr=32; cent=0; ffahr.value=(&fahr); ffahr.low=(-17968); ffahr.high=18032; fcent.value=(¢); fcent.low=(-10000); fcent.high=10000; FOREVER { if (uOpenDialog("Convert temperature")) return; if (uAddDialogItem(H_DIALOG_FLOAT,"Fahrenheit",&ffahr)) return; if (uAddDialogItem(H_DIALOG_FLOAT,"Centigrade",&fcent)) return; index=uRunDialog(); if (index<=0) break; if (index==2) { cent=(fahr-32)*5/9; Clip(¢); } else { fahr=32+cent*9/5; Clip(&fahr); } } } LOCAL_C VOID Convert(TEXT *pmt1,TEXT *pmt2,INT high1,INT high2) { DOUBLE val1; DOUBLE val2; H_DI_FLOAT fled1; H_DI_FLOAT fled2; INT index; DOUBLE ratio; val1=0; val2=0; fled1.value=(&val1); fled1.low=0; fled1.high=high1; fled2.value=(&val2); fled2.low=0; fled2.high=high2; ratio=fled2.high/fled1.high; FOREVER { if (uOpenDialog("Convert")) return; if (uAddDialogItem(H_DIALOG_FLOAT,pmt1,&fled1)) return; if (uAddDialogItem(H_DIALOG_FLOAT,pmt2,&fled2)) return; index=uRunDialog(); if (index<=0) break; if (index==2) { val2=val1*ratio; Clip(&val2); } else { val1=val2/ratio; Clip(&val1); } } } LOCAL_C VOID InchAndCm(VOID) { Convert("Inches","Centimetres",10000,25400); } LOCAL_C VOID MileAndKm(VOID) { Convert("Miles","Kilometres",20000,32187); } LOCAL_C VOID PoundAndKg(VOID) { Convert("Pounds","Kilograms",31938,14500); } LOCAL_C VOID PintAndL(VOID) { Convert("Pints","Litres",28156,16000); } LOCAL_C VOID ChangeNdp(VOID) { LONG lndp; H_DI_NUMBER num; if (uOpenDialog("Level of significance")) return; lndp=ndp; num.value=(&lndp); num.low=0; num.high=4; if (uAddDialogItem(H_DIALOG_NUMBER,"Decimal places",&num)) return; if (uRunDialog()<=0) return; ndp=(WORD)lndp; CalcSmall(); } LOCAL_C VOID SetUpDiDate(H_DI_DATE *pdate,P_DAYSEC *pds) { ULONG sdate; sdate=p_date(); p_sttods(&sdate,pds); pdate->value=(&pds->day); pdate->low=0; pdate->high=H_LAST_DAY; } LOCAL_C VOID DayOfWeek(VOID) { P_DAYSEC ds; H_DI_DATE date; TEXT buf[40]; H_DI_TEXT txt; SetUpDiDate(&date,&ds); do { p_nmday(&buf[1],p_wkday(ds.day)); buf[0]=p_slen(&buf[1]); txt.str=(&buf[0]); txt.type=H_DTEXT_ALIGN_LEFT; if (uOpenDialog("Find day of week")) return; if (uAddDialogItem(H_DIALOG_DATE,"Date",&date)) return; if (uAddDialogItem(H_DIALOG_TEXT,"Day of week",&txt)) return; } while (uRunDialog()>0); } LOCAL_D TEXT *orient[]= { "Rat","Cow","Tiger","Rabbit","Dragon","Snake", "Horse","Sheep","Monkey","Rooster","Dog","Pig" }; LOCAL_D TEXT *western[]= { "Capricorn","Aquarius","Pisces","Aries","Taurus","Gemini", "Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius" }; LOCAL_C INT Zodiac(P_DATE *pdt) { INT ret; LOCAL_D changeover[12]={19,18,19,19,20,20,22,22,22,22,21,20}; ret=pdt->month; if (pdt->day>changeover[ret]) { if (ret++==11) ret=0; } return(ret); } LOCAL_C VOID Horoscope(VOID) { P_DAYSEC ds; H_DI_DATE date; P_DATE dt; INT key; TEXT buf[40]; SetUpDiDate(&date,&ds); FOREVER { if (uOpenDialog("Horoscope")) return; if (uAddDialogItem(H_DIALOG_DATE,"Date of birth",&date)) return; if (uAddButtonList("Stop",W_KEY_ESCAPE, "Western",'w',"Oriental",'o',NULL)) return; key=uRunDialog(); if (key<=0) return; p_dstodt(&ds,&dt); if (key=='o') p_atos(&buf[0],"Oriental horoscope is %s",orient[dt.year%12]); else p_atos(&buf[0],"Western horoscope is %s",western[Zodiac(&dt)]); wInfoMsg(&buf[0]); } } LOCAL_C INT AddListOfDays(UWORD *pdiw) { H_DI_CHOICE ch; TEXT nam[32]; INT i; if (uBeginDCL(&ch)) return(-1); for (i=0; i<7; i++) { p_nmday(&nam[0],i); if (uGrowDCL(&ch,&nam[0])) return(-1); } return(uAddDCL("Day in week",pdiw,&ch)); } LOCAL_C VOID Combinations(VOID) { P_DAYSEC ds; H_DI_DATE date; P_DATE dt; INT key; UWORD diw; LONG dim; H_DI_NUMBER num; INT diff; ULONG reset; INT inc; SetUpDiDate(&date,&ds); p_dstodt(&ds,&dt); diw=p_wkday(ds.day)+1; dim=dt.day+1; num.value=(&dim); num.low=1; num.high=31; FOREVER { if (uOpenDialog("Find date combinations")) return; if (AddListOfDays(&diw)) return; if (uAddDialogItem(H_DIALOG_NUMBER,"Day in month",&num)) return; if (uAddDialogItem(H_DIALOG_DATE,"Found date",&date)) return; if (uAddButtonList("Stop",W_KEY_ESCAPE,"Backwards",W_KEY_MENU, "Forwards",W_KEY_RETURN,0)) return; key=uRunDialog(); if (key<=0) return; reset=ds.day; diff=diw-p_wkday(ds.day)-1; if (key==W_KEY_RETURN) { if (diff<=0) diff+=7; inc=7; } else { if (diff>=0) diff-=7; inc=(-7); } ds.day+=diff; dim-=1; FOREVER { if (ds.day>H_LAST_DAY) { wInfoMsg("No further matches"); ds.day=reset; break; } p_dstodt(&ds,&dt); if (dt.day==dim) break; ds.day+=inc; } dim+=1; } } LOCAL_C VOID SetUpTime(H_DI_TIME *ptime,P_DAYSEC *pds) { ptime->value=(&pds->sec); ptime->low=0; ptime->high=P_NSECDAY-1; ptime->type=H_DTIME_SHOW_SECONDS; } LOCAL_C VOID TimeDifference(VOID) { P_DAYSEC ds1; H_DI_DATE date1; H_DI_TIME time1; P_DAYSEC ds2; H_DI_DATE date2; H_DI_TIME time2; LONG diff; TEXT buf[40]; SetUpDiDate(&date1,&ds1); SetUpDiDate(&date2,&ds2); SetUpTime(&time1,&ds1); SetUpTime(&time2,&ds2); FOREVER { if (uOpenDialog("Time difference")) return; if (uAddDialogItem(H_DIALOG_DATE,"From",&date1)) return; if (uAddDialogItem(H_DIALOG_TIME,"",&time1)) return; if (uAddDialogItem(H_DIALOG_DATE,"To",&date2)) return; if (uAddDialogItem(H_DIALOG_TIME,"",&time2)) return; if (uRunDialog()<=0) return; diff=ds2.day-ds1.day; if (diff<0 || !diff && ds2.sec0x7fffffffl/P_NSECDAY) { wInfoMsg("Dates are too far apart"); continue; } p_atos(&buf[0],"Dates are %ld seconds apart", diff*P_NSECDAY+ds2.sec-ds1.sec); wInfoMsg(&buf[0]); } } LOCAL_C INT AddNoYesChoiceList(TEXT *pmt,UWORD *pval) { return(uAddChoiceList(pmt,pval,"No","Yes",NULL)); } LOCAL_C VOID TimeNow(VOID) { INT values; H_DI_TEXT txt; TEXT buf[48]; txt.str=(&buf[0]); do { if (uOpenDialog(NULL)) return; uZTStoBCS(&buf[0],"Time is now"); txt.type=H_DTEXT_ALIGN_CENTRE; if (uAddDialogItem(H_DIALOG_TEXT,NULL,&txt)) return; values=0; if (ttMonth==2) values=H_TIME_FORMAT_MONTH_NAME; if (ttDay==2) values|=H_TIME_FORMAT_DAY_NAME; if (ttSuffix==2) values|=H_TIME_FORMAT_SUFFIX; if (ttCentury==1) values|=H_TIME_FORMAT_NO_CENTURY; if (ttSeconds==1) values|=H_TIME_FORMAT_NO_SECONDS; hTTSetFormat(ttH,values); hTTSetTime(ttH,H_TIME_SET_NOW,NULL); buf[0]=hTTSenseString(ttH,H_TIME_SENSE_BOTH,&buf[1]); txt.type=H_DTEXT_ALIGN_CENTRE|H_DTEXT_UNDERLINE; if (uAddDialogItem(H_DIALOG_TEXT,NULL,&txt)) return; if (AddNoYesChoiceList("Give month name",&ttMonth)) return; if (AddNoYesChoiceList("Give day name",&ttDay)) return; if (AddNoYesChoiceList("Use date suffix",&ttSuffix)) return; if (AddNoYesChoiceList("Show century",&ttCentury)) return; if (AddNoYesChoiceList("Show seconds",&ttSeconds)) return; } while (uRunDialog()>0); } LOCAL_C VOID EnterPassword(VOID) { TEXT pass1[10]; TEXT pass2[10]; H_DI_XINPUT x1; H_DI_XINPUT x2; x1.str=(&pass1[0]); x2.str=(&pass2[0]); FOREVER { if (uOpenDialog(NULL)) return; if (uAddDialogItem(H_DIALOG_XINPUT,"Define password",&x1)) return; if (uAddDialogItem(H_DIALOG_XINPUT,"Confirm password",&x2)) return; if (uRunDialog()<=0) return; if (p_bcmpi(&pass1[1],pass1[0],&pass2[1],pass2[0])) { wInfoMsg("Password not confirmed"); continue; } if (pass1[0]) break; wInfoMsg("Please supply password"); } p_bfil(&pass[0],10,0); p_bcpy(&pass[0],&pass1[0],pass1[0]+1); } LOCAL_C VOID MakeReadable(TEXT *out,TEXT *in) { INT len; INT i; INT val; i=32; len=(*in++); *out++=len*2; while (len--) { val=(*in++); *out++=i+(val&0xf); i+=16; *out++=i+(val>>4); if (i==112) i=32; else i+=16; } } LOCAL_C VOID MakeUnreadable(TEXT *out,TEXT *in) { INT len; INT i; INT val; i=32; len=(*in++)/2; *out++=len; while (len--) { val=(*in++)-i; i+=16; val+=((*in++)-i)<<4; *out++=val; if (i==112) i=32; else i+=16; } } LOCAL_C VOID Report(TEXT *title,TEXT *mess) { H_DI_TEXT txt; if (uOpenDialog(title)) return; txt.str=mess; txt.type=H_DTEXT_ALIGN_CENTRE; if (uAddDialogItem(H_DIALOG_TEXT,NULL,&txt)) return; uRunDialog(); } LOCAL_C VOID EncryptMessage(VOID) { P_MASK mask; H_DI_EDIT ed; TEXT in[20]; TEXT out[38]; if (!pass[0]) { wInfoMsg("Can't encrypt with no password set"); return; } p_setmask((VOID **)&mask,&pass[1]); /** bug in prototype **/ if (uOpenDialog("Encrypt message")) return; ed.str=(&in[0]); ed.len=18; in[0]=0; if (uAddDialogItem(H_DIALOG_EDIT,"Message",&ed)) return; if (uRunDialog()<=0) return; p_encrypt(&mask,&in[1],in[0]); MakeReadable(&out[0],&in[0]); Report("Encrypted message",&out[0]); } LOCAL_C VOID DecryptMessage(VOID) { P_MASK mask; H_DI_SEDIT sed; TEXT in[38]; TEXT out[20]; if (!pass[0]) { wInfoMsg("Can't decrypt with no password set"); return; } p_setmask((VOID **)&mask,&pass[1]); if (uOpenDialog("Decrypt message")) return; sed.str=(&in[0]); sed.len=36; sed.width=16; in[0]=0; if (uAddDialogItem(H_DIALOG_SEDIT,"Message",&sed)) return; if (uRunDialog()<=0) return; MakeUnreadable(&out[0],&in[0]); p_decrypt(&mask,&out[1],out[0]); Report("Decrypted message",&out[0]); } LOCAL_C VOID FileSize(VOID) { TEXT fname[P_FNAMESIZE+2]; H_DI_FSEL fsel; P_INFO info; TEXT buf[30]; fname[0]=0; fsel.fname=(&fname[0]); fsel.flags=H_FILE_PICK_SELECTOR; FOREVER { if (uOpenDialog("Find file size")) return; if (uAddDialogItem(H_DIALOG_FSEL,"File:",&fsel)) return; if (uRunDialog()<=0) return; fname[1+fname[0]]=0; if (!uErrorValue(p_finfo(&fname[1],&info))) { p_atos(&buf[0],"File size is %lu bytes",info.size); wInfoMsg(&buf[0]); } } } LOCAL_C VOID ManageCommand(INT index) { switch (index) { case ITEMS_BEFORE_CONVERT: InchAndCm(); break; case ITEMS_BEFORE_CONVERT+1: MileAndKm(); break; case ITEMS_BEFORE_CONVERT+2: PoundAndKg(); break; case ITEMS_BEFORE_CONVERT+3: PintAndL(); break; case ITEMS_BEFORE_CONVERT+4: Temperatures(); break; case ITEMS_BEFORE_CALENDAR: DayOfWeek(); break; case ITEMS_BEFORE_CALENDAR+1: Combinations(); break; case ITEMS_BEFORE_CALENDAR+2: TimeDifference(); break; case ITEMS_BEFORE_CALENDAR+3: Horoscope(); break; case ITEMS_BEFORE_CALENDAR+4: TimeNow(); break; case ITEMS_BEFORE_SECRET: EnterPassword(); break; case ITEMS_BEFORE_SECRET+1: EncryptMessage(); break; case ITEMS_BEFORE_SECRET+2: DecryptMessage(); break; case ITEMS_BEFORE_SPECIAL: ChangeNdp(); break; case ITEMS_BEFORE_SPECIAL+1: FileSize(); break; case ITEMS_BEFORE_SPECIAL+2: p_exit(0); } } LOCAL_C VOID TryExecuteCommand(INT keycode) { keycode=uLocateCommand(keycode); if (keycode>=0) ManageCommand(keycode); } LOCAL_C VOID MainLoop(VOID) { INT ret; WMSG_KEY key; FOREVER { uGetKey(&key); if (key.keycode&W_EVENT_KEY) { if (key.keycode==CONS_EVENT_COMMAND) p_exit(0); } else if (key.keycode&W_SPECIAL_KEY) TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY)); else if (key.keycode==W_KEY_MENU && !(key.modifiers&W_CTRL_MODIFIER)) { ret=uPresentMenus(); if (ret>0) TryExecuteCommand(ret); } } } LOCAL_C VOID ReduceScreenSize(VOID) { W_WINDATA wd; wd.extent.tl.x=wd.extent.tl.y=0; wd.extent.width=189; wd.extent.height=80; wSetWindow(MainWid,W_WIN_EXTENT,&wd); if (uErrorValue(wCheckPoint())) p_exit(0); } LOCAL_C VOID CreateGC(VOID) { INT hgc; hgc=gCreateGC0(MainWid); if (hgc<0) p_exit(hgc); } LOCAL_C VOID SpecificInit(VOID) { hCrackCommandLine(); MainWid=uFindMainWid(); ReduceScreenSize(); CreateGC(); gBorder(W_BORD_CORNER_4); wsEnable(); CalcSmall(); ttH=hTTOpen(); } GLDEF_C VOID main(VOID) { uCommonInit(); SpecificInit(); MainLoop(); }