1 package gnu.jemacs.buffer; 2 import java.awt.Color ; 3 4 5 6 public class BufferWriter extends java.io.Writer implements Runnable 7 { 8 Marker marker; 9 Object style; 10 Object stylePlain; 11 boolean adjustPoint; 12 13 14 static final int NO_ESCAPES_STATE = 1; 15 16 static final int NORMAL_STATE = 0; 17 20 static final int LAST_COLUMN_STATE = 1; 21 22 static final int SEEN_ESC_STATE = 2; 23 25 static final int SEEN_ESC_LBRAC_STATE = 3; 26 static final int SEEN_ESC_RBRAC_STATE = 4; 27 int state = NORMAL_STATE; 28 29 static final int ESC = 033; 30 31 boolean insertMode = false; 32 33 char[] savedOutput; 34 int savedCount; 35 36 public BufferWriter (Marker marker, boolean adjustPoint) 37 { 38 this.marker = marker; 39 EToolkit toolkit = EToolkit.getInstance(); 40 this.stylePlain = toolkit.getFace("output", true); 41 this.style = stylePlain; 42 this.adjustPoint = adjustPoint; 43 } 45 46 public BufferWriter (Buffer buffer) 47 { 48 this(buffer.pointMarker, false); 49 } 50 51 boolean bold = false; 52 boolean underline = false; 53 boolean blink = false; boolean inverse; 55 boolean invisible; 56 String foregroundName; 57 String backgroundName; 58 Color foreground; 59 Color background; 60 StringBuffer styleNameBuf; 61 String styleName; 62 63 void resetAttributes() 64 { 65 bold = false; 66 underline = false; 67 blink = false; 68 inverse = false; 69 invisible = false; 70 foregroundName = null; 71 backgroundName = null; 72 foreground = null; 73 background = null; 74 } 75 76 void updateStyle() 77 { 78 if (styleNameBuf == null) 79 styleNameBuf = new StringBuffer (60); 80 styleNameBuf.setLength(0); 81 if (underline) styleNameBuf.append("underlined,"); 82 if (bold) styleNameBuf.append("bold,"); 83 if (foreground != null) 84 { 85 styleNameBuf.append("fg="); 86 styleNameBuf.append(foregroundName != null ? foregroundName 87 : foreground.toString()); 88 styleNameBuf.append(','); 89 } 90 if (background != null) 91 { 92 styleNameBuf.append("bg="); 93 styleNameBuf.append(backgroundName != null ? backgroundName 94 : background.toString()); 95 styleNameBuf.append(','); 96 } 97 int slen = styleNameBuf.length(); 98 if (slen == 0) 99 { 100 style = stylePlain; 101 styleName = "output"; 102 return; 103 } 104 styleNameBuf.setLength(slen-1); styleName = styleNameBuf.toString(); 106 EToolkit toolkit = EToolkit.getInstance(); 107 style = toolkit.getFace(styleName, false); 108 if (style != null) 109 return; 110 style = toolkit.getFace(styleName, true); 111 toolkit.setUnderline(style, underline); 112 toolkit.setBold(style, bold); 113 if (foreground != null) 114 toolkit.setForeground(style, foreground); 115 if (background != null) 116 toolkit.setBackground(style, background); 117 } 118 119 private String name; 120 private Color color; 121 private void getColor(int index, boolean bright ) 122 { 123 switch (index) 124 { 125 case 0: color = Color.black; name = "black"; break; 126 case 1: color = Color.red; name = "red"; break; 127 case 2: color = Color.green; name = "green"; break; 128 case 3: color = Color.yellow; name = "yellow"; break; 129 case 4: color = Color.blue; name = "blue"; break; 130 case 5: color = Color.magenta; name = "magenta"; break; 131 case 6: color = Color.cyan; name = "cyan"; break; 132 case 7: color = Color.white; name = "white"; break; 133 default: color = null; name = null; 134 } 135 } 136 137 143 public int handleSetCharacterRendition(int param, int position) 144 { 145 switch (param) 146 { 147 case -1: case 0: 148 resetAttributes(); 149 case 1: 150 bold = true; 151 break; 152 case 4: 153 underline = true; 154 break; 155 case 22: 156 bold = false; 157 break; 158 case 24: 159 underline = false; 160 break; 161 default: 162 if (param >= 30 && param <= 39) 163 { 164 getColor(param - 30, false); 165 foreground = color; 166 foregroundName = name; 167 } 168 else if (param >= 40 && param <= 49) 169 { 170 getColor(param - 40, false); 171 background = color; 172 backgroundName = name; 173 } 174 else if (param >= 90 && param <= 97) 175 { 176 getColor(param - 90, true); 177 background = color; 178 backgroundName = name; 179 } 180 else if (param >= 100 && param <= 107) 181 { 182 getColor(param - 100, true); 183 background = color; 184 backgroundName = name; 185 } 186 } 188 return position; 189 } 190 191 public void handleOperatingSystemCommand(char ch) 192 { 193 if (ch == '\007') 194 { 195 state = NORMAL_STATE; 197 } 198 else if (savedCount >= savedOutput.length) 199 { 200 int i; 202 for (i = 0; i < savedCount && savedOutput[i] != '\n';) i++; 203 if (i < savedCount || ch == '\n') 204 state = NORMAL_STATE; else 206 savedCount = 0; } 208 else 209 savedOutput[savedCount++] = ch; 210 } 211 212 220 public int handleCSICommand(char ch, int param, int position) 221 { 222 switch (ch) 223 { 224 case 'C': moveColumns(param > 0 ? param : 1); 226 break; 227 case 'D': moveColumns(- (param > 0 ? param : 1)); 229 break; 230 case 'h': if (param == 4) 232 insertMode = true; 233 break; 234 case 'l': if (param == 4) 236 insertMode = false; 237 break; 238 case 'm': 239 return handleSetCharacterRendition(param, position); 240 } 241 return position; 242 } 243 244 public void handleEscapeBracket(char ch) 245 { 246 if (ch == ';' || (ch >= '0' && ch <= '9')) 247 { 248 if (savedCount >= savedOutput.length) 249 savedCount = 0; savedOutput[savedCount++] = ch; 251 } 252 else 253 { 254 int value = -1; 255 for (int i = 0; i < savedCount; i++) 256 { 257 ch = savedOutput[i]; 258 if (ch >= '0' && ch <= '9') 259 value = (value <= 0 ? 0 : 10 * value) + (ch - '0'); 260 else 261 { 262 i = handleCSICommand('m', value, i); 263 value = -1; 264 } 265 } 266 handleCSICommand('m', value, savedCount); 267 updateStyle(); 268 state = NORMAL_STATE; 269 } 270 } 271 272 public void unTabifyRestOfLine() 273 { 274 } 276 277 278 public void removeChars(int count) 279 { 280 int save = marker.getOffset(); 281 moveColumns(count); 282 marker.removeChar(marker.getOffset() - save); 283 } 284 285 286 public void moveColumns(int count) 287 { 288 marker.moveToColumn(marker.currentColumn() + count, true); 289 } 290 291 306 307 public synchronized void put (char[] data, int off, int len) 308 { 309 if (len == 0) 310 return; 311 if (insertMode) 312 unTabifyRestOfLine(); 313 else 314 removeChars(len); 315 boolean mustAdjustPoint 316 = adjustPoint && marker.getOffset() == marker.buffer.getDot(); 317 marker.insert(new String (data, off, len), style); 318 if (mustAdjustPoint) 319 marker.buffer.setDot(marker.getOffset()); 320 } 321 322 char[] buf1 = new char[1]; 323 324 public synchronized void write(int ch) 325 { 326 boolean move = marker.getOffset() == marker.buffer.getDot(); 327 write1(ch); 328 if (move) marker.buffer.setDot(marker.getOffset()); 329 } 330 331 public synchronized void write1(int ch) 332 { 333 if (state <= NORMAL_STATE) 334 { 335 if (ch >= ' ' || ch == '\n' || state < NORMAL_STATE) 336 { 337 buf1[0] = (char) ch; 338 put(buf1, 0, 1); 339 } 340 else if (ch == ESC) 341 state = SEEN_ESC_STATE; 342 else if (ch == '\b') 343 moveColumns(-1); 344 else if (ch == '\t') 345 { 346 int col = marker.currentColumn(); 347 marker.moveToColumn(col + 8 - (col & 7), true); 348 } 349 else if (ch == '\r') 350 { 351 } 354 else 355 System.err.println("received ctrl-"+(char)(ch+64)); 356 } 357 else if (state == SEEN_ESC_STATE) 358 { 359 switch (ch) 360 { 361 case '[': 362 state = SEEN_ESC_LBRAC_STATE; 363 if (savedOutput == null) 364 savedOutput = new char[100]; 365 savedCount = 0; 366 break; 367 case ']': 368 state = SEEN_ESC_RBRAC_STATE; 369 if (savedOutput == null) 370 savedOutput = new char[100]; 371 savedCount = 0; 372 break; 373 default: 374 state = NORMAL_STATE; 375 break; 376 } 377 } 378 else if (state == SEEN_ESC_LBRAC_STATE) 379 { 380 handleEscapeBracket((char) ch); 381 } 382 else 383 { 384 handleOperatingSystemCommand((char) ch); 385 } 386 } 387 388 public synchronized void write (char[] data, int off, int len) 389 { 390 boolean move = marker.getOffset() == marker.buffer.getDot(); 391 while (len > 0) 392 { 393 if (state > NORMAL_STATE) 394 { 395 write1(data[off++]); 396 len--; 397 } 398 else 399 { 400 int i; 401 if (state == NO_ESCAPES_STATE) 402 i = len; 403 else 404 { 405 for (i = 0; i < len; i++) 406 { 407 char ch = data[off+i]; 408 if (ch < ' ') 409 break; 410 } 411 } 412 if (i > 0) 413 { 414 put(data, off, i); 415 off += i; 416 len -= i; 417 } 418 if (i < len) 419 { 420 write1(data[off++]); 421 len--; 422 } 423 } 424 } 425 if (move) marker.buffer.setDot(marker.getOffset()); 426 } 427 428 public synchronized void flush() 429 { 430 } 431 432 public synchronized void close() 433 { 434 } 435 436 char[] buffer; 437 int count; 438 public void run() 439 { 440 write(buffer, 0, count); 441 } 442 } 443 | Popular Tags |