/* * The machine specific stuff for edwin device driver * Douglas 4/3/86 */ #include #include #include #include #include #include /* * Some external routine specs */ extern Raster *NewPhysRaster(); extern Raster *NewRaster(); extern RFont *ReadFontFile(); extern Window *BasicRawWinCreate(); extern Window *WinCreate(); extern char *getenv(); /* * Declarations for window stuff */ static Window *CWin; static Raster *Page; static int Pan; /* Physical panel pointer */ static RSize CSize; /* Size of window */ RFont *CurFont; static WinX = 1023; static WinY = 767; static RBox refbox = {{0,0},{1024,768}}; static FillMode = 0; static CCol = 1; /* * These are the initialisation routine for edwin, they open physical windows, * set up fonts and icons for the windows, and make the windows visible */ static initialised = 0; extern int IMP_ARGC; extern char **IMP_ARGV; #define patternfile "patterns" #define NICONS 40 Icon Patterns[NICONS]; EDWIN_DD_INIT(MaxX,MaxY) int *MaxX, *MaxY; { char *Font; char *icon; char *title; static RSize ISize = {64, 64}; RSize Size; int i; int Ch; RPos Br; RSize PSize; *MaxX = WinX; *MaxY = WinY; if (initialised == 2) { /* EDWIN_DD_TERM called, so in stowed status */ resetscreen(); return; } else if (initialised == 1) { /* already active - so do nothing */ return; } else { /* Really initialising the package */ initialised = 1; } /* * First set up the icon file */ title = IMP_ARGV[0]; icon = "ICON"; icon = getenv(icon); CSize.w = WinX + 1; CSize.h = WinY + 1; Br.x = Br.y = 0; /* if (icon == NULL) { if (BasicInit(&Br,&CSize,0,0,0,0,0) < 0) Fail("BasicInit"); } else { if (BasicInit(&Br,&CSize,0,&ISize,0,0,icon) < 0) Fail("BasicInit"); } if (BasicParse(&IMP_ARGC,&IMP_ARGV) < 0) Fail("BasicParse"); */ /* Create a new physical raster */ if ((Page = NewPhysRaster(CSize.w,CSize.h)) == NULL) Fail("NewPhysRaster"); /* if ((CWin = BasicRawWinCreate(CSize,W_PHYS_TYPE)) == NULL) Fail("BasicRawWinCreate"); */ CWin = WinCreate(&Br,&CSize,&CSize,NULL,NULL,0,NULL,title,NULL,W_PHYS_TYPE); if (CWin == NULL) Fail("WinCreate"); Pan = WinGetPanel(CWin); if (Pan < PAN_ROOT) Fail("WinGetPanel"); if ((PageDefine(Pan,0,Page,NULL,NULL)) == -1) Fail("PageDefine"); PanelGetRank(Pan,&i); PanelPop(Pan); PanelGetSize(Pan,&PSize); *MaxX = WinX = PSize.w - 1; *MaxY = WinY = PSize.h - 1; Font = getenv("LATTICE_FONT"); if (Font == NULL) Font = "elite"; CurFont = ReadFontFile(Font); if (CurFont == NULL) Fail("Failed ReadFontFile"); /* initialise events */ eventinit(); WinDisplay(CWin); PageSelect(Pan,0); /* set up icon patterns for the different fill styles */ i = ReadIconFile(patternfile,Patterns,NICONS); if (i <= 0) Fail("ReadIconFile"); } EDWIN_DD_TERM() { initialised = 2; WinStow(CWin); } EDWIN_DD_UPDATE() { PanelUpdate(Pan,refbox,1); } EDWIN_DD_CLEAR() { RasterOp(F_0,0,0,0,Page,0,&CSize); } /* Background patterns to be used with shading */ static FillMap[] = {0,1,34,22,26,33,27,19,30,5,18}; static int Omode = 0; EDWIN_DD_COL(Col) int Col; { PanelUpdate(Pan,refbox,1); CCol = Col; EDWIN_DD_MODE(Omode); } static int Rop = F_S; /* current raster operation */ static OpMap[] = {F_S, F_AND, F_1, F_XOR, F_NOTD}; EDWIN_DD_MODE(Mode) int Mode; { if (Mode == 0) { if (CCol == 0) Rop = F_0; else Rop = F_1; } else { if (Mode <= 4) Rop = OpMap[Mode]; } Omode = Mode; } EDWIN_DD_FILL(Mode) int Mode; { if (Mode >= 80) Mode = 1; if (Mode == 40) Mode = 1; if (Mode > 40) { Mode = Mode - 40; } else { if (Mode <= 10) Mode = FillMap [Mode]; } FillMode = Mode; } EDWIN_DD_DOT(x,y) int x,y; { RPos Br; Br.x = x; Br.y = WinY - y; GPlot(Rop,&Br,Page); } EDWIN_DD_LINE(ox,oy,nx,ny) int ox,oy,nx,ny; { RPos Br,To; Br.x = ox; Br.y = WinY - oy; To.x = nx; To.y = WinY - ny; GLine(&To,Rop,&Br,Page); } swap(x,y) int *x,*y; { int z; if (*x > *y) { z = *x ; *x = *y ; *y = z; } } EDWIN_DD_RECT(lx,ly,nx,ny) int lx,ly,nx,ny; { RPos Br,To; RSize Size; swap(&lx,&nx); swap(&ly,&ny); Br.x = lx; Br.y = WinY - ny; Size.w = nx - lx; Size.h = ny - ly + 1; if (FillMode > 1) { /* use patterns for fill styles */ RasterOp(F_TILE | F_OR,&Patterns[FillMode].Image,0,0,Page,&Br,&Size); ny = WinY - ny; ly = WinY - ly; To.x = lx; To.y = ly; GLine(&To,F_1,&Br,Page); To.x = nx; GLine(&To,F_1,&Br,Page); To.y = ny; GLine(&To,F_1,&Br,Page); To.x = lx; GLine(&To,F_1,&Br,Page); } else { RasterOp(Rop,Page,&Br,&Size,Page,&Br,&Size); } } EDWIN_DD_HLINE(xl,xr,y) int xl,xr,y; { /* * this routine is used to fill in funny shaped polygons by doing a rasterop * on a single scan line and not drawing a box round it */ RPos Br; RSize Size; Br.x = xl; Br.y = y; Size.w = xr - xl; Size.h = 1; if (FillMode > 1) { RasterOp(F_TILE | F_OR,&Patterns[FillMode].Image,0,0,Page,&Br,&Size); } else { RasterOp(Rop,Page,&Br,&Size,Page,&Br,&Size); } } EDWIN_DD_POLY(count,pts) int count; RPos pts[]; { int i; RPos Br; /* only have to draw outline - HLINE and RECT does the rest */ Br.x = pts[0].x; Br.y = pts[0].y; for (i = 1; i < count - 1; i ++) GLine(&pts[i],F_1,&Br,Page); } EDWIN_DD_TEXT(sx,sy,ch) int sx,sy; char *ch; { RPos Br; Br.x = sx; Br.y = WinY - sy; GPutString(Page,&Br,F_S,CurFont,ch); } /* * Input stuff */ #define MAXEVENTS 100 #define EVENTMASK (E_MOVE_CLASS | E_BUTTON_CLASS | E_KEY_CLASS) Event events[MAXEVENTS]; static int arrayptr = 0; static int numevents = 0; eventinit() { KeyboardAttach(Pan); if (WinSetMask(CWin,EVENTMASK) == -1) Fail("WinSetMask"); PanelFlush(Pan); } resetscreen() { if (WinStowStatus(CWin) == 1) { /* if the window is stowed, then open it */ WinUnstow(CWin); eventinit(); } } EDWIN_DD_INTCHECK() { int thiseve,z; /* * This routine checks the keyboard for any ^C so that drawing can be * interrrupted */ WinSetNoWait(CWin); numevents = WinRead(CWin,events,MAXEVENTS); if (numevents < 0) Fail("Interrupt check"); arrayptr = 0; while (arrayptr < numevents) { if (events[arrayptr].EType == E_KEYPRESS) { z = events[arrayptr].EChar; if ((z == 3) || (z == 127)) { /* control C or DEL key */ WinSetWait(CWin); fprintf(stderr,"Interrupted\n"); return(1); } } arrayptr ++; } PanelFlush(Pan); WinSetWait(CWin); return(0); } checkevent() { if (events[arrayptr].EType == E_KEYPRESS) { arrayptr ++; return(events[arrayptr - 1].EChar); } return(0); } EDWIN_SCREEN_TTGET() { int ret; /* look at any old events sitting about */ PanelUpdate(Pan,refbox,1); resetscreen(); /* while (arrayptr < numevents) { ret = checkevent(); if (ret > 0) return(ret); arrayptr ++; } */ /* read some new events */ while (1) { /* only read if there are not some still to be read */ arrayptr ++; if (numevents <= arrayptr) { /* PanelFlush(Pan); */ numevents = WinRead(CWin,events,MAXEVENTS); arrayptr = 0; if (numevents < 0) Fail("EDWIN_SCREEN_TTGET - Bad ev count"); } while (arrayptr < numevents) { ret = checkevent(); if (ret > 0) return(ret); arrayptr ++; } } } static int lastx = 0, lasty = 0; static fromcursor = 0; EDWIN___B_SAM(z,x,y) int *z,*x,*y; { int thiseve; if (fromcursor == 0) { PanelUpdate(Pan,refbox,1); resetscreen(); /* open it if it is stowed */ } while (1) { /* again only read more if there are none waiting to be processed */ arrayptr ++; if (numevents <= arrayptr) { arrayptr = 0; /* PanelFlush(Pan); */ numevents = WinRead(CWin,events,MAXEVENTS); if (numevents < 0) Fail("EDWIN___B_SAM - bad EV count"); } *z = 0; while (arrayptr < numevents) { thiseve = events[arrayptr].EType; *x = events[arrayptr].EX; *y = WinY - events[arrayptr].EY; switch (events[arrayptr].EType) { case E_CURSOR_MOVES : case E_CURSOR_CROSS : { /* dont return unless last event */ lastx = *x; lasty = *y; if (arrayptr == numevents - 1) return; break; } case E_KEYPRESS : { *z = events[arrayptr].EChar; return; } case E_BUTTON : { *z = events[arrayptr].EButtons; return; } case E_CLICK : { /* No click events enabled, because they are too slow * (looking for double clicks etc) */ *z = events[arrayptr].EButtons; if (*z > 15) *z = *z / 16; return; } default : break; } arrayptr ++; } } } EDWIN___B_REQ(z,x,y) int *z, *x, *y; { resetscreen(); /* unstow etc if necessary */ *z = 0; while (1) { EDWIN___B_SAM(z,x,y); if (((0 < *z) && (*z <= 7)) || ((' ' <= *z) && (*z <= '~'))) break; } } static Fail(FailS) char *FailS; { fprintf(stderr,"EDWIN fails - %s\n",FailS); exit(1); }