Jogamp
Fix Window destroyNotify() -> QUIT
[users/sgothel/jake2.git] / src / jake2 / render / opengl / NEWTWin.java
CommitLineData
f5612e7d
SG
1/*
2 * NEWTWin.java
3 * Copyright (C) 2004
4 *
5 */
6package jake2.render.opengl;
7
8import jake2.Defines;
9import jake2.Globals;
10import jake2.SizeChangeListener;
11import jake2.client.VID;
4c41dbb4 12import jake2.game.cvar_t;
f5612e7d 13import jake2.qcommon.Cbuf;
4c41dbb4 14import jake2.qcommon.Cvar;
f5612e7d
SG
15import jake2.render.Base;
16import jake2.sys.NEWTKBD;
17
18import java.util.List;
19
4c41dbb4 20import javax.media.nativewindow.CapabilitiesChooser;
c15865e0 21import javax.media.nativewindow.WindowClosingProtocol.WindowClosingMode;
f5612e7d
SG
22import javax.media.nativewindow.util.Dimension;
23import javax.media.nativewindow.util.DimensionImmutable;
24import javax.media.nativewindow.util.SurfaceSize;
25import javax.media.opengl.GLCapabilities;
0d353c8b 26import javax.media.opengl.GLContext;
f5612e7d
SG
27import javax.media.opengl.GLProfile;
28
29import jogamp.opengl.FPSCounterImpl;
30
fe6a24e2 31import com.jogamp.common.os.Platform;
5611eeb8 32import com.jogamp.newt.*;
f5612e7d
SG
33import com.jogamp.newt.event.WindowAdapter;
34import com.jogamp.newt.event.WindowEvent;
35import com.jogamp.newt.opengl.GLWindow;
5611eeb8 36import com.jogamp.newt.util.MonitorModeUtil;
4c41dbb4 37import com.jogamp.opengl.GenericGLCapabilitiesChooser;
f5612e7d
SG
38
39public class NEWTWin {
5611eeb8 40 MonitorMode oldDisplayMode = null;
f5612e7d
SG
41 volatile Screen screen = null;
42 volatile GLWindow window = null;
c15865e0 43 volatile boolean shouldQuit = false;
f5612e7d
SG
44 final FPSCounterImpl fpsCounter = new FPSCounterImpl();
45
5611eeb8
SG
46 public List<MonitorMode> getModeList() {
47 if( null != window ) {
48 final MonitorDevice mainMonitor = window.getMainMonitor();
49 return mainMonitor.getSupportedModes();
50 } else {
51 return screen.getMonitorModes();
52 }
f5612e7d
SG
53 }
54
5611eeb8
SG
55 public MonitorMode findDisplayMode(DimensionImmutable dim) {
56 final List<MonitorMode> sml = MonitorModeUtil.filterByResolution(getModeList(), dim);
0d353c8b 57 if(sml.size() == 0) {
f5612e7d
SG
58 return oldDisplayMode;
59 }
60 return sml.get(0);
61 }
62
5611eeb8 63 public String getModeString(MonitorMode mm) {
f5612e7d
SG
64 final SurfaceSize ss = mm.getSurfaceSize();
65 final DimensionImmutable m = ss.getResolution();
66 final StringBuffer sb = new StringBuffer();
67 sb.append(m.getWidth());
68 sb.append('x');
69 sb.append(m.getHeight());
70 sb.append('x');
71 sb.append(ss.getBitsPerPixel());
72 sb.append('@');
73 sb.append(mm.getRefreshRate());
74 sb.append("Hz");
75 return sb.toString();
76 }
77
78 /**
79 * @param dim
80 * @param mode
81 * @param fullscreen
04d63492 82 * @param driverName TODO
f5612e7d
SG
83 * @return enum Base.rserr_t
84 */
04d63492 85 public int setMode(GLProfile glp, Dimension dim, int mode, boolean fullscreen, String driverName) {
fe6a24e2 86 final boolean isARM = Platform.CPUFamily.ARM == Platform.getCPUFamily();
f5612e7d
SG
87
88 final Dimension newDim = new Dimension();
89
0d353c8b 90 VID.Printf(Defines.PRINT_ALL, "Initializing OpenGL display for profile "+glp+"\n");
f5612e7d 91
f5612e7d
SG
92 if(null == screen) {
93 screen = NewtFactory.createScreen(NewtFactory.createDisplay(null), 0);
94 screen.addReference(); // trigger native creation
5c21146b
SG
95 } else if( !screen.isNativeValid() ) {
96 screen.addReference(); // trigger native creation
f5612e7d
SG
97 }
98
99 if (!VID.GetModeInfo(newDim, mode)) {
100 VID.Printf(Defines.PRINT_ALL, " invalid mode\n");
101 return Base.rserr_invalid_mode;
102 }
103
0d353c8b 104 VID.Printf(Defines.PRINT_ALL, "...setting mode " + mode + ", " + newDim.getWidth() + " x " + newDim.getHeight() + ", fs " + fullscreen + ", driver " + driverName + "\n");
f5612e7d 105
0d353c8b
SG
106 // destroy the existing window, not screen
107 shutdownImpl(false);
f5612e7d 108
0d353c8b
SG
109 if(null != window) {
110 throw new InternalError("XXX");
f5612e7d 111 }
0d353c8b
SG
112 final GLCapabilities caps = new GLCapabilities(glp);
113 CapabilitiesChooser chooser = null; // default
114 {
115 final cvar_t v = Cvar.Get("jogl_rgb565", "0", 0);
116 if( v.value != 0f ) {
117 caps.setRedBits(5);
118 caps.setGreenBits(6);
119 caps.setBlueBits(5);
120 chooser = new GenericGLCapabilitiesChooser(); // don't trust native GL-TK chooser
121 }
f5612e7d 122 }
0d353c8b 123 window = GLWindow.create(screen, caps);
c15865e0 124 window.setDefaultCloseOperation(WindowClosingMode.DO_NOTHING_ON_CLOSE); // we do handle QUIT on our own, no GLWindow.display() called.
0d353c8b 125 window.setCapabilitiesChooser(chooser);
f5612e7d
SG
126 window.addWindowListener(new WindowAdapter() {
127 public void windowDestroyNotify(WindowEvent e) {
c15865e0 128 shouldQuit = !Globals.appletMode && null != window; // not applet and not already in shutdown ?
f5612e7d
SG
129 }
130
131 public void windowResized(WindowEvent e) {
0d353c8b 132 propagateNewSize();
f5612e7d
SG
133 }
134 });
0d353c8b 135 window.setTitle("Jake2 ("+driverName+"-newt-"+glp.getName().toLowerCase()+")");
f5612e7d 136
5611eeb8
SG
137 final MonitorDevice mainMonitor = window.getMainMonitor();
138
0d353c8b 139 if (oldDisplayMode == null) {
5611eeb8 140 oldDisplayMode = mainMonitor.getCurrentMode();
f5612e7d
SG
141 }
142
143 // We need to feed the NEWT Window to the NEWTKBD
144 NEWTKBD.Init(window);
145
f5612e7d
SG
146 window.addWindowListener(NEWTKBD.listener);
147 window.addKeyListener(NEWTKBD.listener);
148 window.addMouseListener(NEWTKBD.listener);
149
150 if (fullscreen) {
5611eeb8
SG
151 MonitorMode mm = findDisplayMode(newDim);
152 final DimensionImmutable smDim = mm.getSurfaceSize().getResolution();
f5612e7d
SG
153 newDim.setWidth( smDim.getWidth() );
154 newDim.setHeight( smDim.getHeight() );
5611eeb8 155 mainMonitor.setCurrentMode(mm);
f5612e7d 156 window.setFullscreen(true);
f5612e7d 157 } else {
0d353c8b
SG
158 window.setSize(newDim.getWidth(), newDim.getHeight());
159 if (Globals.appletMode) {
f5612e7d
SG
160 // Notify the size listener about the change
161 final SizeChangeListener listener = Globals.sizeChangeListener;
162 if (listener != null) {
163 listener.sizeChanged(newDim.getWidth(), newDim.getHeight());
164 }
165 }
166 }
0d353c8b 167 window.setVisible(true);
f5612e7d
SG
168
169 if (!Globals.appletMode) {
170 while ( !window.isNativeValid()|| !window.isRealized() ) {
171 try {
172 Thread.sleep(100);
173 } catch (InterruptedException e) {}
174 }
175 }
176 window.requestFocus();
177 window.display(); // force GL resource validation
953acae5 178 window.setAutoSwapBufferMode(false);
0d353c8b 179
fe6a24e2
SG
180 VID.Printf(Defines.PRINT_ALL, "...reques GLCaps "+window.getRequestedCapabilities()+'\n');
181 VID.Printf(Defines.PRINT_ALL, "...chosen GLCaps "+window.getChosenGLCapabilities()+'\n');
0d353c8b 182 VID.Printf(Defines.PRINT_ALL, "...size "+window.getWidth()+" x "+window.getHeight()+'\n');
fe6a24e2 183 fpsCounter.setUpdateFPSFrames(isARM ? 60 : 4*60, System.err);
f5612e7d 184
0d353c8b
SG
185 // propagateNewSize("init");
186 activateGLContext();
187
f5612e7d
SG
188 return Base.rserr_ok;
189 }
0d353c8b
SG
190
191 private void propagateNewSize() {
192 final int width = window.getWidth();
193 final int height = window.getHeight();
194 final int _width;
195 final int mask = ~0x03;
196 if ((width & 0x03) != 0) {
197 _width = ( width & mask ) + 4;
198 } else {
199 _width = width;
200 }
201 VID.Printf(Defines.PRINT_ALL, "Resize: " + width + " x " + height + ", masked " + _width + "x" + height + "\n");
f5612e7d 202
0d353c8b
SG
203 Base.setVid(_width, height);
204 // let the sound and input subsystems know about the new window
205 VID.NewWindow(_width, height);
206 }
207
208 protected final void activateGLContext() {
209 final GLContext ctx = window.getContext();
210 if ( null != ctx && GLContext.getCurrent() != ctx ) {
211 ctx.makeCurrent();
212 }
213 }
214
215 protected final void deactivateGLContext() {
216 final GLContext ctx = window.getContext();
217 if ( null != ctx && GLContext.getCurrent() == ctx) {
218 ctx.release();
219 }
220 }
221
c15865e0
SG
222 /** Performs {@link GLWindow#swapBuffers()}, ticks the fps counter and performs <code>QUIT</code> if requested. */
223 public final void endFrame() {
224 window.swapBuffers();
225 fpsCounter.tickFPS();
226 if( shouldQuit ) {
227 deactivateGLContext();
228 Cbuf.ExecuteText(Defines.EXEC_APPEND, "quit");
229 }
230 }
231 /** Performs <code>QUIT</code> if requested. */
232 public final void checkQuit() {
233 if( shouldQuit ) {
234 deactivateGLContext();
235 Cbuf.ExecuteText(Defines.EXEC_APPEND, "quit");
236 }
237 }
238
f5612e7d 239 void shutdown() {
0d353c8b
SG
240 shutdownImpl(true);
241 }
242
243 private void shutdownImpl(boolean withScreen) {
244 if ( null != window ) {
245 deactivateGLContext();
5611eeb8 246 final GLWindow _window = window;
0d353c8b 247 window = null;
5611eeb8 248 _window.destroy(); // same thing
0d353c8b
SG
249 }
250 if( withScreen && null != screen ) {
251 screen.destroy();
252 screen = null;
f5612e7d 253 }
f5612e7d
SG
254 }
255
256}
http://JogAmp.org git info: FAQ, tutorial and man pages.