1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.microemu.device.swt;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.net.URL;
26 import java.util.Enumeration;
27 import java.util.Hashtable;
28 import java.util.Vector;
29
30 import javax.microedition.lcdui.Canvas;
31 import javax.microedition.lcdui.Displayable;
32 import javax.microedition.lcdui.Image;
33 import javax.microedition.lcdui.game.Sprite;
34
35 import org.eclipse.swt.graphics.Font;
36 import org.eclipse.swt.graphics.ImageData;
37 import org.eclipse.swt.graphics.RGB;
38 import org.microemu.DisplayAccess;
39 import org.microemu.EmulatorContext;
40 import org.microemu.MIDletAccess;
41 import org.microemu.MIDletBridge;
42 import org.microemu.app.ui.swt.ImageFilter;
43 import org.microemu.app.ui.swt.SwtDeviceComponent;
44 import org.microemu.app.ui.swt.SwtGraphics;
45 import org.microemu.app.util.IOUtils;
46 import org.microemu.device.Device;
47 import org.microemu.device.DeviceFactory;
48 import org.microemu.device.InputMethod;
49 import org.microemu.device.MutableImage;
50 import org.microemu.device.impl.Button;
51 import org.microemu.device.impl.Color;
52 import org.microemu.device.impl.DeviceDisplayImpl;
53 import org.microemu.device.impl.PositionedImage;
54 import org.microemu.device.impl.Rectangle;
55 import org.microemu.device.impl.Shape;
56 import org.microemu.device.impl.SoftButton;
57
58
59 public class SwtDeviceDisplay implements DeviceDisplayImpl
60 {
61 EmulatorContext context;
62
63 Rectangle displayRectangle;
64 Rectangle displayPaintable;
65
66 boolean isColor;
67 int numColors;
68 int numAlphaLevels;
69
70 Color backgroundColor;
71 Color foregroundColor;
72
73 PositionedImage mode123Image;
74 PositionedImage modeAbcUpperImage;
75 PositionedImage modeAbcLowerImage;
76
77 public SwtDeviceDisplay(EmulatorContext context)
78 {
79 this.context = context;
80 }
81
82
83 public MutableImage getDisplayImage()
84 {
85 return context.getDisplayComponent().getDisplayImage();
86 }
87
88
89 public int getHeight()
90 {
91 return displayPaintable.height;
92 }
93
94
95 public int getWidth()
96 {
97 return displayPaintable.width;
98 }
99
100
101 public int getFullHeight()
102 {
103 return displayRectangle.height;
104 }
105
106
107 public int getFullWidth()
108 {
109 return displayRectangle.width;
110 }
111
112
113 public boolean isColor()
114 {
115 return isColor;
116 }
117
118
119 public boolean isFullScreenMode()
120 {
121 MIDletAccess ma = MIDletBridge.getMIDletAccess();
122 if (ma == null) {
123 return false;
124 } else {
125 DisplayAccess da = ma.getDisplayAccess();
126 if (da == null) {
127 return false;
128 } else {
129 return da.isFullScreenMode();
130 }
131 }
132 }
133
134
135 public int numAlphaLevels()
136 {
137 return numAlphaLevels;
138 }
139
140
141 public int numColors()
142 {
143 return numColors;
144 }
145
146
147 public void paintControls(SwtGraphics g)
148 {
149 Device device = DeviceFactory.getDevice();
150
151 g.setBackground(g.getColor(new RGB(
152 backgroundColor.getRed(),
153 backgroundColor.getGreen(),
154 backgroundColor.getBlue())));
155 g.fillRectangle(0, 0, displayRectangle.width, displayPaintable.y);
156 g.fillRectangle(0, displayPaintable.y,
157 displayPaintable.x, displayPaintable.height);
158 g.fillRectangle(displayPaintable.x + displayPaintable.width, displayPaintable.y,
159 displayRectangle.width - displayPaintable.x - displayPaintable.width, displayPaintable.height);
160 g.fillRectangle(0, displayPaintable.y + displayPaintable.height,
161 displayRectangle.width, displayRectangle.height - displayPaintable.y - displayPaintable.height);
162
163 g.setForeground(g.getColor(new RGB(
164 foregroundColor.getRed(),
165 foregroundColor.getGreen(),
166 foregroundColor.getBlue())));
167 for (Enumeration s = device.getSoftButtons().elements(); s.hasMoreElements();) {
168 ((SwtSoftButton) s.nextElement()).paint(g);
169 }
170
171 int inputMode = device.getInputMethod().getInputMode();
172 if (inputMode == InputMethod.INPUT_123) {
173 g.drawImage(((SwtImmutableImage) mode123Image.getImage()).getImage(),
174 mode123Image.getRectangle().x, mode123Image.getRectangle().y);
175 } else if (inputMode == InputMethod.INPUT_ABC_UPPER) {
176 g.drawImage(((SwtImmutableImage) modeAbcUpperImage.getImage()).getImage(),
177 modeAbcUpperImage.getRectangle().x, modeAbcUpperImage.getRectangle().y);
178 } else if (inputMode == InputMethod.INPUT_ABC_LOWER) {
179 g.drawImage(((SwtImmutableImage) modeAbcLowerImage.getImage()).getImage(),
180 modeAbcLowerImage.getRectangle().x, modeAbcLowerImage.getRectangle().y);
181 }
182 }
183
184
185 public void paintDisplayable(SwtGraphics g, int x, int y, int width, int height)
186 {
187 MIDletAccess ma = MIDletBridge.getMIDletAccess();
188 if (ma == null) {
189 return;
190 }
191 DisplayAccess da = ma.getDisplayAccess();
192 if (da == null) {
193 return;
194 }
195 Displayable current = da.getCurrent();
196 if (current == null) {
197 return;
198 }
199
200 g.setForeground(g.getColor(new RGB(
201 foregroundColor.getRed(),
202 foregroundColor.getGreen(),
203 foregroundColor.getBlue())));
204
205 org.eclipse.swt.graphics.Rectangle oldclip = g.getClipping();
206 if (!(current instanceof Canvas)
207 || ((Canvas) current).getWidth() != displayRectangle.width
208 || ((Canvas) current).getHeight() != displayRectangle.height) {
209 g.translate(displayPaintable.x, displayPaintable.y);
210 }
211 g.setClipping(new org.eclipse.swt.graphics.Rectangle(x, y, width, height));
212 Font oldf = g.getFont();
213 ma.getDisplayAccess().paint(new SwtDisplayGraphics(g, getDisplayImage()));
214 g.setFont(oldf);
215 if (!(current instanceof Canvas)
216 || ((Canvas) current).getWidth() != displayRectangle.width
217 || ((Canvas) current).getHeight() != displayRectangle.height) {
218 g.translate(-displayPaintable.x, -displayPaintable.y);
219 }
220 g.setClipping(oldclip);
221 }
222
223
224 public void repaint(int x, int y, int width, int height)
225 {
226 context.getDisplayComponent().repaintRequest(x, y, width, height);
227 }
228
229
230 public void setScrollDown(boolean state)
231 {
232 Enumeration en = DeviceFactory.getDevice().getSoftButtons().elements();
233 while (en.hasMoreElements()) {
234 SoftButton button = (SoftButton) en.nextElement();
235 if (button.getType() == SoftButton.TYPE_ICON
236 && button.getName().equals("down")) {
237 button.setVisible(state);
238 }
239 }
240 }
241
242
243 public void setScrollUp(boolean state)
244 {
245 Enumeration en = DeviceFactory.getDevice().getSoftButtons().elements();
246 while (en.hasMoreElements()) {
247 SoftButton button = (SoftButton) en.nextElement();
248 if (button.getType() == SoftButton.TYPE_ICON
249 && button.getName().equals("up")) {
250 button.setVisible(state);
251 }
252 }
253 }
254
255
256 public Rectangle getDisplayRectangle()
257 {
258 return displayRectangle;
259 }
260
261
262 public Rectangle getDisplayPaintable()
263 {
264 return displayPaintable;
265 }
266
267
268 public Color getBackgroundColor()
269 {
270 return backgroundColor;
271 }
272
273
274 public Color getForegroundColor()
275 {
276 return foregroundColor;
277 }
278
279
280 public Image createImage(int width, int height)
281 {
282 if (width <= 0 || height <= 0) {
283 throw new IllegalArgumentException();
284 }
285
286 return new SwtMutableImage(width, height);
287 }
288
289
290 public Image createImage(String name)
291 throws IOException
292 {
293 return getImage(name);
294 }
295
296
297 public Image createImage(javax.microedition.lcdui.Image source)
298 {
299 if (source.isMutable()) {
300 return new SwtImmutableImage((SwtMutableImage) source);
301 } else {
302 return source;
303 }
304 }
305
306
307 public Image createImage(byte[] imageData, int imageOffset, int imageLength)
308 {
309 ByteArrayInputStream is = new ByteArrayInputStream(imageData, imageOffset, imageLength);
310 try {
311 return getImage(is);
312 } catch (IOException ex) {
313 throw new IllegalArgumentException(ex.toString());
314 }
315 }
316
317 public Image createImage(InputStream is) throws IOException
318 {
319 if (is == null) {
320 throw new IOException();
321 }
322
323 return getImage(is);
324 }
325
326
327 public void setNumAlphaLevels(int i)
328 {
329 numAlphaLevels = i;
330 }
331
332
333
334
335
336
337 public void setNumColors(int i)
338 {
339 numColors = i;
340 }
341
342
343
344
345
346 public void setIsColor(boolean b)
347 {
348 isColor = b;
349 }
350
351
352
353
354
355 public void setBackgroundColor(Color color)
356 {
357 backgroundColor = color;
358 }
359
360
361
362
363
364 public void setForegroundColor(Color color)
365 {
366 foregroundColor = color;
367 }
368
369
370
371
372
373 public void setDisplayRectangle(Rectangle rectangle)
374 {
375 displayRectangle = rectangle;
376 }
377
378
379
380
381
382 public void setDisplayPaintable(Rectangle rectangle)
383 {
384 displayPaintable = rectangle;
385 }
386
387
388
389
390 public void setMode123Image(PositionedImage object)
391 {
392 mode123Image = object;
393 }
394
395
396
397
398
399 public void setModeAbcLowerImage(PositionedImage object)
400 {
401 modeAbcLowerImage = object;
402 }
403
404
405
406
407
408 public void setModeAbcUpperImage(PositionedImage object)
409 {
410 modeAbcUpperImage = object;
411 }
412
413
414 public Image createSystemImage(URL url)
415 throws IOException
416 {
417 return new SwtImmutableImage(SwtDeviceComponent.createImage(url.openStream()));
418 }
419
420
421 private Image getImage(String str)
422 throws IOException
423 {
424
425
426 Object midlet = MIDletBridge.getCurrentMIDlet();
427 if (midlet == null) {
428 midlet = getClass();
429 }
430 InputStream is = midlet.getClass().getResourceAsStream(str);
431
432 if (is == null) {
433 throw new IOException(str + " could not be found.");
434 }
435 try {
436 return getImage(is);
437 } finally {
438 IOUtils.closeQuietly(is);
439 }
440 }
441
442
443 private Image getImage(InputStream is)
444 throws IOException
445 {
446 ImageFilter filter = null;
447 if (isColor()) {
448 filter = new RGBImageFilter();
449 } else {
450 if (numColors() == 2) {
451 filter = new BWImageFilter();
452 } else {
453 filter = new GrayImageFilter();
454 }
455 }
456
457 return new SwtImmutableImage(SwtDeviceComponent.createImage(is, filter));
458 }
459
460
461 public Button createButton(String name, Shape shape, int keyCode, String keyName, Hashtable inputToChars)
462 {
463 return new SwtButton(name, shape, keyCode, keyName, inputToChars);
464 }
465
466
467 public SoftButton createSoftButton(String name, Shape shape, int keyCode, String keyName, Rectangle paintable, String alignmentName, Vector commands, javax.microedition.lcdui.Font font)
468 {
469 return new SwtSoftButton(name, shape, keyCode, keyName, paintable, alignmentName, commands, font);
470 }
471
472
473 public SoftButton createSoftButton(String name, Rectangle paintable, Image normalImage, Image pressedImage)
474 {
475 return new SwtSoftButton(name, paintable, normalImage, pressedImage);
476 }
477
478
479 public Image createRGBImage(int[] rgb, int width, int height, boolean processAlpha)
480 {
481 if (rgb == null)
482 throw new NullPointerException();
483 if (width <= 0 || height <= 0)
484 throw new IllegalArgumentException();
485
486 org.eclipse.swt.graphics.Image img = SwtDeviceComponent.createImage(width, height);
487 ImageData imageData = img.getImageData();
488
489 if (!processAlpha) {
490
491
492
493 int l = rgb.length;
494
495 int [] rgbAux = new int[l];
496 for (int i = 0; i < l; i++)
497 rgbAux[i] = rgb[i] | 0xff000000;
498 rgb = rgbAux;
499 }
500
501
502
503 for (int y = 0; y < height; y++) {
504 imageData.setPixels(0, y, width, rgb, y * width);
505 }
506
507
508 ImageFilter filter = null;
509 if (isColor()) {
510 filter = new RGBImageFilter();
511 } else {
512 if (numColors() == 2) {
513 filter = new BWImageFilter();
514 } else {
515 filter = new GrayImageFilter();
516 }
517 }
518
519 return new SwtImmutableImage(SwtDeviceComponent.createImage(imageData));
520 }
521
522
523 public Image createImage(Image image, int x, int y, int width, int height, int transform)
524 {
525 if (image == null) {
526 throw new NullPointerException();
527 }
528 if (x + width > image.getWidth() || y + height > image.getHeight()
529 || width <= 0 || height <= 0 || x < 0 || y < 0) {
530 throw new IllegalArgumentException("Area out of Image");
531 }
532
533
534 int [] rgbData = new int[height * width];
535 int [] rgbTransformedData = new int[height * width];
536 if (image instanceof SwtImmutableImage) {
537 ((SwtImmutableImage) image).getRGB(rgbData, 0, width, x, y, width, height);
538 } else {
539 ((SwtMutableImage) image).getRGB(rgbData, 0, width, x, y, width, height);
540 }
541
542
543 int colIncr, rowIncr, offset;
544
545 switch(transform) {
546 case Sprite.TRANS_NONE: {
547 offset = 0;
548 colIncr = 1;
549 rowIncr = 0;
550 break;
551 }
552 case Sprite.TRANS_ROT90: {
553 offset = (height - 1) * width;
554 colIncr = -width;
555 rowIncr = (height * width) + 1;
556 int temp = width;
557 width = height;
558 height = temp;
559 break;
560 }
561 case Sprite.TRANS_ROT180: {
562 offset = (height * width) - 1;
563 colIncr = -1;
564 rowIncr = 0;
565 break;
566 }
567 case Sprite.TRANS_ROT270: {
568 offset = width - 1;
569 colIncr = width;
570 rowIncr = -(height * width) - 1;
571 int temp = width;
572 width = height;
573 height = temp;
574 break;
575 }
576 case Sprite.TRANS_MIRROR: {
577 offset = width - 1;
578 colIncr = -1;
579 rowIncr = width << 1;
580 break;
581 }
582 case Sprite.TRANS_MIRROR_ROT90: {
583 offset = (height * width) - 1;
584 colIncr = -width;
585 rowIncr = (height * width) - 1;
586 int temp = width;
587 width = height;
588 height = temp;
589 break;
590 }
591 case Sprite.TRANS_MIRROR_ROT180: {
592 offset = (height - 1) * width;
593 colIncr = 1;
594 rowIncr = -(width << 1);
595 break;
596 }
597 case Sprite.TRANS_MIRROR_ROT270: {
598 offset = 0;
599 colIncr = width;
600 rowIncr = -(height * width) + 1;
601 int temp = width;
602 width = height;
603 height = temp;
604 break;
605 }
606 default:
607 throw new IllegalArgumentException("Bad transform");
608 }
609
610
611 for (int row = 0, i = 0; row < height; row++, offset += rowIncr) {
612 for (int col = 0; col < width; col++, offset += colIncr, i++) {
613 rgbTransformedData[i] = rgbData[offset];
614 }
615 }
616
617 rgbData = null;
618 image = null;
619
620 return createRGBImage(rgbTransformedData, width, height, true);
621 }
622
623 }