home *** CD-ROM | disk | FTP | other *** search
- /* Alain Birtz, 16/2/86 */
- #include "gemdefs.h"
-
- /************************************************************************/
-
- #define WI_KIND (MOVER|CLOSER|NAME) /* can be moved, closed */
- /* and title exist */
- #define NO_WINDOW (-1)
-
- #define Getrez() (int)xbios(4) /* return resolution */
-
- /************************************************************************/
-
- extern int gl_apid;
- extern long xbios();
-
- /************************************************************************/
-
- int rez; /* resolution number */
- int ux,uy; /* unit in pixels */
- int box[28][4]; /* key */
- int blank; /* screen state */
- int dot; /* dot in float. point */
- int oper; /* current operation */
- int kb_conv[3][12]={
- {0x31,0x32,0x33,0x7f,0x34,0x35,0x36,0x2b,0x37,0x38,0x39,0x2d},
- {0x30,0x21,0xff,0x2a,0x2e,0x62,0x6f,0x2f,0x25,0x26,0x7c,0x3d},
- {0x61,0x62,0x63,0x2a,0x64,0x65,0x66,0x2f,0x30,0x26,0x7c,0x3d}
- };
-
- int menu_id ; /* our menu id */
- int phys_handle; /* physical workstation */
- int handle; /* virtual workstation */
- int wi_handle; /* window handle */
- int top_window; /* handle of topped */
-
- int x_init,y_init,w_init,h_init;
- int xwork,ywork,hwork,wwork; /* initial, work areas */
-
- int msgbuff[8]; /* event message buffer */
- int mx,my; /* mouse x and y pos. */
- int kb_code; /* keyboard return */
- int butdown; /* button state */
- int d; /* dummy variable */
-
- int contrl[12]; /* AES, VDI variable */
- int intin[128];
- int ptsin[128];
- int intout[128];
- int ptsout[128];
-
- int work_in[11]; /* Input GSX parameter */
- int work_out[57]; /* Output GSX parameter */
-
- long base; /* 10=DECI, 16=HEXA */
- long temp_base; /* used in octal,binary */
- long mem_val, scr_val; /* arithmetic value */
- long mem_div=1L, scr_div=1L; /* used in float. point */
-
- char key_symb[3][12]={
- {'1','2','3','\275','4','5','6','+','7','8','9','-'},
- {'0','!','\361','*','.','b','o','/','%','&','|','='},
- {'A','B','C','*','D','E','F','/','0','&','|','='}
- };
- char hex_deci[][5]={"HEXA","DECI"};
- char chr[]=" "; /* to print one char */
-
-
- /************************************************************************/
-
- set_unit() /* according to rez. */
- {
- rez=Getrez();
- ux=10;
- uy=(rez==2 ? 10:5);
- }
-
- /************************************************************************/
-
- author()
- {
- long time;
-
- v_gtext(handle,box[26][0]+ux/2,box[26][3]-uy/2," by A.Birtz");
- time=150000L;
- while(time--)
- ; /* timeout */
- reset_v();
- base=10L; /* initialisation */
- temp_base=10L;
- oper=3;
- display(); /* clear author! */
- }
-
- /************************************************************************/
-
- one_key(no,style) /* draw one key */
- int no, style;
- {
- char *s;
-
- if (no<24)
- {
- chr[0]=key_symb[(no<12 ? 0:1+(base==16L))][no%12];
- s=chr;
- }
- else
- s=hex_deci[no-24];
-
- graf_mouse(256,0); /* hide mouse */
- fill(box[no],style,0); /* clear and fill */
- vswr_mode(handle,(style) ? 3:1); /* reverse if style=1 */
- /* print text */
- v_gtext(handle,box[no][0]+7*ux/10+2*(no>23),box[no][3]-4*uy/10,s);
- vswr_mode(handle,1); /* normal printing */
- graf_mouse(257,0); /* show mouse */
- }
-
- /************************************************************************/
-
- open_vwork() /* open workstation */
- {
- int i;
- for(i=0;i<10;work_in[i++]=1);
- work_in[10]=2;
- handle=phys_handle;
- v_opnvwk(work_in,&handle,work_out);
- }
-
- /************************************************************************/
-
- open_window() /* open window */
- {
- wi_handle=wind_create(WI_KIND,x_init,y_init,w_init,h_init);
- wind_set(wi_handle, WF_NAME," Calculator ",0,0);
- wind_open(wi_handle,x_init,y_init,w_init,h_init);
- wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
- }
-
- /************************************************************************/
-
- main()
- {
- appl_init();
- phys_handle=graf_handle(&d,&d,&d,&d);
- menu_id=menu_register(gl_apid," Calculator");
-
- set_unit();
-
- x_init=5*ux;
- y_init=5*uy;
- w_init=15*ux;
- h_init=31*uy;
-
- wi_handle=NO_WINDOW;
- butdown=1;
-
- multi();
- }
-
- /************************************************************************/
-
- multi()
- {
- int event, k;
-
- while (1)
- {
- event = evnt_multi(MU_MESAG | MU_BUTTON | MU_KEYBD,
- 1,1,butdown,0,0,0,0,0,0,0,0,0,0,
- msgbuff,0,0,&mx,&my,&d,&d,&kb_code,&d);
-
- wind_update(1);
- wind_get(wi_handle,WF_TOP,&top_window,&d,&d,&d);
-
- if (event & MU_MESAG)
-
- /*..................................................begin switch........*/
- switch (msgbuff[0])
- {
- case WM_NEWTOP:case WM_TOPPED:
- if (msgbuff[3] == wi_handle)
- {
- wind_set(wi_handle,WF_TOP,0,0,0,0);
- draw();
- }
- break;
-
- case AC_CLOSE:
- if ((msgbuff[3] == menu_id)&&(wi_handle != NO_WINDOW))
- {
- v_clsvwk(handle);
- wi_handle = NO_WINDOW;
- }
- break;
-
- case WM_CLOSED:
- if (msgbuff[3] == wi_handle)
- {
- wind_close(wi_handle);
- wind_delete(wi_handle);
- v_clsvwk(handle);
- wi_handle = NO_WINDOW;
- graf_mouse(0,0); /* arrow form */
- }
- break;
-
- case WM_MOVED:
- if (msgbuff[3] == wi_handle)
- {
- wind_set(wi_handle,WF_CURRXYWH,msgbuff[4],
- msgbuff[5],msgbuff[6],msgbuff[7]);
- wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
- draw();
- }
- break;
-
- case AC_OPEN:
- if (msgbuff[4] == menu_id && wi_handle == NO_WINDOW)
- {
- open_vwork();
- open_window();
- draw();
- author();
- }
- break;
-
- }
- /*....................................................end switch........*/
-
- if ((event & MU_BUTTON)&&(wi_handle == top_window))
- if (butdown)
- {
- if ((k=key_numb())>-1)
- math(k);
- butdown=0;
- }
- else
- butdown=1;
-
- if (event & MU_KEYBD)
- {
- if ((k=kb_ret())>-1)
- math(k);
- }
-
- wind_update(0);
-
- } /* end of while (1) */
-
- }
-
- /***********************************************************************/
-
- reset_v()
- {
- blank=1;
- dot=0;
- scr_val=mem_val=0L;
- scr_div=mem_div=1L;
- }
-
- /***********************************************************************/
-
- plus()
- {
- long max_div;
-
- if (scr_div>1L || mem_div>1L)
- {
- max_div=(scr_div>mem_div ? scr_div:mem_div);
- scr_val=max_div/mem_div*mem_val + max_div/scr_div*scr_val;
- scr_div=max_div;
- }
- else
- scr_val += mem_val;
- }
-
- /***********************************************************************/
-
- minus()
- {
- long max_div;
-
- if (scr_div>1L || mem_div>1L)
- {
- max_div=(scr_div>mem_div ? scr_div:mem_div);
- scr_val=max_div/mem_div*mem_val - max_div/scr_div*scr_val;
- scr_div=max_div;
- }
- else
- scr_val=mem_val-scr_val;
- }
-
- /***********************************************************************/
-
- product()
- {
- scr_val *= mem_val;
- scr_div *= mem_div;
- while (scr_div>100L)
- {
- scr_val /= 10L;
- scr_div /= 10L;
- }
- }
-
- /***********************************************************************/
-
- quotient()
- {
- long work;
-
- if (!scr_div) /* division by zero */
- return;
-
- if (scr_div>1L || mem_div>1L)
- {
- work=100L; /* ???? */
- scr_val=work/mem_div*mem_val*scr_div/scr_val;
- scr_div=100L;
- }
- else
- scr_val=mem_val/scr_val;
- }
-
- /************************************************************************/
-
- math(k)
- int k;
- {
- int i;
- long fact;
-
- if (k>-1 && k<24) /* hit key signal */
- {
- one_key(k,1); /* dark key */
- for(i=0;i<20000;i++)
- ; /* time out */
- one_key(k,0); /* white key end signal */
- }
-
- blank=0;
-
- if (k!=-1 && k<21 && k%4!=3) /* digit (DECI or HEXA) */
- if (base==16L || (k<13 && (!dot || scr_div<100L)))
- {
- scr_val *= base;
- scr_val += (long) ((3*(k/4) + k%4 + 1)%(base==10L ? 10:16));
- if (dot)
- scr_div *= 10L;
- }
-
- switch(k)
- {
- case 3:reset_v();break; /* clear */ case 7:case 11:case 15:case 19:case 21:case 22:
- /* + - * / & | */
- mem_div=scr_div;scr_div=1L;
- mem_val=scr_val;scr_val=0L;
- oper=k;blank=1;dot=0;break;
- case 13: /* factorial */
- if (base==10L && scr_val>-1L && scr_val<16L)
- {
- i=1; fact=1L;
- while (i< (int) scr_val)
- fact *= (long) ++i;
- scr_val=fact;
- }
- break;
- case 14:if (base==10L) /* sign change */
- scr_val= -scr_val;
- break;
- case 16:if (base==10L) /* set float point dot */
- dot=1;
- break;
- case 17:case 18: /* binary and octal */
- if (!dot && base==10L)
- {
- temp_base=(k==17 ? 2L:8L);
- if (k==17) /* first 8 bits only */
- scr_val &= 0xff;
- }
- break;
- case 20:if (base==10L) /* per cent (%) */
- {
- while (mem_div<100L)
- {
- mem_div *= 10L; /* convert in float. */
- mem_val *= 10L;
- }
- product();scr_val /= 100L;
- }
- break;
- case 23:switch(oper) /* equal (=) */
- {
- case 7:plus();break;
- case 11:minus();break;
- case 15:product();break;
- case 19:quotient();break;
- case 21:if (!dot) /* 'and' operator */
- scr_val &= mem_val;
- break;
- case 22: /* 'or' operator */
- if (!dot)
- scr_val |= mem_val;
- break;
- default:break;
- }
- break;
- case 24:case 25: /* HEXA or DECI */
- base=(k==24 ? 16L:10L);
- one_key(24,(k==24));one_key(25,(k==25));
- for(i=12;i<21;i++)
- if (i%4!=3) /* draw new key */
- one_key(i,0);
- if (dot)
- reset_v();
- if (mem_div>1L)
- {
- mem_val=0L;
- mem_div=1L;
- }
- break;
- default:
- break;
- }
-
- display();
- }
-
- /************************************************************************/
-
- fill(rect,style,index)
- int rect[], style, index;
- {
- vsf_interior(handle,style); /* fill inside the rect. */
- vsf_style(handle,index); /* with index and style param. */
- v_bar(handle,rect);
- }
-
- /************************************************************************/
-
- draw() /* box[][0] is left upper x */
- { /* box[][1] is left upper y */
- int i, j; /* box[][2] is right lower x */
- char chr[2]; /* box[][3] is right lower y */
-
- for(j=0;j<6;j++) /* 6 key row */
- for(i=0;i<4;i++) /* 4 column */
- {
- box[i+4*j][0]=xwork+(2+3*i)*ux;
- box[i+4*j][2]=box[i+4*j][0]+2*ux;
- box[i+4*j][1]=ywork+(10+3*j)*uy;
- box[i+4*j][3]=box[i+4*j][1]+2*uy;
- }
- for(i=0;i<2;i++) /* HEXA and DECI box */
- {
- box[i+24][0]=xwork+(2+6*i)*ux;
- box[i+24][2]=box[i+24][0]+5*ux;
- box[i+24][1]=ywork+7*uy;
- box[i+4*j][3]=box[i+24][1]+2*uy;
- }
-
- box[26][0]=xwork+2*ux; /* show box */
- box[26][2]=xwork+13*ux;
- box[26][1]=ywork+2*uy;
- box[26][3]=ywork+5*uy;
-
- box[27][0]=xwork; /* calculator box */
- box[27][1]=ywork;
- box[27][2]=xwork+wwork;
- box[27][3]=ywork+hwork;
-
- graf_mouse(256,0); /* hide mouse */
-
- fill(box[27],2,(rez==2) ? 6:5); /* draw frame, grey */
-
- for(i=0;i<25;i++) /* draw key box */
- one_key(i,0); /* with white fill */
- one_key(25,1); /* DECI active */
-
- fill(box[26],0,0); /* draw show box */
- for(i=0;i<4;i++) /* reduce size */
- box[26][i] += 3*(1-2*(i>1));
- fill(box[26],0,0); /* interior box */
-
- graf_mouse(3,0); /* extented finger */
- graf_mouse(257,0); /* show mouse */
- }
-
- /************************************************************************/
-
- key_numb() /* return the clicked key number or -1 if outside */
- {
- int i;
-
- for(i=0;i<26;i++)
- if (mx>box[i][0] && mx<box[i][2]
- && my>box[i][1] && my<box[i][3])
- return(i);
-
- return(-1);
- }
-
- /************************************************************************/
-
- kb_ret() /* convert keyboard code to the key calculator */
- { /* code, or return -1 if no valid key */
- int i, b;
-
- kb_code &= 0xff;
-
- for(i=0;i<12;i++)
- if (kb_conv[0][i]==kb_code)
- return(i);
-
- b=((base==10L) ? 1:2);
-
- for(i=0;i<12;i++)
- if (kb_conv[b][i]==kb_code)
- return(i+12);
-
- return(-1);
- }
-
- /************************************************************************/
-
- display()
- {
- int neg, s_index, l_div, i;
- long same, value, work_base, r;
- char s[12];
-
- for(i=0;i<12;i++) /* white space */
- s[i]=' ';
- s[i]='\0';
-
- if (blank) /* nothing to print */
- {
- v_gtext(handle,box[26][0]+ux/2,box[26][3]-uy/2,s);
- return;
- }
-
- neg=0;
- s_index=11;
- same=value=scr_val;
- l_div= (scr_div>1L)+(scr_div>10L);
-
- work_base=(!temp_base ? base:temp_base);
-
- if (value==0L) /* if zero */
- {
- if (l_div)
- {
- for(i=0;i<l_div;i++)
- s[s_index--]='0';
- s[s_index--]='.';
- }
- else
- if (dot)
- s[s_index--]='.';
- else
- s[s_index--]='0';
- }
-
- if (value<0L) /* if negative */
- {
- same = value = -value; /* make positive */
- neg=1; /* set neg flag */
- }
-
- while (value>0L)
- {
- if ((dot || scr_div>1L) && s_index==11-l_div)
- s[s_index--]='.';
- r = value; /* % don't work */
- value /= work_base; /* with long integer */
- r -= work_base*value; /* on DRI C */
- s[s_index--]= (base==16L && r>9L ? 'A'-10:'0') + (int) r;
- }
-
- if (same && scr_div>same)
- { /* header . and 0 */
- i=l_div+s_index-11;
- while(i--)
- s[s_index--]='0';
- s[s_index--]='.';
- }
-
- temp_base=0L;
-
- if (neg==1) /* negative need sign - */
- s[s_index]='-';
-
- v_gtext(handle,box[26][0]+ux/2,box[26][3]-uy/2,s);
- }
-