package bmsi.fsp; import java.io.IOException; import java.awt.Rectangle; import java.awt.AWTError; /** A physical screen window. This class uses actual screen coordinates and windowizes the basic terminal operations: write, fill, copyArea. @author Stuart D. Gathman Copyright (C) 2000 Business Management Systems, Inc. */ abstract public class PWin { private final PWinMgr wm; int id = -1; Rectangle loc; private char attr; /** Called by PWinMgr when repainting a part of the screen owned by this PWin. */ abstract protected void paint(int x,int y,int w,int h) throws IOException; public int getScreenRows() { return wm.ps.getRows(); } public int getScreenCols() { return wm.cols; } public void repaint(int x,int y,int w,int h) { if (isVisible()) wm.repaint(loc.intersection(new Rectangle(x,y,w,h))); } public void repaint() { if (isVisible()) wm.repaint(loc); } void set() { wm.set(loc.x,loc.y,loc.width,loc.height,id); } public void paint() throws IOException { paint(loc.x,loc.y,loc.width,loc.height); } public PWin(PWinMgr wm) { this.wm = wm; loc = wm.getScreenRect(); } public boolean isOnTop() { return wm.onTop[id]; } public boolean isVisible() { return id >= 0; } public void setVisible(boolean vis) { if (vis != isVisible()) { if (vis) { id = wm.addWin(this); } else { wm.delWin(id); id = -1; } reset(loc); } } private void reset(Rectangle r) { wm.reset(r); } public void setBounds(int x,int y,int w,int h) { //System.err.println("x="+x+",y="+y+",w="+w+",h="+h); if (!isVisible()) loc.setBounds(x,y,w,h); else { Rectangle r = loc; loc = new Rectangle(x,y,w,h).intersection(wm.getScreenRect()); reset(r.union(loc)); } } public void toFront() { if (isVisible()) wm.toFront(this); } public void toBack() { if (isVisible()) wm.toBack(this); } public void setAttr(int a) { attr = (char)a; } public void fill(int x,int y,int w,int h,char c) throws IOException { //System.err.println("Pwin.fill("+x+','+y+','+w+','+h+")="+(int)c); PScreen ps = wm.ps; // translate and clip to bounds Rectangle loc = this.loc; int x1 = loc.x; int x2 = loc.width; int y1 = loc.y; int y2 = loc.height; if (x < 0) { w += x; x = 0; } if (x + w > x2) { w = x2 - x; } if (w <= 0) return; if (y < 0) { h += y; y = 0; } if (y + h > y2) { h = y2 - y; } if (h <= 0) return; x += x1; y += y1; ps.setAttr(attr); if (isOnTop()) { //System.err.println("ps.fill("+x+','+y+','+w+','+h+')'); ps.fill(x,y,w,h,c); return; } int cols = wm.cols; char[] mask = wm.mask; for (int r = y; r < y + h; ++r) { int i = r * cols + x; int i1 = i; int w1 = w; while (w1 > 0) { int n = 0; while (n < w1 && mask[i+n] == id) ++n; if (n > 0) { //System.err.println("ps.fill("+(x+i-i1)+','+r+','+n+','+1+')'); ps.fill(x+i-i1,r,n,1,c); i += n; w1 -= n; n = 0; } while (n < w1 && mask[i + n] != id) ++n; i += n; w1 -= n; } } } public void write(int x,int y,char[] c,int pos,int w) throws IOException { //System.err.println("PWin.write("+x+','+y+") "+new String(c,pos,w)); PScreen ps = wm.ps; // clip to bounds Rectangle loc = this.loc; int x1 = loc.x; int x2 = loc.width; int y1 = loc.y; int y2 = loc.height; if (y < 0) return; if (y >= y2) return; if (x < 0) { w += x; x = 0; } if (x + w > x2) { w = x2 - x; } if (w <= 0) return; x += x1; y += y1; ps.setAttr(attr); if (isOnTop()) { //System.err.println("ps.write("+x+','+y+") "+new String(c,pos,w)); ps.setBufPos(x,y); ps.write(c,pos,w); //ps.write(x,y,w,new String(c,pos,w),attr); return; } int i = y * wm.cols + x; char[] mask = wm.mask; while (w > 0) { int n = 0; while (n < w && mask[i+n] == id) ++n; if (n > 0) { //System.err.println("mps.write("+x+','+y+") "+new String(c,pos,n)); ps.setBufPos(x,y); ps.write(c,pos,n); pos += n; x += n; i += n; w -= n; n = 0; } while (n < w && mask[i + n] != id) ++n; pos += n; x += n; i += n; w -= n; } } }