LWJGL as an JNLP Extension

It is currently necessary to sign the application as well as the libraries when using LWJGL as a JNLP extension. This will be inconvenient for the LWJGL16k competition as signing the jar expands its size by about 1.5k

As a temporary workaround, I have created the following utility class, which should be put in a signed jar and used as a JNLP extension. It duplicates the problematic methods in org.lwjgl.opengl.Display & org.lwjgl.util.Display with a security wrapper.

This will make it easier to demonstrate that the unsigned jar is no more then 16k when distributed with webstart.

Alan

/*
 * Display.java
 *
 * Created on 29 May 2005, 06:40
 */
package util;

import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.opengl.Drawable;

/** This wraps key methods of the two LWJGL Display classes to allow
    LWJGL to work as a JNLP Extension. */
public final class Display {
    
    /** Creates a new instance of Display */
    public Display() {
    }

    // Wrapping key methods from org.lwjgl.opengl.Display

    /** Create the OpenGL context.*/
    public static void create() throws org.lwjgl.LWJGLException {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.create();
                        return null;
                    } 
                });         
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Create the OpenGL context with the given minimum parameters. */
    public static void create(PixelFormat pixel_format)
        throws org.lwjgl.LWJGLException {
        final PixelFormat fpixel_format = pixel_format; 
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.create(fpixel_format);
                        return null;
                    } 
                });         
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }
    
    /** Create the OpenGL context with the given minimum parameters. */
    public static void create(PixelFormat pixel_format,
        Drawable shared_drawable) throws org.lwjgl.LWJGLException {
        final PixelFormat fpixel_format = pixel_format;
        final Drawable fshared_drawable = shared_drawable;
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.create(
                            fpixel_format,fshared_drawable);
                        return null;
                    } 
                });         
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Returns the entire list of possible fullscreen display modes
        as an array, in no particular order.*/
    public static DisplayMode[] getAvailableDisplayModes()
        throws org.lwjgl.LWJGLException {
        try {
            final Object fmodes = AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        return org.lwjgl.opengl.Display.getAvailableDisplayModes();
                    } 
                }); 
            return (DisplayMode[])fmodes;    
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Make the Display the current rendering context for GL calls. */
    public static void makeCurrent() throws org.lwjgl.LWJGLException {
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.makeCurrent();
                        return null;
                    } 
                });         
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Set the display configuration to the specified gamma,
        brightness and contrast. */
    public static void setDisplayConfiguration(
        float gamma, float brightness, float contrast) 
        throws org.lwjgl.LWJGLException {
        final float fgamma = gamma;
        final float fbrightness = brightness;
        final float fcontrast = contrast;
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.setDisplayConfiguration(
                            fgamma, fbrightness, fcontrast);
                        return null;
                    } 
                });         
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Set the current display mode */
    public static void setDisplayMode(DisplayMode mode)
        throws org.lwjgl.LWJGLException {
        final DisplayMode fmode = mode;
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                       org.lwjgl.opengl.Display.setDisplayMode(fmode);
                       return null;
                    } 
                });            
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }

    /** Set the fullscreen mode of the context. */
    public static void setFullscreen(boolean fullscreen)
        throws org.lwjgl.LWJGLException {
        final boolean ffullscreen = fullscreen;
        try {
            AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                        org.lwjgl.opengl.Display.setFullscreen(ffullscreen);
                        return null;
                    } 
                });                 
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }
    
    // Wrapping key methods from org.lwjgl.util.Display
    
    /** Determine the available display modes that match
        the specified minimum and maximum criteria. */
    public static DisplayMode[] getAvailableDisplayModes(
        int minWidth, int minHeight, int maxWidth, int maxHeight,
        int minBPP, int maxBPP, int minFreq, int maxFreq)
        throws org.lwjgl.LWJGLException {
        final int fminWidth = minWidth;
        final int fminHeight = minHeight;
        final int fmaxWidth = maxWidth;
        final int fmaxHeight = maxHeight;
        final int fminBPP = minBPP;
        final int fmaxBPP = maxBPP;
        final int fminFreq = minFreq;
        final int fmaxFreq = maxFreq;
        try {
            final Object fmodes = AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws org.lwjgl.LWJGLException { 
                       return org.lwjgl.util.Display.getAvailableDisplayModes(
                           fminWidth, fminHeight, fmaxWidth, fmaxHeight,
                            fminBPP, fmaxBPP, fminFreq, fmaxFreq);
                    } 
                }); 
            return (DisplayMode[])fmodes;    
        } catch (PrivilegedActionException e) {
            throw (org.lwjgl.LWJGLException) e.getException();
        }
    }
    
    /** Create the display by choosing from a list of display modes
        based on an order of preference. */
    public static DisplayMode setDisplayMode(
        DisplayMode[] dm, String[] param)
        throws Exception { // Why does this not throw LWJGLException?
        final DisplayMode[] fdm = dm;
        final String[] fparam = param;
        try {
            final Object fmode = AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws Exception { 
                       return org.lwjgl.util.Display.setDisplayMode(
                           fdm, fparam );
                    } 
                }); 
            return (DisplayMode)fmode;            
        } catch (PrivilegedActionException e) {
            throw (Exception) e.getException();
        }
    }
}

I took a stab at fixing this and comitted to CVS. Please notify me if I missed anything.

  • elias

[quote]I took a stab at fixing this and comitted to CVS. Please notify me if I missed anything.

  • elias
    [/quote]
    Thanks, I’ll go take a look.

Alan

you could also just put a java webstart library at the lwjgl website, which should contain the latest version.

this way, others can reference this library by putting

<extension href="http://www.lwjgl.org/webstart/lwjgl.jnlp" name="LWJGL"/>

(example, this doesn’t exist)

in their own JNLP files.

there will never be a latests, since the will cause problems. If anything we might do some versioned ones - say 0.98 or 1.0. However we would have to check bandwidth issues before hand, since it might skyrocket.