home *** CD-ROM | disk | FTP | other *** search
- /* key processor for Ed
- Copyright C.T.Stretch 1990
- Thu,21 Jun 1990
- */
-
- #include "Edhdr.h"
- #include "wkey.h"
- #include <ctype.h>
-
- #define MF CKMOD(CD);break
- #define MFL if(cline->col<NCOL||CF) CKMOD(CD);break
- #define NOCARET (1<<25);
- #define HEX(k) (k-(k>'9'?(k>'Z'?('a'-10):('A'-10)):'0'))
-
- static int hexch[]={ '\\','x','0','0',0 };
-
- void keys_checkcp()
- { wimp_wstate state;
- wimp_openstr *o=&state.o;
- wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
- if(clinen<cwind->over+(OFFSET-o->y+LINEHT-1)/LINEHT)
- { o->y=OFFSET+LINEHT*(cwind->over-clinen);
- wimpt_noerr(wimp_open_wind(o));
- }
- else
- if(clinen>cwind->over+(OFFSET-o->y+o->box.y1-o->box.y0-LINEHT+1)/LINEHT)
- { o->y=OFFSET+LINEHT*(cwind->over-clinen-1)+o->box.y1-o->box.y0;
- wimpt_noerr(wimp_open_wind(o));
- }
- if(cpos<((o->x+CHWIDTH-1)/CHWIDTH))
- { o->x=CHWIDTH*cpos;
- wimpt_noerr(wimp_open_wind(o));
- }
- else
- if(cpos>((o->x+o->box.x1-o->box.x0-CHWIDTH+1)/CHWIDTH))
- { o->x=CHWIDTH*(cpos+1)+o->box.x0-o->box.x1;
- wimpt_noerr(wimp_open_wind(o));
- }
- }
-
- static void indent(line *l)
- { int n=0,m,s=0;
- line *pl=l->prev;
- char *t=l->text,*p=pl->text;
- while(l->len>0&&t[l->len-1]==' ') l->len--;
- if(pl&&!pl->fold&&l->col<NCOL)
- { for(;(n<pl->len)&&(p[n]==' ');n++);
- if(n>=pl->len) n=0;
- for(m=n;m<pl->len;m++)
- { if(p[m]=='{') { n+=2;s++;}
- if(p[m]=='}'&&s>0) { n-=2;s--;}
- if(m<pl->len-1&&!strncmp(p+m,"/*",2))
- { m=find_skipcomm(pl,m+2);continue;}
- if(p[m]=='\'') { m=find_skipchar(pl,m+1);continue;}
- if(p[m]=='\"') { m=find_skipstr(pl,m+1);continue;}
- }
- if(n<0) n=0;
- }
- if(l==cline) cpos=n;
- if(!l->len) return;
- for(m=0;(m<l->len)&&(t[m]==' ');m++);
- if(t[m]=='}'&&n>=2) n-=2;
- if(l->len+n-m>MAXC)
- { n=MAXC-l->len+m;
- BEEP;
- }
- if(m==n) return;
- memmove(t+n,t+m,l->len-m);
- if(n>m) memset(t+m,' ',n-m);
- l->len+=(n-m);
- }
-
- static void nl(BOOL split)
- { wimp_wstate state;
- wimp_openstr *o=&state.o;
- int n=CL-cpos;
- wind *w;
- wimp_box sou[1];
- wimp_caretstr cs[1];
- if(!mem_getline(cline)) return;
- CD->len+=1;
- if(n>0&&split)
- { memcpy(CN->text,CT+cpos,n);
- memset(CT+cpos,' ',n);
- CL=cpos;CN->len=n;
- }
- cline=CN;clinen++;cpos=0;
- if(split&&CP->col>=NCOL) cline->col=NCOL;
- indent(cline);
- wimpt_noerr(wimp_get_caret_pos(cs));
- cs->height=NOCARET;
- wimpt_noerr(wimp_set_caret_pos(cs));
- w=CD->list;
- while(w)
- { wimpt_noerr(wimp_get_wind_state(w->hand,&state));
- if(clinen<=w->over+(OFFSET-o->y)/LINEHT)
- { w->over+=1;
- disp_sete(w);
- }
- else
- { disp_sete(w);
- if(clinen<=w->over+(OFFSET-o->y+o->box.y1-o->box.y0)/LINEHT)
- { sou->x0=0;sou->y0=LBASE(CD->len-1);
- sou->x1=WWIDTH;sou->y1=LBASE(clinen)+4;
- wimpt_noerr(wimp_blockcopy(w->hand,sou,0,LBASE(CD->len)));
- disp_update(0,MAXC);
- if(split) disp_updatel(CP);
- }
- }
- w=w->next;
- }
- cs->height=CARHT;
- wimpt_noerr(wimp_set_caret_pos(cs));
- }
-
- static void tidy(void)
- { line *l;
- for(l=cline;l&&!l->fold&&l->len;l=l->next) indent(l);
- disp_fred(CD);
- }
-
- static void del()
- { if(cpos<=0) return;
- if(cpos>CL) {cpos--;return;}
- if(cpos==CL){CT[--cpos]=32;disp_update(cpos,CL--);return;}
- memcpy(CT+cpos-1,CT+cpos,CL-cpos);
- disp_update(--cpos,CL--);
- CT[CL]=32;
- }
-
- static void dline()
- { wimp_wstate state;
- wimp_openstr *o=&state.o;
- wimp_box sou[1];
- wimp_caretstr cs[1];
- wind *w;
- line **l;
- int nextln=clinen+1;
- if(CF) for(l=&(CF);*l;mem_unlink(l)) if(*l==MARK) MARK=0;
- if(!CN&&!CP) { mem_clear(cline);cpos=0;disp_update(0,MAXC);return;}
- if(MARK==cline) MARK=0;
- CD->len-=1;
- if(CP)
- { cline=CP;clinen--;cpos=CL;mem_unlink(cline);
- }
- else
- { cline=CN;cpos=0;mem_unlink(&(CD->line));
- }
- wimpt_noerr(wimp_get_caret_pos(cs));
- cs->height=NOCARET;
- wimpt_noerr(wimp_set_caret_pos(cs));
- w=CD->list;
- while(w)
- { disp_sete(w);
- wimpt_noerr(wimp_get_wind_state(w->hand,&state));
- if(clinen>=w->over+(OFFSET-o->y)/LINEHT-1
- && clinen<=w->over+(OFFSET-o->y+o->box.y1-o->box.y0)/LINEHT)
- { sou->x0=0;sou->y0=LBASE(CD->len+2);
- sou->x1=WWIDTH;sou->y1=LBASE(nextln)+4;
- wimpt_noerr(wimp_blockcopy(w->hand,sou,0,LBASE(CD->len+1)));
- }
- w=w->next;
- }
- cs->height=CARHT;
- wimpt_noerr(wimp_set_caret_pos(cs));
- }
-
- static void clearleft()
- { int n=CL;
- if(!cpos) return;
- if(cpos>n) cpos=n;
- if(n>cpos) memmove(CT,CT+cpos,n-cpos);
- memset(CT+n-cpos,' ',cpos);
- CL-=cpos;
- disp_update(0,n);
- cpos=0;
- }
-
- static void clearright()
- { int n=CL;
- if(cpos>=n) return;
- memset(CT+cpos,' ',n-cpos);
- CL=cpos;
- disp_update(cpos,n);
- }
-
- static void up() {if(CP) {cline=CP;clinen--;} }
-
- static void down()
- { if(!CN) if(!mem_getline(cline)) return;
- cline=CN;clinen++;
- }
-
- static void left()
- { if(cpos>0) cpos--;
- else if(CP)
- { cline=CP;clinen--;cpos=CL;
- }
- }
-
- static void right() { if(cpos<MAXC) cpos++;}
-
- static void upgo()
- { wimp_wstate state;
- wimp_openstr *o=&state.o;
- cline=CD->line;
- clinen=0;
- wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
- o->x=0;o->y=(cwind->over)*LINEHT;
- cpos=0;
- wimpt_noerr(wimp_open_wind(o));
- }
-
- static void downgo()
- { int x;
- wimp_wstate state;
- wimp_openstr *o=&state.o;
- wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
- o->y=(cwind->over-CD->len-2)*LINEHT+o->box.y1-o->box.y0;
- cline=CD->line;clinen=0;
- while(CN) {cline=CN;clinen++;}
- cpos=CL;
- x=cpos*16-(o->box.x1-o->box.x0);
- o->x=(x<0)?0:x;
- wimpt_noerr(wimp_open_wind(o));
- }
-
- static void pgmove(int d)
- { wimp_wstate state;
- wimp_openstr *o=&state.o;
- wimpt_noerr(wimp_get_wind_state(cwind->hand,&state));
- o->y+=d*(o->box.y1-o->box.y0);
- clinen=cwind->over+1+(OFFSET-o->y)/LINEHT;
- if(clinen>=CD->len) clinen=CD->len-1;
- cline=disp_find(clinen,CD);
- wimpt_noerr(wimp_open_wind(o));
- }
-
- static void join(void)
- { int n;
- if(!CP||CF||CP->fold) return;
- cpos=CP->len;
- for(n=0;n<CL&&CT[n]==' ';n++);
- if(CL+CP->len-n>MAXC) return;
- memcpy(CP->text+CP->len,CT+n,CL-n);
- CP->len+=CL-n;
- mem_unlink(CP);
- cline=CP;clinen--;
- disp_fred(CD);
- }
-
- void keys_add(int k)
- { char *t=CT;
- int l=CL;
- if(!cline || cpos>=MAXC || l>=MAXC) { BEEP;return;}
- if(cpos<l) memmove(t+cpos+1,t+cpos,l-cpos);
- if(cpos>l) CL=cpos;
- CT[cpos++]=(char)k;
- CL++;
- disp_update(cpos-1,CL);
- disp_setcaret();
- if(cline->col<NCOL) CKMOD(CD);
- }
-
- static void insfkey(int n)
- { char v[10],s[MAXC],*w;
- sprintf(v,"Key$%d",n);
- os_read_var_val(v,s,MAXC);
- for(w=s;*w;w++) keys_add(*w);
- }
-
- static BOOL insedx(int n)
- { char v[10];
- char s[257];
- char *m;
- int a,b,c;
- sprintf(v,"Ed$%c",(char)n);
- os_read_var_val(v,s,256);
- if(!*s) return FALSE;
- for(m=s;*m;m++)
- { if(*m=='&')
- { a=m[1];
- if(a=='&') { keys_add('&');m++;continue;}
- b=m[2];
- c=m[3];
- if(!(isxdigit(a)&&isxdigit(b)&&isxdigit(c)))
- { werr(0,"Bad Ed$%c char %d",(char)n,m-s);
- return TRUE;
- }
- keys_key((HEX(a)<<8)+(HEX(b)<<4)+HEX(c));
- m+=3;
- }
- else keys_key(*m);
- }
- return TRUE;
- }
-
- static void setfkey(int n)
- { char v[MAXC+12];
- sprintf(v,"Set Key$%d %*.*s",n,CL,CL,CT);
- system(v);
- }
-
- static void topset(int n)
- { int *m;
- hexch[2]='0'+(n>>4);
- if(hexch[2]>'9') hexch[2]+='A'-'9'-1;
- hexch[3]='0'+(n&0xF);
- if(hexch[3]>'9') hexch[3]+='A'-'9'-1;
- for(m=hexch;*m;m++) keys_add(*m);
- }
-
- static void other(int k)
- { if(k>=wkey_CF(1)&&k<=wkey_CF(9)) { insfkey(k-wkey_CF(0));return;}
- if(k>=wkey_CSF(1)&&k<=wkey_CSF(9)) { setfkey(k-wkey_CSF(0));return;}
- if(k>=128&&k<=255) { topset(k);return;}
- if(k>=wkey_C('A')&&k<=wkey_C('_')) if(insedx(k+'A'-wkey_C('A'))) return;
- wimp_processkey(k);
- }
-
- #ifdef SHOWBUG
- static void showbug(void)
- { werr(0,"emptyn %d empty %p ",emptyn,empty);
- werr(0,"cwind %p cline %p cdoc %p cdoc->wind %p",cwind,cline,CD,CD->list);
- }
- #endif
-
- static void keyop(int k)
- { switch(k)
- {
- #ifdef SHOWBUG
- case wkey_C('Q'):showbug();break;
- #endif
- case wkey_DEL: del();MFL;
- case wkey_INS: nl(FALSE);MFL;
- case wkey_RIGHT: right();break;
- case wkey_DOWN: down();break;
- case wkey_LEFT: left();break;
- case wkey_UP: up();break;
- case wkey_CLEFT: cpos=0;break;
- case wkey_CRIGHT:cpos=CL;break;
- case wkey_CDOWN: downgo();break;
- case wkey_CUP: upgo();break;
- case wkey_SDOWN: pgmove(-1);break;
- case wkey_SUP: pgmove(1);break;
- case wkey_F(0): file_savedoc("printer:",CD);break;
- case wkey_SF(0): if(CD->mark) file_saveline("printer:",CD->mark);break;
- case wkey_F(1): fold_mark();break;
- case wkey_SF(1): fold_unmark();break;
- case wkey_F(2): fold_gomark();break;
- case wkey_SF(2): fold_note();MFL;
- case wkey_F(3): nl(FALSE);cline->col=NCOL;break;
- case wkey_SF(3): fold_unnote();MF;
- case wkey_F(4): fold_gonote();break;
- case wkey_SF(4): fold_comnote();MF;
- case wkey_F(5): fold_copy();MFL;
- case wkey_SF(5): fold_movel();MFL;
- case wkey_F(6): clearleft();MFL;
- case wkey_SF(6): clearright();MFL;
- case wkey_F(7): nl(TRUE);MFL;
- case wkey_SF(7): join();MF;
- case wkey_F(8): dline();MFL;
- case wkey_SF(8): tidy();MF;
- case wkey_F(9): fold_fold();break;
- case wkey_SF(9): fold_unfoldall();break;
- case wkey_F(10): fold_unfold1();break;
- case wkey_SF(10):fold_fold1();break;
- case wkey_F(11): fold_foldmark();break;
- case wkey_SF(11):file_runline(FALSE);break;
- case wkey_SF(12):file_runline(TRUE);break;
- default:other(k);
- }
- while(CL>0&&CT[CL-1]==' ') CL--;
- keys_checkcp();
- disp_setcaret();
- }
-
- void keys_key(int k)
- { if(k>31 && k<127) keys_add(k);
- else keyop(k);
- }
-