1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // Multi-Phasic Applications: SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.runtime
.lcdui
.scritchui
;
12 import cc
.squirreljme
.jvm
.mle
.exceptions
.MLECallError
;
13 import cc
.squirreljme
.jvm
.mle
.scritchui
.NativeScritchInterface
;
14 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchEnvironmentInterface
;
15 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchInterface
;
16 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchScreenInterface
;
17 import cc
.squirreljme
.jvm
.mle
.scritchui
.ScritchWindowInterface
;
18 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchScreenBracket
;
19 import cc
.squirreljme
.jvm
.mle
.scritchui
.brackets
.ScritchWindowBracket
;
20 import cc
.squirreljme
.jvm
.mle
.scritchui
.constants
.ScritchWindowManagerType
;
21 import cc
.squirreljme
.runtime
.cldc
.annotation
.SquirrelJMEVendorApi
;
22 import cc
.squirreljme
.runtime
.cldc
.debug
.Debugging
;
23 import cc
.squirreljme
.runtime
.midlet
.ApplicationHandler
;
24 import java
.util
.ArrayList
;
25 import java
.util
.LinkedHashMap
;
26 import java
.util
.List
;
28 import javax
.microedition
.lcdui
.Display
;
29 import javax
.microedition
.lcdui
.DisplayListener
;
32 * Tracker for displays.
37 public final class DisplayManager
39 /** The number of available desktop windows. */
40 private static final int _DESKTOP_WINDOWS
=
43 /** The instance of the display tracker. */
44 private static volatile DisplayManager _INSTANCE
;
46 /** The ScritchUI interface used. */
48 protected final ScritchInterface scritch
;
50 /** The mapping of displays. */
52 private final Map
<Integer
, DisplayState
> _displays
=
53 new LinkedHashMap
<>();
56 * Initializes the base tracker.
58 * @param __scritch The scritch interface to use.
59 * @throws NullPointerException On null arguments.
62 private DisplayManager(ScritchInterface __scritch
)
63 throws NullPointerException
65 if (__scritch
== null)
66 throw new NullPointerException("NARG");
68 this.scritch
= __scritch
;
72 * Adds a display listener.
74 * @param __dl The display listener to add.
75 * @throws NullPointerException On null arguments.
79 public void displayListenerAdd(DisplayListener __dl
)
80 throws NullPointerException
83 throw new NullPointerException("NARG");
85 throw Debugging
.todo();
89 * Removes the display listener.
91 * @param __dl The display listener to remove.
92 * @throws NullPointerException On null arguments.
96 public void displayListenerRemove(DisplayListener __dl
)
97 throws NullPointerException
100 throw new NullPointerException("NARG");
102 throw Debugging
.todo();
106 * Maps the given set of screens to displays.
108 * @param __factory The factory used for initializing new displays.
109 * @return The resultant displays.
110 * @throws NullPointerException On null arguments.
113 @SquirrelJMEVendorApi
114 public Display
[] mapScreens(DisplayFactory __factory
)
115 throws NullPointerException
117 if (__factory
== null)
118 throw new NullPointerException("NARG");
120 ScritchInterface scritchApi
= this.scritch
;
121 ScritchEnvironmentInterface envApi
= scritchApi
.environment();
122 ScritchScreenInterface screenApi
= scritchApi
.screen();
124 // Are there any actual screens to map?
125 ScritchScreenBracket
[] screens
= envApi
.screens();
126 if (screens
== null || screens
.length
== 0)
127 return new Display
[0];
129 // Resultant displays
130 List
<Display
> result
= new ArrayList
<>();
132 // Depends on the type of window manager being used...
133 switch (envApi
.windowManagerType())
135 // One frame per screen
136 case ScritchWindowManagerType
.ONE_FRAME_PER_SCREEN
:
137 for (ScritchScreenBracket screen
: screens
)
138 result
.add(this.__mapScreen(screenApi
.screenId(screen
),
142 // Frames can share the same screen freely
143 case ScritchWindowManagerType
.STANDARD_DESKTOP
:
144 for (int i
= 0; i
< DisplayManager
._DESKTOP_WINDOWS
; i
++)
145 result
.add(this.__mapScreen(i
, screens
[0], __factory
));
149 // Return any attached screen
150 return result
.toArray(new Display
[result
.size()]);
154 * Returns the ScritchUI interface in use.
156 * @return The ScritchUI interface.
159 @SquirrelJMEVendorApi
160 public ScritchInterface
scritch()
166 * Internally maps a screen.
168 * @param __id The screen ID.
169 * @param __screen The screen to map to.
170 * @param __factory The factory for creating displays.
171 * @return The resultant display, either newly created or cached.
174 private Display
__mapScreen(int __id
, ScritchScreenBracket __screen
,
175 DisplayFactory __factory
)
177 ScritchInterface scritchApi
= this.scritch
;
178 ScritchWindowInterface winApi
= scritchApi
.window();
180 // Map any displays which are not yet mapped
181 Map
<Integer
, DisplayState
> displays
= this._displays
;
183 // Each screen has a unique ID
186 // Could be called from different threads
189 // If the display already exists, use it
190 DisplayState display
= displays
.get(id
);
192 return display
.display();
194 // Setup new window for this display
195 ScritchWindowBracket window
= winApi
.windowNew();
197 // Otherwise it needs to be created
198 display
= __factory
.create(scritchApi
, window
, __screen
);
199 displays
.put(id
, display
);
202 return display
.display();
207 * Obtains the display tracker instance.
209 * @return The tracker for displays.
212 @SquirrelJMEVendorApi
213 public static DisplayManager
instance()
215 DisplayManager instance
= DisplayManager
._INSTANCE
;
216 if (instance
!= null)
219 // Grab from the native system
222 instance
= new DisplayManager(
223 NativeScritchInterface
.nativeInterface());
224 DisplayManager
._INSTANCE
= instance
;
226 catch (MLECallError __e
)
228 throw new HeadlessDisplayException(__e
);
231 // Since we have it now, register idle runner
232 ApplicationHandler
.setIdleTask(new __ExecIdle__(
233 instance
.scritch().eventLoop()));