Exiting the JVM and FSEM

Hi all,

I am having a little trouble getting FSEM to work the way I think it should work. (My expectations might be to blame, but I don’t think so.)

The game client allows the user to toggle back and forth between FSEM and windowed modes. But when I exit the JVM using System.exit(0), the screen does that funny thing that it does when it switches into one mode or the other (I don’t know exactly what’s going on underneath the hood, but you know–screen goes black, things flash around a bit, then the mode is switched). That would be fine except that this happens even if the app is already in windowed mode when I exit the game. If the game is already in windowed mode, shouldn’t it just exit as if I’d never entered FSEM in the first place?

(I’ve checked the logic, and there is no duplicate call to GraphicsDevice.setFullScreenWindow()… so that’s not it.)

I tried Thread.sleep()-ing for five seconds before the exit, thinking that maybe the System.exit(0) was abruptly preventing some other thread from completing. That did not make a difference. After the five seconds, the System.exit(0) got called, and then the screen turned black, flashed, and went into windowed mode on exit (even though it was already in windowed mode).

Thanks,
Willie

p.s. If I start the client with FSEM turned off, and never enter FSEM, then when I finally System.exit(0), the exit is perfectly standard. No flashing screen or anything like that. It is only if I went into FSEM during the game. I figure that there is something I am not cleaning up properly when I switch from FSEM to windowed mode, and so when the JVM exits, it does the entire cleanup for me. That is just a guess, but I am hoping somebody will have some insight.

Try exiting the full screen first by calling setFullScreenWindow(null).

Hi Trembovetski,

Thanks for the reply. I am doing that. So people don’t have to wonder about the code, here is code that illustrates the problem:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test implements ActionListener {
      private GraphicsEnvironment                  ge;
      private GraphicsDevice                        gd;
      private DisplayMode                              origDispMode;
      private DisplayMode                              newDispMode;

      private JFrame                                    frame;
      private JButton                                    fsemButton;
      private JButton                                    windowedButton;
      private JButton                                    exitButton;

      public static void main(String[] args) { new Test(); }

      public Test() {

            // Prepare for FSEM
            this.ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            this.gd = ge.getDefaultScreenDevice();
            this.origDispMode = gd.getDisplayMode();
            this.newDispMode =
                  new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN);

            // Build the frame
            this.frame = new JFrame("Test");
            frame.setSize(800, 600);

            this.fsemButton = new JButton("FSEM");
            this.windowedButton = new JButton("Windowed");
            this.exitButton = new JButton("Exit");

            fsemButton.addActionListener(this);
            windowedButton.addActionListener(this);
            exitButton.addActionListener(this);

            Container c = frame.getContentPane();
            c.setLayout(new FlowLayout());
            c.add(fsemButton);
            c.add(windowedButton);
            c.add(exitButton);

            // Show the frame.
            frame.show();
      }

      public void actionPerformed(ActionEvent e) {
            Object src = e.getSource();
            if (src == fsemButton) {
                  gd.setFullScreenWindow(frame);
                  gd.setDisplayMode(newDispMode);
            } else if (src == windowedButton) {
                  gd.setDisplayMode(origDispMode);
                  gd.setFullScreenWindow(null);
            } else if (src == exitButton) {
                  System.exit(0);
            }
      }
}

To see what I am talking about, run the program. First press FSEM, then press Windowed, then press Exit. FSEM should enter into FSEM. Windowed should return to Windowed. Exit should exit the JVM. On my system, pressing Exit does the screen flash thing again, which I would not expect.

(Disclaimer: I know that the code above has other problems, such as not checking for windowed mode before trying to enter windowed mode. I’ve suppressed all such checks in the interest of making the problem very clear.)

Thanks,
Willie

Willie,

I ran your code and it worked ok for me. I switched to FS (monitor click & flash), switched back to windowed (monitor click & flash), then exited (nothing, clean exit).

Only thing I noticed is that your frame is still decorated in FS. There are other problems, as you mentioned, but for isolating your issue, I couldn’t reproduce it.

Hi Stanky. Thanks for trying that out. That report is very useful. I will try playing with my video card settings, and try it out on another machine as well.

As to the frame–yeah, in the real game the frame is decorated only in windowed mode. I just wanted to keep the code simple.

Thanks again!

OK, now I see what you’re saying but I can’t reproduce the problem (WinXP, SiS630 video), 1.5beta1.

It looks like it’s some kind of drivers/video board weirdness.

What OS, video board, driver version, DX version, and jdk version are you using?

As usual, it pays to have the latest drivers, and try it on the latest jdk available (1.5beta1 at this point).

What OS, video board, driver version, DX version, and > jdk version are you using?

Yeah, good idea about updating JDK and drivers. I’m on Win XP Pro, with a NVidia GeForce2 Go video card. The driver is nv4_disp.dll 6.14.10.4482, DirectX v9.0, and JDK 1.4.2. I have another machine too that I can try this out on, with a Radeon card.

Thanks again for the help and ideas.

Another thing - try running the app with -Dsun.java2d.d3d=false, just to see if it helps.

Hey man, updating my driver seems to have helped out. The little test program I wrote now has a much different behavior: when I hit exit, it just leaves me in the low-res display mode, and doesn’t try to do anything. I think that’s progress. Lemme try fixing the test program just slightly more. Thanks again for all of your good ideas.

Everything is working much better with the new driver. Thanks!

when i hit exit it doesnt leave me in low res mode, it puts the screen back how it was before i went full screen. i get a clean exit if i have changed back to windowed before closing.

hope this helps some, it wouldnt hurt to just have the program remember what display mode it was on before exiting though it may fix your problem and create new problems on other systems.