001: ///////////////////////////////////////////////////////////////////////////////
002: //
003: // This program is free software; you can redistribute it and/or modify
004: // it under the terms of the GNU General Public License and GNU Library
005: // General Public License as published by the Free Software Foundation;
006: // either version 2, or (at your option) any later version.
007: //
008: // This program is distributed in the hope that it will be useful,
009: // but WITHOUT ANY WARRANTY; without even the implied warranty of
010: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: // GNU General Public License and GNU Library General Public License
012: // for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // and GNU Library General Public License along with this program; if
016: // not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
017: // MA 02139, USA.
018: //
019: ///////////////////////////////////////////////////////////////////////////////
020:
021: package org.rdesktop.server.rdp;
022:
023: import java.awt.*;
024: import java.awt.image.*;
025:
026: import org.rdesktop.server.rdp.orders.*;
027: import org.rdesktop.server.rdp.keymapping.KeyCode;
028: import org.rdesktop.server.rdp.keymapping.KeyCode_FileBased;
029:
030: public abstract class RdpAbstractDesktopCanvas extends Canvas {
031: public static final int ROP2_COPY = 0xc;
032: private static final int ROP2_XOR = 0x6;
033: private static final int ROP2_AND = 0x8;
034: private static final int ROP2_NXOR = 0x9;
035: private static final int ROP2_OR = 0xe;
036: private static final int MIX_TRANSPARENT = 0;
037: private static final int MIX_OPAQUE = 1;
038: private static final int TEXT2_VERTICAL = 0x04;
039: private static final int TEXT2_IMPLICIT_X = 0x20;
040:
041: private int m_top = 0;
042: private int m_left = 0;
043: private int m_right = 0;
044: private int m_bottom = 0;
045:
046: private RdpCache m_cache = null;
047: private RdpRasterOp m_rasterOp = null;
048: private RdpAbstractInput m_input = null;
049: protected RdpImage m_backstore = null;
050: protected IndexColorModel colormap = null;
051:
052: public int m_width = 0;
053: public int m_height = 0;
054: public RdpProto m_rdp = null;
055: public KeyCode_FileBased m_fbKeys = null;
056:
057: protected static int parse_delta(byte[] buffer, int[] offset) {
058: int value = buffer[offset[0]++] & 0xff;
059: int two_byte = value & 0x80;
060:
061: if ((value & 0x40) != 0) {
062: value |= ~0x3f;
063: } else {
064: value &= 0x3f;
065: }
066:
067: if (two_byte != 0) {
068: value = (value << 8) | (buffer[offset[0]++] & 0xff);
069: }
070:
071: return value;
072: }
073:
074: public RdpAbstractDesktopCanvas(int width, int height) {
075: m_rasterOp = new RdpRasterOp();
076:
077: m_width = width;
078: m_height = height;
079: m_right = m_width - 1;
080: m_bottom = m_height - 1;
081:
082: setSize(m_width, m_height);
083:
084: m_backstore = new RdpImage(m_width, m_height,
085: BufferedImage.TYPE_INT_RGB);
086: }
087:
088: protected Cursor createCustomCursor(Image wincursor, Point p,
089: String s, int cache_idx) {
090: if (cache_idx == 1) {
091: return Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
092: }
093:
094: return Cursor.getDefaultCursor();
095: }
096:
097: public void paint(Graphics g) {
098: update(g);
099: }
100:
101: public void registerPalette(IndexColorModel cm) {
102: this .colormap = cm;
103:
104: m_backstore.setIndexColorModel(cm);
105: }
106:
107: public void registerCommLayer(RdpProto rdp) {
108: m_rdp = rdp;
109: if (m_fbKeys != null) {
110: m_input = new RdpInput(m_rdp, this , m_fbKeys);
111: }
112: }
113:
114: public void registerKeyboard(KeyCode_FileBased keys) {
115: m_fbKeys = keys;
116: if (m_rdp != null) {
117: m_input = new RdpInput(m_rdp, this , keys);
118: }
119: }
120:
121: public void registerCache(RdpCache cache) {
122: m_cache = cache;
123: }
124:
125: public void displayCompressed(int x, int y, int width, int height,
126: int size, RdpPacket data, int Bpp, IndexColorModel cm)
127: throws RdpDesktopException {
128: m_backstore = RdpBitmap.decompressImgDirect(width, height,
129: size, data, Bpp, cm, x, y, m_backstore);
130: }
131:
132: public void displayImage(Image img, int x, int y)
133: throws RdpDesktopException {
134:
135: Graphics g = m_backstore.getGraphics();
136: g.drawImage(img, x, y, null);
137: g.dispose();
138:
139: }
140:
141: public void displayImage(int[] data, int w, int h, int x, int y,
142: int cx, int cy) throws RdpDesktopException {
143: m_backstore.setRGB(x, y, cx, cy, data, 0, w);
144: }
145:
146: public int[] getImage(int x, int y, int cx, int cy) {
147:
148: int[] data = new int[cx * cy];
149: data = m_backstore.getRGB(x, y, cx, cy, null, 0, cx);
150: return data;
151: }
152:
153: public void putImage(int x, int y, int cx, int cy, int[] data) {
154: m_backstore.setRGBNoConversion(x, y, cx, cy, data, 0, cx);
155: this .repaint(x, y, cx, cy);
156: }
157:
158: public void resetClip() {
159: Graphics g = this .getGraphics();
160: Rectangle bounds = this .getBounds();
161: g.setClip(bounds.x, bounds.y, bounds.width, bounds.height);
162: m_top = 0;
163: m_left = 0;
164: m_right = m_width - 1;
165: m_bottom = m_height - 1;
166: }
167:
168: public void setClip(BoundsOrder bounds) {
169: Graphics g = this .getGraphics();
170: g.setClip(bounds.getLeft(), bounds.getTop(), bounds.getRight()
171: - bounds.getLeft(), bounds.getBottom()
172: - bounds.getTop());
173: m_top = bounds.getTop();
174: m_left = bounds.getLeft();
175: m_right = bounds.getRight();
176: m_bottom = bounds.getBottom();
177: }
178:
179: public void movePointer(int x, int y) {
180: }
181:
182: public void fillRectangle(int x, int y, int cx, int cy, int color) {
183: if (x > m_right || y > m_bottom) {
184: return;
185: }
186:
187: int Bpp = RdpOptions.Bpp;
188: color = RdpBitmap.convertTo24(color);
189:
190: if (Bpp == 3) {
191: color = ((color & 0xFF) << 16) | (color & 0xFF00)
192: | ((color & 0xFF0000) >> 16);
193: }
194:
195: int clipright = x + cx - 1;
196: if (clipright > m_right) {
197: clipright = m_right;
198: }
199:
200: if (x < m_left) {
201: x = m_left;
202: }
203:
204: cx = clipright - x + 1;
205:
206: int clipbottom = y + cy - 1;
207: if (clipbottom > m_bottom) {
208: clipbottom = m_bottom;
209: }
210:
211: if (y < m_top) {
212: y = m_top;
213: }
214:
215: cy = clipbottom - y + 1;
216:
217: int[] rect = new int[cx * cy];
218: for (int i = 0; i < rect.length; i++) {
219: rect[i] = color;
220: }
221:
222: m_backstore.setRGB(x, y, cx, cy, rect, 0, cx);
223:
224: this .repaint(x, y, cx, cy);
225: }
226:
227: public void drawLine(int x1, int y1, int x2, int y2, int color,
228: int opcode) {
229: color = RdpBitmap.convertTo24(color);
230:
231: if (x1 == x2 || y1 == y2) {
232: drawLineVerticalHorizontal(x1, y1, x2, y2, color, opcode);
233: return;
234: }
235:
236: int deltax = Math.abs(x2 - x1);
237: int deltay = Math.abs(y2 - y1);
238: int x = x1;
239: int y = y1;
240: int xinc1, xinc2, yinc1, yinc2;
241: int num, den, numadd, numpixels;
242:
243: if (x2 >= x1) {
244: xinc1 = 1;
245: xinc2 = 1;
246: } else {
247: xinc1 = -1;
248: xinc2 = -1;
249: }
250:
251: if (y2 >= y1) {
252: yinc1 = 1;
253: yinc2 = 1;
254: } else {
255: yinc1 = -1;
256: yinc2 = -1;
257: }
258:
259: if (deltax >= deltay) {
260: xinc1 = 0;
261: yinc2 = 0;
262: den = deltax;
263: num = deltax / 2;
264: numadd = deltay;
265: numpixels = deltax;
266: } else {
267: xinc2 = 0;
268: yinc1 = 0;
269: den = deltay;
270: num = deltay / 2;
271: numadd = deltax;
272: numpixels = deltay;
273: }
274:
275: for (int curpixel = 0; curpixel <= numpixels; curpixel++) {
276: setPixel(opcode, x, y, color);
277: num += numadd;
278: if (num >= den) {
279: num -= den;
280: x += xinc1;
281: y += yinc1;
282: }
283:
284: x += xinc2;
285: y += yinc2;
286: }
287:
288: int x_min = x1 < x2 ? x1 : x2;
289: int x_max = x1 > x2 ? x1 : x2;
290: int y_min = y1 < y2 ? y1 : y2;
291: int y_max = y1 > y2 ? y1 : y2;
292:
293: this
294: .repaint(x_min, y_min, x_max - x_min + 1, y_max - y_min
295: + 1);
296: }
297:
298: public void drawLineVerticalHorizontal(int x1, int y1, int x2,
299: int y2, int color, int opcode) {
300: int i;
301: int pbackstore;
302: if (y1 == y2) {
303: if (y1 >= m_top && y1 <= m_bottom) {
304: if (x2 > x1) {
305: if (x1 < m_left) {
306: x1 = m_left;
307: }
308:
309: if (x2 > m_right) {
310: x2 = m_right;
311: }
312:
313: pbackstore = y1 * m_width + x1;
314: for (i = 0; i < x2 - x1; i++) {
315: m_rasterOp.do_pixel(opcode, m_backstore,
316: x1 + i, y1, color);
317: pbackstore++;
318: }
319:
320: repaint(x1, y1, x2 - x1 + 1, 1);
321: } else {
322: if (x2 < m_left) {
323: x2 = m_left;
324: }
325:
326: if (x1 > m_right) {
327: x1 = m_right;
328: }
329:
330: pbackstore = y1 * m_width + x1;
331: for (i = 0; i < x1 - x2; i++) {
332: m_rasterOp.do_pixel(opcode, m_backstore,
333: x2 + i, y1, color);
334: pbackstore--;
335: }
336:
337: repaint(x2, y1, x1 - x2 + 1, 1);
338: }
339: }
340: } else {
341: if (x1 >= m_left && x1 <= m_right) {
342: if (y2 > y1) {
343: if (y1 < m_top) {
344: y1 = m_top;
345: }
346:
347: if (y2 > m_bottom) {
348: y2 = m_bottom;
349: }
350:
351: pbackstore = y1 * m_width + x1;
352: for (i = 0; i < y2 - y1; i++) {
353: m_rasterOp.do_pixel(opcode, m_backstore, x1, y1
354: + i, color);
355: pbackstore += m_width;
356: }
357:
358: repaint(x1, y1, 1, y2 - y1 + 1);
359: } else {
360: if (y2 < m_top) {
361: y2 = m_top;
362: }
363:
364: if (y1 > m_bottom) {
365: y1 = m_bottom;
366: }
367:
368: pbackstore = y1 * m_width + x1;
369: for (i = 0; i < y1 - y2; i++) {
370: m_rasterOp.do_pixel(opcode, m_backstore, x1, y2
371: + i, color);
372: pbackstore -= m_width;
373: }
374:
375: repaint(x1, y2, 1, y1 - y2 + 1);
376: }
377: }
378: }
379: }
380:
381: public void drawLineOrder(LineOrder line) {
382: int x1 = line.getStartX();
383: int y1 = line.getStartY();
384: int x2 = line.getEndX();
385: int y2 = line.getEndY();
386:
387: int fgcolor = line.getPen().getColor();
388:
389: int opcode = line.getOpcode() - 1;
390: drawLine(x1, y1, x2, y2, fgcolor, opcode);
391: }
392:
393: public void drawDestBltOrder(DestBltOrder destblt) {
394: int x = destblt.getX();
395: int y = destblt.getY();
396:
397: if (x > m_right || y > m_bottom) {
398: return;
399: }
400:
401: int cx = destblt.getCX();
402: int cy = destblt.getCY();
403:
404: int clipright = x + cx - 1;
405: if (clipright > m_right) {
406: clipright = m_right;
407: }
408:
409: if (x < m_left) {
410: x = m_left;
411: }
412:
413: cx = clipright - x + 1;
414:
415: int clipbottom = y + cy - 1;
416: if (clipbottom > m_bottom) {
417: clipbottom = m_bottom;
418: }
419:
420: if (y < m_top) {
421: y = m_top;
422: }
423:
424: cy = clipbottom - y + 1;
425:
426: m_rasterOp.do_array(destblt.getOpcode(), m_backstore, m_width,
427: x, y, cx, cy, null, 0, 0, 0);
428: this .repaint(x, y, cx, cy);
429:
430: }
431:
432: public void drawScreenBltOrder(ScreenBltOrder screenblt) {
433: int x = screenblt.getX();
434: int y = screenblt.getY();
435:
436: if (x > m_right || y > m_bottom) {
437: return;
438: }
439:
440: int cx = screenblt.getCX();
441: int cy = screenblt.getCY();
442: int srcx = screenblt.getSrcX();
443: int srcy = screenblt.getSrcY();
444:
445: int clipright = x + cx - 1;
446: if (clipright > m_right) {
447: clipright = m_right;
448: }
449:
450: if (x < m_left) {
451: x = m_left;
452: }
453:
454: cx = clipright - x + 1;
455:
456: int clipbottom = y + cy - 1;
457: if (clipbottom > m_bottom) {
458: clipbottom = m_bottom;
459: }
460:
461: if (y < m_top) {
462: y = m_top;
463: }
464:
465: cy = clipbottom - y + 1;
466:
467: srcx += x - screenblt.getX();
468: srcy += y - screenblt.getY();
469:
470: m_rasterOp.do_array(screenblt.getOpcode(), m_backstore,
471: m_width, x, y, cx, cy, null, m_width, srcx, srcy);
472: this .repaint(x, y, cx, cy);
473:
474: }
475:
476: public void drawMemBltOrder(MemBltOrder memblt) {
477: int x = memblt.getX();
478: int y = memblt.getY();
479:
480: if (x > m_right || y > m_bottom) {
481: return;
482: }
483:
484: int cx = memblt.getCX();
485: int cy = memblt.getCY();
486: int srcx = memblt.getSrcX();
487: int srcy = memblt.getSrcY();
488:
489: int clipright = x + cx - 1;
490: if (clipright > m_right) {
491: clipright = m_right;
492: }
493:
494: if (x < m_left) {
495: x = m_left;
496: }
497:
498: cx = clipright - x + 1;
499:
500: int clipbottom = y + cy - 1;
501: if (clipbottom > m_bottom) {
502: clipbottom = m_bottom;
503: }
504:
505: if (y < m_top) {
506: y = m_top;
507: }
508:
509: cy = clipbottom - y + 1;
510:
511: srcx += x - memblt.getX();
512: srcy += y - memblt.getY();
513:
514: try {
515: RdpBitmap bitmap = m_cache.getBitmap(memblt.getCacheID(),
516: memblt.getCacheIDX());
517: m_rasterOp.do_array(memblt.getOpcode(), m_backstore,
518: m_width, x, y, cx, cy, bitmap.getBitmapData(),
519: bitmap.getWidth(), srcx, srcy);
520: this .repaint(x, y, cx, cy);
521: } catch (RdpDesktopException e) {
522: }
523: }
524:
525: public void patBltOrder(int opcode, int x, int y, int cx, int cy,
526: int fgcolor, int bgcolor, Brush brush) {
527: fgcolor = RdpBitmap.convertTo24(fgcolor);
528: bgcolor = RdpBitmap.convertTo24(bgcolor);
529:
530: int clipright = x + cx - 1;
531: if (clipright > m_right) {
532: clipright = m_right;
533: }
534:
535: if (x < m_left) {
536: x = m_left;
537: }
538:
539: cx = clipright - x + 1;
540:
541: int clipbottom = y + cy - 1;
542: if (clipbottom > m_bottom) {
543: clipbottom = m_bottom;
544: }
545:
546: if (y < m_top) {
547: y = m_top;
548: }
549:
550: cy = clipbottom - y + 1;
551:
552: int i;
553: int[] src = null;
554: switch (brush.getStyle()) {
555: case 0: {
556: src = new int[cx * cy];
557: for (i = 0; i < src.length; i++) {
558: src[i] = fgcolor;
559: }
560: m_rasterOp.do_array(opcode, m_backstore, m_width, x, y, cx,
561: cy, src, cx, 0, 0);
562: this .repaint(x, y, cx, cy);
563: break;
564: }
565: case 2: {
566: break;
567: }
568: case 3: {
569: int brushx = brush.getXOrigin();
570: int brushy = brush.getYOrigin();
571: byte[] pattern = brush.getPattern();
572: byte[] ipattern = pattern;
573:
574: src = new int[cx * cy];
575: int psrc = 0;
576: for (i = 0; i < cy; i++) {
577: for (int j = 0; j < cx; j++) {
578: if ((ipattern[(i + brushy) % 8] & (0x01 << ((j + brushx) % 8))) == 0) {
579: src[psrc] = fgcolor;
580: } else {
581: src[psrc] = bgcolor;
582: }
583:
584: psrc++;
585: }
586: }
587:
588: m_rasterOp.do_array(opcode, m_backstore, m_width, x, y, cx,
589: cy, src, cx, 0, 0);
590: this .repaint(x, y, cx, cy);
591: break;
592: }
593: default: {
594: }
595: }
596: }
597:
598: public void drawPatBltOrder(PatBltOrder patblt) {
599: Brush brush = patblt.getBrush();
600: int x = patblt.getX();
601: int y = patblt.getY();
602:
603: if (x > m_right || y > m_bottom) {
604: return;
605: }
606:
607: int cx = patblt.getCX();
608: int cy = patblt.getCY();
609: int fgcolor = patblt.getForegroundColor();
610: int bgcolor = patblt.getBackgroundColor();
611: int opcode = patblt.getOpcode();
612:
613: patBltOrder(opcode, x, y, cx, cy, fgcolor, bgcolor, brush);
614: }
615:
616: public void drawTriBltOrder(TriBltOrder triblt) {
617: int x = triblt.getX();
618: int y = triblt.getY();
619:
620: if (x > m_right || y > m_bottom) {
621: return;
622: }
623:
624: int cx = triblt.getCX();
625: int cy = triblt.getCY();
626: int srcx = triblt.getSrcX();
627: int srcy = triblt.getSrcY();
628: int fgcolor = triblt.getForegroundColor();
629: int bgcolor = triblt.getBackgroundColor();
630: Brush brush = triblt.getBrush();
631:
632: fgcolor = RdpBitmap.convertTo24(fgcolor);
633: bgcolor = RdpBitmap.convertTo24(bgcolor);
634:
635: int clipright = x + cx - 1;
636: if (clipright > m_right) {
637: clipright = m_right;
638: }
639:
640: if (x < m_left) {
641: x = m_left;
642: }
643:
644: cx = clipright - x + 1;
645:
646: int clipbottom = y + cy - 1;
647: if (clipbottom > m_bottom) {
648: clipbottom = m_bottom;
649: }
650:
651: if (y < m_top) {
652: y = m_top;
653: }
654:
655: cy = clipbottom - y + 1;
656:
657: try {
658: RdpBitmap bitmap = m_cache.getBitmap(triblt.getCacheID(),
659: triblt.getCacheIDX());
660: switch (triblt.getOpcode()) {
661: case 0x69: {
662: m_rasterOp.do_array(ROP2_XOR, m_backstore, m_width, x,
663: y, cx, cy, bitmap.getBitmapData(), bitmap
664: .getWidth(), srcx, srcy);
665: patBltOrder(ROP2_NXOR, x, y, cx, cy, fgcolor, bgcolor,
666: brush);
667: break;
668: }
669: case 0xb8: {
670: patBltOrder(ROP2_XOR, x, y, cx, cy, fgcolor, bgcolor,
671: brush);
672: m_rasterOp.do_array(ROP2_AND, m_backstore, m_width, x,
673: y, cx, cy, bitmap.getBitmapData(), bitmap
674: .getWidth(), srcx, srcy);
675: patBltOrder(ROP2_XOR, x, y, cx, cy, fgcolor, bgcolor,
676: brush);
677: break;
678: }
679: case 0xc0: {
680: m_rasterOp.do_array(ROP2_COPY, m_backstore, m_width, x,
681: y, cx, cy, bitmap.getBitmapData(), bitmap
682: .getWidth(), srcx, srcy);
683: patBltOrder(ROP2_AND, x, y, cx, cy, fgcolor, bgcolor,
684: brush);
685: break;
686: }
687: default: {
688: m_rasterOp.do_array(ROP2_COPY, m_backstore, m_width, x,
689: y, cx, cy, bitmap.getBitmapData(), bitmap
690: .getWidth(), srcx, srcy);
691: break;
692: }
693: }
694: } catch (RdpDesktopException e) {
695: }
696: }
697:
698: public void drawPolyLineOrder(PolyLineOrder polyline) {
699: int x = polyline.getX();
700: int y = polyline.getY();
701: int fgcolor = polyline.getForegroundColor();
702: int datasize = polyline.getDataSize();
703: byte[] databytes = polyline.getData();
704: int lines = polyline.getLines();
705:
706: fgcolor = RdpBitmap.convertTo24(fgcolor);
707:
708: int[] data = new int[1];
709: data[0] = ((lines - 1) / 4) + 1;
710: int flags = 0;
711: int index = 0;
712:
713: int opcode = polyline.getOpcode() - 1;
714:
715: for (int line = 0; (line < lines) && (data[0] < datasize); line++) {
716: int xfrom = x;
717: int yfrom = y;
718:
719: if (line % 4 == 0) {
720: flags = databytes[index++];
721: }
722:
723: if ((flags & 0xc0) == 0) {
724: flags |= 0xc0;
725: }
726:
727: if ((flags & 0x40) != 0) {
728: x += parse_delta(databytes, data);
729: }
730:
731: if ((flags & 0x80) != 0) {
732: y += parse_delta(databytes, data);
733: }
734:
735: drawLine(xfrom, yfrom, x, y, fgcolor, opcode);
736: flags <<= 2;
737: }
738: }
739:
740: public void drawRectangleOrder(RectangleOrder rect) {
741: fillRectangle(rect.getX(), rect.getY(), rect.getCX(), rect
742: .getCY(), rect.getColor());
743: }
744:
745: public void setPixel(int opcode, int x, int y, int color) {
746: int Bpp = RdpOptions.Bpp;
747:
748: if (Bpp == 3) {
749: color = ((color & 0xFF) << 16) | (color & 0xFF00)
750: | ((color & 0xFF0000) >> 16);
751: }
752:
753: if ((x < m_left) || (x > m_right) || (y < m_top)
754: || (y > m_bottom)) {
755: } else {
756: m_rasterOp.do_pixel(opcode, m_backstore, x, y, color);
757: }
758: }
759:
760: public void drawGlyph(int mixmode, int x, int y, int cx, int cy,
761: byte[] data, int bgcolor, int fgcolor) {
762: int pdata = 0;
763: int index = 0x80;
764:
765: int bytes_per_row = (cx - 1) / 8 + 1;
766: int newx, newy, newcx, newcy;
767:
768: int Bpp = RdpOptions.Bpp;
769:
770: fgcolor = RdpBitmap.convertTo24(fgcolor);
771: bgcolor = RdpBitmap.convertTo24(bgcolor);
772:
773: if (Bpp == 3) {
774: fgcolor = ((fgcolor & 0xFF) << 16) | (fgcolor & 0xFF00)
775: | ((fgcolor & 0xFF0000) >> 16);
776: bgcolor = ((bgcolor & 0xFF) << 16) | (bgcolor & 0xFF00)
777: | ((bgcolor & 0xFF0000) >> 16);
778: }
779:
780: if (x > m_right || y > m_bottom) {
781: return;
782: }
783:
784: int clipright = x + cx - 1;
785: if (clipright > m_right) {
786: clipright = m_right;
787: }
788:
789: if (x < m_left) {
790: newx = m_left;
791: } else {
792: newx = x;
793: }
794:
795: newcx = clipright - x + 1;
796:
797: int clipbottom = y + cy - 1;
798: if (clipbottom > m_bottom) {
799: clipbottom = m_bottom;
800: }
801:
802: if (y < m_top) {
803: newy = m_top;
804: } else {
805: newy = y;
806: }
807:
808: newcy = clipbottom - newy + 1;
809:
810: int pbackstore = (newy * m_width) + x;
811: pdata = bytes_per_row * (newy - y);
812:
813: if (mixmode == MIX_TRANSPARENT) {
814: for (int i = 0; i < newcy; i++) {
815: for (int j = 0; j < newcx; j++) {
816: if (index == 0) {
817: pdata++;
818: index = 0x80;
819: }
820:
821: if ((data[pdata] & index) != 0) {
822: if ((x + j >= newx) && (newx + j > 0)
823: && (newy + i > 0)) {
824: m_backstore.setRGB(newx + j, newy + i,
825: fgcolor);
826: }
827: }
828:
829: index >>= 1;
830: }
831:
832: pdata++;
833: index = 0x80;
834: pbackstore += m_width;
835: if (pdata == data.length) {
836: pdata = 0;
837: }
838: }
839: } else {
840: for (int i = 0; i < newcy; i++) {
841: for (int j = 0; j < newcx; j++) {
842: if (index == 0) {
843: pdata++;
844: index = 0x80;
845: }
846:
847: if (x + j >= newx) {
848: if ((x + j > 0) && (y + i > 0)) {
849: if ((data[pdata] & index) != 0) {
850: m_backstore.setRGB(x + j, y + i,
851: fgcolor);
852: } else {
853: m_backstore.setRGB(x + j, y + i,
854: bgcolor);
855: }
856: }
857: }
858:
859: index >>= 1;
860: }
861:
862: pdata++;
863: index = 0x80;
864: pbackstore += m_width;
865: if (pdata == data.length) {
866: pdata = 0;
867: }
868: }
869: }
870:
871: this .repaint(newx, newy, newcx, newcy);
872: }
873:
874: public Cursor createCursor(int x, int y, int w, int h,
875: byte[] andmask, byte[] xormask, int cache_idx) {
876: int pxormask = 0;
877: int pandmask = 0;
878: Point p = new Point(x, y);
879: int size = w * h;
880: int scanline = w / 8;
881: int offset = 0;
882: byte[] mask = new byte[size];
883: int[] cursor = new int[size];
884: int pcursor = 0, pmask = 0;
885:
886: offset = size;
887:
888: for (int i = 0; i < h; i++) {
889: offset -= w;
890: pmask = offset;
891: for (int j = 0; j < scanline; j++) {
892: for (int bit = 0x80; bit > 0; bit >>= 1) {
893: if ((andmask[pandmask] & bit) != 0) {
894: mask[pmask] = 0;
895: } else {
896: mask[pmask] = 1;
897: }
898:
899: pmask++;
900: }
901:
902: pandmask++;
903: }
904: }
905:
906: offset = size;
907: pcursor = 0;
908:
909: for (int i = 0; i < h; i++) {
910: offset -= w;
911: pcursor = offset;
912: for (int j = 0; j < w; j++) {
913: cursor[pcursor] = ((xormask[pxormask + 2] << 16) & 0x00ff0000)
914: | ((xormask[pxormask + 1] << 8) & 0x0000ff00)
915: | (xormask[pxormask] & 0x000000ff);
916: pxormask += 3;
917: pcursor++;
918: }
919:
920: }
921:
922: offset = size;
923: pmask = 0;
924: pcursor = 0;
925: pxormask = 0;
926:
927: for (int i = 0; i < h; i++) {
928: for (int j = 0; j < w; j++) {
929: if ((mask[pmask] == 0) && (cursor[pcursor] != 0)) {
930: cursor[pcursor] = ~(cursor[pcursor]);
931: cursor[pcursor] |= 0xff000000;
932: } else if ((mask[pmask] == 1) || (cursor[pcursor] != 0)) {
933: cursor[pcursor] |= 0xff000000;
934: }
935:
936: pcursor++;
937: pmask++;
938: }
939: }
940:
941: Image wincursor = this .createImage(new MemoryImageSource(w, h,
942: cursor, 0, w));
943: return createCustomCursor(wincursor, p, "", cache_idx);
944: }
945:
946: public void lostFocus() {
947: if (m_input != null) {
948: m_input.lostFocus();
949: }
950: }
951:
952: public void gainedFocus() {
953: if (m_input != null) {
954: m_input.gainedFocus();
955: }
956: }
957:
958: public void triggerReadyToSend() {
959: m_input.triggerReadyToSend();
960: }
961: }
|