Source code: com/barteo/emulator/device/swt/SwtDevice.java
1 /*
2 * MicroEmulator
3 * Copyright (C) 2002 Bartek Teodorczyk <barteo@it.pl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package com.barteo.emulator.device.swt;
21
22 import java.io.BufferedReader;
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.util.Enumeration;
28 import java.util.Vector;
29
30 import javax.microedition.lcdui.Canvas;
31
32 import nanoxml.XMLElement;
33 import nanoxml.XMLParseException;
34
35 import org.eclipse.swt.SWT;
36 import org.eclipse.swt.graphics.Image;
37 import org.eclipse.swt.graphics.RGB;
38 import org.eclipse.swt.graphics.Rectangle;
39
40 import com.barteo.emulator.EmulatorContext;
41 import com.barteo.emulator.app.ui.swt.ImageFilter;
42 import com.barteo.emulator.app.ui.swt.SwtDeviceComponent;
43 import com.barteo.emulator.device.Device;
44 import com.barteo.emulator.device.DeviceDisplay;
45 import com.barteo.emulator.device.FontManager;
46 import com.barteo.emulator.device.InputMethod;
47
48
49 public class SwtDevice implements Device
50 {
51 private EmulatorContext context;
52
53 private SwtDeviceDisplay deviceDisplay;
54 private FontManager fontManager = null;
55 private SwtInputMethod inputMethod = null;
56 private Vector buttons;
57 private Vector softButtons;
58
59 private Image normalImage;
60 private Image overImage;
61 private Image pressedImage;
62
63
64 public SwtDevice()
65 {
66 }
67
68
69 public void init(EmulatorContext context)
70 {
71 // Here should be device.xml but Netscape security manager doesn't accept this extension
72 init(context, "/com/barteo/emulator/device/device.txt");
73 }
74
75
76 public void init(EmulatorContext context, String config)
77 {
78 this.context = context;
79
80 deviceDisplay = new SwtDeviceDisplay(this);
81 buttons = new Vector();
82 softButtons = new Vector();
83
84 try {
85 loadConfig(config);
86 } catch (IOException ex) {
87 System.out.println("Cannot load config: " + ex);
88 }
89 }
90
91
92 public javax.microedition.lcdui.Image createImage(int width, int height)
93 {
94 if (width <= 0 || height <= 0) {
95 throw new IllegalArgumentException();
96 }
97
98 return new SwtMutableImage(width, height);
99 }
100
101
102 public javax.microedition.lcdui.Image createImage(String name)
103 throws IOException
104 {
105 return new SwtImmutableImage(getImage(name));
106 }
107
108
109 public javax.microedition.lcdui.Image createImage(javax.microedition.lcdui.Image source)
110 {
111 if (source.isMutable()) {
112 return new SwtImmutableImage((SwtMutableImage) source);
113 } else {
114 return source;
115 }
116 }
117
118
119 public javax.microedition.lcdui.Image createImage(byte[] imageData, int imageOffset, int imageLength)
120 {
121 ByteArrayInputStream is = new ByteArrayInputStream(imageData, imageOffset, imageLength);
122 try {
123 return new SwtImmutableImage(getImage(is));
124 } catch (IOException ex) {
125 throw new IllegalArgumentException(ex.toString());
126 }
127 }
128
129
130 public EmulatorContext getEmulatorContext()
131 {
132 return context;
133 }
134
135
136 public DeviceDisplay getDeviceDisplay()
137 {
138 return deviceDisplay;
139 }
140
141
142 public FontManager getFontManager()
143 {
144 if (fontManager == null) {
145 fontManager = new SwtFontManager();
146 }
147
148 return fontManager;
149 }
150
151
152 public InputMethod getInputMethod()
153 {
154 if (inputMethod == null) {
155 inputMethod = new SwtInputMethod();
156 }
157
158 return inputMethod;
159 }
160
161
162 public int getGameAction(int keyCode)
163 {
164 // TODO poprawic KeyEvent
165 switch (keyCode) {
166 case SWT.ARROW_UP:
167 return Canvas.UP;
168
169 case SWT.ARROW_DOWN:
170 return Canvas.DOWN;
171
172 case SWT.ARROW_LEFT:
173 return Canvas.LEFT;
174
175 case SWT.ARROW_RIGHT:
176 return Canvas.RIGHT;
177
178 case SWT.CR:
179 return Canvas.FIRE;
180
181 /* case KeyEvent.VK_1:
182 case KeyEvent.VK_A:
183 return Canvas.GAME_A;
184
185 case KeyEvent.VK_3:
186 case KeyEvent.VK_B:
187 return Canvas.GAME_B;
188
189 case KeyEvent.VK_7:
190 case KeyEvent.VK_C:
191 return Canvas.GAME_C;
192
193 case KeyEvent.VK_9:
194 case KeyEvent.VK_D:
195 return Canvas.GAME_D;*/
196
197 default:
198 return 0;
199 }
200 }
201
202
203 public int getKeyCode(int gameAction)
204 {
205 // TODO poprawic KeyEvent
206 switch (gameAction) {
207 case Canvas.UP:
208 return SWT.ARROW_UP;
209
210 case Canvas.DOWN:
211 return SWT.ARROW_DOWN;
212
213 case Canvas.LEFT:
214 return SWT.ARROW_LEFT;
215
216 case Canvas.RIGHT:
217 return SWT.ARROW_RIGHT;
218
219 case Canvas.FIRE:
220 return SWT.CR;
221
222 /* case Canvas.GAME_A:
223 return KeyEvent.VK_1;
224
225 case Canvas.GAME_B:
226 return KeyEvent.VK_3;
227
228 case Canvas.GAME_C:
229 return KeyEvent.VK_7;
230
231 case Canvas.GAME_D:
232 return KeyEvent.VK_9;*/
233
234 default:
235 throw new IllegalArgumentException();
236 }
237 }
238
239
240 public Vector getSoftButtons()
241 {
242 return softButtons;
243 }
244
245
246 public Image getNormalImage()
247 {
248 return normalImage;
249 }
250
251
252 public Image getOverImage()
253 {
254 return overImage;
255 }
256
257
258 public Image getPressedImage()
259 {
260 return pressedImage;
261 }
262
263
264 public boolean hasPointerMotionEvents()
265 {
266 return false;
267 }
268
269
270 public boolean hasPointerEvents()
271 {
272 return false;
273 }
274
275
276 public boolean hasRepeatEvents()
277 {
278 return false;
279 }
280
281
282 public void dispose()
283 {
284 inputMethod.dispose();
285 inputMethod = null;
286 }
287
288
289 public Vector getButtons()
290 {
291 return buttons;
292 }
293
294
295 public void loadConfig(String config)
296 throws IOException
297 {
298 String readLine;
299 StringBuffer xmlBuffer = new StringBuffer();
300 BufferedReader dis = new BufferedReader(
301 new InputStreamReader(getClass().getResourceAsStream(config)));
302 while ((readLine = dis.readLine()) != null) {
303 xmlBuffer.append(readLine);
304 }
305
306 XMLElement doc = new XMLElement();
307 try {
308 doc.parseString(xmlBuffer.toString());
309 } catch (XMLParseException ex) {
310 throw new IOException(ex.toString());
311 }
312
313 for (Enumeration e = doc.enumerateChildren(); e.hasMoreElements(); ) {
314 XMLElement tmp = (XMLElement) e.nextElement();
315 if (tmp.getName().equals("img")) {
316 try {
317 if (tmp.getStringAttribute("name").equals("normal")) {
318 normalImage = getSystemImage(tmp.getStringAttribute("src"));
319 } else if (tmp.getStringAttribute("name").equals("over")) {
320 overImage = getSystemImage(tmp.getStringAttribute("src"));
321 } else if (tmp.getStringAttribute("name").equals("pressed")) {
322 pressedImage = getSystemImage(tmp.getStringAttribute("src"));
323 }
324 } catch (IOException ex) {
325 System.out.println("Cannot load " + tmp.getStringAttribute("src"));
326 return;
327 }
328 } else if (tmp.getName().equals("display")) {
329 for (Enumeration e_display = tmp.enumerateChildren(); e_display.hasMoreElements(); ) {
330 XMLElement tmp_display = (XMLElement) e_display.nextElement();
331 if (tmp_display.getName().equals("numcolors")) {
332 deviceDisplay.numColors = Integer.parseInt(tmp_display.getContent());
333 } else if (tmp_display.getName().equals("iscolor")) {
334 deviceDisplay.isColor = parseBoolean(tmp_display.getContent());
335 } else if (tmp_display.getName().equals("background")) {
336 int color = Integer.parseInt(tmp_display.getContent(), 16);
337 deviceDisplay.backgroundColor =
338 SwtDeviceComponent.createColor(
339 new RGB((color >> 16) % 256, (color >> 8) % 256, color % 256));
340 } else if (tmp_display.getName().equals("foreground")) {
341 int color = Integer.parseInt(tmp_display.getContent(), 16);
342 deviceDisplay.foregroundColor =
343 SwtDeviceComponent.createColor(
344 new RGB((color >> 16) % 256, (color >> 8) % 256, color % 256));
345 } else if (tmp_display.getName().equals("rectangle")) {
346 deviceDisplay.displayRectangle = getRectangle(tmp_display);
347 } else if (tmp_display.getName().equals("paintable")) {
348 deviceDisplay.displayPaintable = getRectangle(tmp_display);
349 }
350 }
351 for (Enumeration e_display = tmp.enumerateChildren(); e_display.hasMoreElements(); ) {
352 XMLElement tmp_display = (XMLElement) e_display.nextElement();
353 if (tmp_display.getName().equals("img")) {
354 if (tmp_display.getStringAttribute("name").equals("up")) {
355 deviceDisplay.upImage = new PositionedImage(
356 getImage(tmp_display.getStringAttribute("src")),
357 getRectangle(getElement(tmp_display, "paintable")));
358 } else if (tmp_display.getStringAttribute("name").equals("down")) {
359 deviceDisplay.downImage = new PositionedImage(
360 getImage(tmp_display.getStringAttribute("src")),
361 getRectangle(getElement(tmp_display, "paintable")));
362 } else if (tmp_display.getStringAttribute("name").equals("mode")) {
363 if (tmp_display.getStringAttribute("type").equals("123")) {
364 deviceDisplay.mode123Image = new PositionedImage(
365 getImage(tmp_display.getStringAttribute("src")),
366 getRectangle(getElement(tmp_display, "paintable")));
367 } else if (tmp_display.getStringAttribute("type").equals("abc")) {
368 deviceDisplay.modeAbcLowerImage = new PositionedImage(
369 getImage(tmp_display.getStringAttribute("src")),
370 getRectangle(getElement(tmp_display, "paintable")));
371 } else if (tmp_display.getStringAttribute("type").equals("ABC")) {
372 deviceDisplay.modeAbcUpperImage = new PositionedImage(
373 getImage(tmp_display.getStringAttribute("src")),
374 getRectangle(getElement(tmp_display, "paintable")));
375 }
376 }
377 }
378 }
379 } else if (tmp.getName().equals("keyboard")) {
380 for (Enumeration e_keyboard = tmp.enumerateChildren(); e_keyboard.hasMoreElements(); ) {
381 XMLElement tmp_keyboard = (XMLElement) e_keyboard.nextElement();
382 if (tmp_keyboard.getName().equals("button")) {
383 Rectangle rectangle = null;
384 Vector stringArray = new Vector();
385 for (Enumeration e_button = tmp_keyboard.enumerateChildren(); e_button.hasMoreElements(); ) {
386 XMLElement tmp_button = (XMLElement) e_button.nextElement();
387 if (tmp_button.getName().equals("chars")) {
388 for (Enumeration e_chars = tmp_button.enumerateChildren(); e_chars.hasMoreElements(); ) {
389 XMLElement tmp_chars = (XMLElement) e_chars.nextElement();
390 if (tmp_chars.getName().equals("char")) {
391 stringArray.addElement(tmp_chars.getContent());
392 }
393 }
394 } else if (tmp_button.getName().equals("rectangle")) {
395 rectangle = getRectangle(tmp_button);
396 }
397 }
398 char[] charArray = new char[stringArray.size()];
399 for (int i = 0; i < stringArray.size(); i++) {
400 String str = (String) stringArray.elementAt(i);
401 if (str.length() > 0) {
402 charArray[i] = str.charAt(0);
403 } else {
404 charArray[i] = ' ';
405 }
406 }
407 buttons.addElement(new SwtButton(tmp_keyboard.getStringAttribute("name"),
408 rectangle, tmp_keyboard.getStringAttribute("key"), charArray));
409 } else if (tmp_keyboard.getName().equals("softbutton")) {
410 Vector commands = new Vector();
411 Rectangle rectangle = null, paintable = null;
412 for (Enumeration e_button = tmp_keyboard.enumerateChildren(); e_button.hasMoreElements(); ) {
413 XMLElement tmp_button = (XMLElement) e_button.nextElement();
414 if (tmp_button.getName().equals("rectangle")) {
415 rectangle = getRectangle(tmp_button);
416 } else if (tmp_button.getName().equals("paintable")) {
417 paintable = getRectangle(tmp_button);
418 } else if (tmp_button.getName().equals("command")) {
419 commands.addElement(tmp_button.getContent());
420 }
421 }
422 SwtSoftButton button = new SwtSoftButton(tmp_keyboard.getStringAttribute("name"),
423 rectangle, tmp_keyboard.getStringAttribute("key"), paintable,
424 tmp_keyboard.getStringAttribute("alignment"), commands);
425 buttons.addElement(button);
426 softButtons.addElement(button);
427 }
428 }
429 }
430 }
431 }
432
433
434 private XMLElement getElement(XMLElement source, String name)
435 {
436 for (Enumeration e_content = source.enumerateChildren(); e_content.hasMoreElements(); ) {
437 XMLElement tmp_content = (XMLElement) e_content.nextElement();
438 if (tmp_content.getName().equals(name)) {
439 return tmp_content;
440 }
441 }
442
443 return null;
444 }
445
446
447 private Rectangle getRectangle(XMLElement source)
448 {
449 Rectangle rect = new Rectangle(0, 0, 0, 0);
450
451 for (Enumeration e_rectangle = source.enumerateChildren(); e_rectangle.hasMoreElements(); ) {
452 XMLElement tmp_rectangle = (XMLElement) e_rectangle.nextElement();
453 if (tmp_rectangle.getName().equals("x")) {
454 rect.x = Integer.parseInt(tmp_rectangle.getContent());
455 } else if (tmp_rectangle.getName().equals("y")) {
456 rect.y = Integer.parseInt(tmp_rectangle.getContent());
457 } else if (tmp_rectangle.getName().equals("width")) {
458 rect.width = Integer.parseInt(tmp_rectangle.getContent());
459 } else if (tmp_rectangle.getName().equals("height")) {
460 rect.height = Integer.parseInt(tmp_rectangle.getContent());
461 }
462 }
463
464 return rect;
465 }
466
467
468 private boolean parseBoolean(String value)
469 {
470 if (value.toLowerCase().equals(new String("true").toLowerCase())) {
471 return true;
472 } else {
473 return false;
474 }
475 }
476
477
478 private Image getSystemImage(String str)
479 throws IOException
480 {
481 InputStream is;
482
483 is = getClass().getResourceAsStream(str);
484 if (is == null) {
485 throw new IOException();
486 }
487
488 return SwtDeviceComponent.createImage(is);
489 }
490
491
492 private Image getImage(String str)
493 throws IOException
494 {
495 InputStream is = getEmulatorContext().getClassLoader().getResourceAsStream(str);
496
497 if (is == null) {
498 throw new IOException(str + " could not be found.");
499 }
500
501 return getImage(is);
502 }
503
504
505 private Image getImage(InputStream is)
506 throws IOException
507 {
508 ImageFilter filter = null;
509 if (getDeviceDisplay().isColor()) {
510 filter = new RGBImageFilter();
511 } else {
512 if (getDeviceDisplay().numColors() == 2) {
513 filter = new BWImageFilter();
514 } else {
515 filter = new GrayImageFilter();
516 }
517 }
518
519 return SwtDeviceComponent.createImage(is, filter);
520 }
521
522 }