Move some System.err to Debugging.debugNote.
[SquirrelJME.git] / modules / midp-lcdui / src / main / java / cc / squirreljme / runtime / lcdui / scritchui / DisplayManager.java
blob33b2de7c7dfbce1dd9e5b730056cd1e812a64c34
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;
27 import java.util.Map;
28 import javax.microedition.lcdui.Display;
29 import javax.microedition.lcdui.DisplayListener;
31 /**
32 * Tracker for displays.
34 * @since 2024/03/09
36 @SquirrelJMEVendorApi
37 public final class DisplayManager
39 /** The number of available desktop windows. */
40 private static final int _DESKTOP_WINDOWS =
41 16;
43 /** The instance of the display tracker. */
44 private static volatile DisplayManager _INSTANCE;
46 /** The ScritchUI interface used. */
47 @SquirrelJMEVendorApi
48 protected final ScritchInterface scritch;
50 /** The mapping of displays. */
51 @SquirrelJMEVendorApi
52 private final Map<Integer, DisplayState> _displays =
53 new LinkedHashMap<>();
55 /**
56 * Initializes the base tracker.
58 * @param __scritch The scritch interface to use.
59 * @throws NullPointerException On null arguments.
60 * @since 2024/03/09
62 private DisplayManager(ScritchInterface __scritch)
63 throws NullPointerException
65 if (__scritch == null)
66 throw new NullPointerException("NARG");
68 this.scritch = __scritch;
71 /**
72 * Adds a display listener.
74 * @param __dl The display listener to add.
75 * @throws NullPointerException On null arguments.
76 * @since 2024/03/09
78 @SquirrelJMEVendorApi
79 public void displayListenerAdd(DisplayListener __dl)
80 throws NullPointerException
82 if (__dl == null)
83 throw new NullPointerException("NARG");
85 throw Debugging.todo();
88 /**
89 * Removes the display listener.
91 * @param __dl The display listener to remove.
92 * @throws NullPointerException On null arguments.
93 * @since 2024/03/09
95 @SquirrelJMEVendorApi
96 public void displayListenerRemove(DisplayListener __dl)
97 throws NullPointerException
99 if (__dl == null)
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.
111 * @since 2024/03/09
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),
139 screen, __factory));
140 break;
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));
146 break;
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.
157 * @since 2024/03/09
159 @SquirrelJMEVendorApi
160 public ScritchInterface scritch()
162 return this.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.
172 * @since 2024/04/07
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
184 Integer id = __id;
186 // Could be called from different threads
187 synchronized (this)
189 // If the display already exists, use it
190 DisplayState display = displays.get(id);
191 if (display != null)
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);
201 // Use this display
202 return display.display();
207 * Obtains the display tracker instance.
209 * @return The tracker for displays.
210 * @since 2024/03/09
212 @SquirrelJMEVendorApi
213 public static DisplayManager instance()
215 DisplayManager instance = DisplayManager._INSTANCE;
216 if (instance != null)
217 return instance;
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()));
235 // Use it!
236 return instance;