+
+ if (reallyCleared) {
+ // Really refreshed, do it all
+ frame.repaint();
+ return;
+ }
+
+ // Do nothing if nothing happened.
+ if (!dirty) {
+ return;
+ }
+
+ // Request a repaint, let the frame's repaint/update methods do the
+ // right thing.
+
+ // Find the minimum-size damaged region.
+ int xMin = frame.getWidth();
+ int xMax = 0;
+ int yMin = frame.getHeight();
+ int yMax = 0;
+
+ synchronized (this) {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ Cell lCell = logical[x][y];
+ Cell pCell = physical[x][y];
+
+ int xPixel = x * frame.textWidth + frame.left;
+ int yPixel = y * frame.textHeight + frame.top;
+
+ if (!lCell.equals(pCell)
+ || ((x == cursorX)
+ && (y == cursorY)
+ && cursorVisible)
+ ) {
+ if (xPixel < xMin) {
+ xMin = xPixel;
+ }
+ if (xPixel + frame.textWidth > xMax) {
+ xMax = xPixel + frame.textWidth;
+ }
+ if (yPixel < yMin) {
+ yMin = yPixel;
+ }
+ if (yPixel + frame.textHeight > yMax) {
+ yMax = yPixel + frame.textHeight;
+ }
+ }
+ }
+ }
+ }
+ if (xMin + frame.textWidth >= xMax) {
+ xMax += frame.textWidth;
+ }
+ if (yMin + frame.textHeight >= yMax) {
+ yMax += frame.textHeight;
+ }
+
+ // Repaint the desired area
+ frame.repaint(xMin, yMin, xMax - xMin, yMax - yMin);
+ // System.err.printf("REPAINT X %d %d Y %d %d\n", xMin, xMax, yMin, yMax);
+ }
+
+ /**
+ * Put the cursor at (x,y).
+ *
+ * @param visible if true, the cursor should be visible
+ * @param x column coordinate to put the cursor on
+ * @param y row coordinate to put the cursor on
+ */
+ @Override
+ public void putCursor(final boolean visible, final int x, final int y) {
+ if ((cursorVisible)
+ && (cursorY <= height - 1)
+ && (cursorX <= width - 1)
+ ) {
+ // Make the current cursor position dirty
+ if (physical[cursorX][cursorY].getChar() == 'Q') {
+ physical[cursorX][cursorY].setChar('X');
+ } else {
+ physical[cursorX][cursorY].setChar('Q');
+ }
+ }
+
+ super.putCursor(visible, x, y);