package org.eclipse.swt.program;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */
 
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.motif.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

import org.eclipse.swt.widgets.Display;

import java.io.*;
import java.util.Iterator;
import java.util.Hashtable;
import java.util.Vector;

/**
 * Instances of this class represent programs and
 * their assoicated file extensions in the operating
 * system.
 */
public final class Program {	
	String name;
	String extension;
	String command;
	Display display;

	static private final String   cdeShell = "Program_CDE_SHELL";  // hidden shell used for DtAppInitialize and DtActionInvoke
	static private final String[] cdeIconExt = { ".m.pm",   ".l.pm",   ".s.pm",   ".t.pm" };
	static private final String[] cdeMaskExt = { ".m_m.bm", ".l_m.bm", ".s_m.bm", ".t_m.bm" };
	static private final String   desktopData = "Program_DESKTOP";
		
	static final int DESKTOP_UNKNOWN = 0;
	static final int DESKTOP_KDE = 1;
	static final int DESKTOP_GNOME = 2;
    static final int DESKTOP_CDE = 3;
	
/**
 * Prevents uninitialized instances from being created outside the package.
 */
Program () {
}

/* Determine the desktop for the given display. */
static int getDesktop( Display display ) {
	if (display == null) return DESKTOP_UNKNOWN;
	
	// If the desktop type for this display is already known, return it.
	Integer desktopValue = (Integer) display.getData( desktopData );
	if (desktopValue != null) {
		return desktopValue.intValue();
	}
	
	// Obtain the atoms for the various window manager signature properties.
	int desktop = DESKTOP_UNKNOWN;
	int xDisplay = display.xDisplay;
	/* Use the character encoding for the default locale */
	byte[] gnomeName = Converter.wcsToMbcs (null, "GNOME_NAME_SERVER", true);
	byte[] cdeName   = Converter.wcsToMbcs (null, "DTWM_IS_RUNNING", true);
	byte[] kdeName   = Converter.wcsToMbcs (null, "KWIN_RUNNING", true);
	int gnome = OS.XInternAtom( xDisplay, gnomeName, true );
	int cde   = OS.XInternAtom( xDisplay, cdeName, true );
	int kde   = OS.XInternAtom( xDisplay, kdeName, true );
	
	// Get the list of properties on the root window.
	int   rootWindow = OS.XDefaultRootWindow( xDisplay );
	int[] numProp = new int[1];
	int   propList = OS.XListProperties( xDisplay, rootWindow, numProp );
	if (propList == 0) return DESKTOP_UNKNOWN;
	int[] property = new int[ numProp[0] ];
	OS.memmove( property, propList, (property.length * 4) );
	OS.XFree( propList );
	
	// A given WM (desktop) is active if the property exists on the root window.
	for (int index = 0; desktop == DESKTOP_UNKNOWN && index < property.length; index++) {
		if (property[ index ] == OS.None) continue; // do not match atoms that do not exist
		if (property[ index ] == gnome) {
			if (gnome_init()) desktop = DESKTOP_GNOME;		
		}
		if (property[ index ] == cde) {
			if (cde_init( display )) desktop = DESKTOP_CDE;
		}	
		if (property[ index ] == kde) {
			if (kde_init()) desktop = DESKTOP_KDE;
		}	
	}
	
	// Save the desktop type on the display itself.
	display.setData( desktopData, new Integer(desktop) );
	return desktop;
}

/**
 * Finds the program that is associated with an extension.
 * The extension may or may not begin with a '.'.
 *
 * @param extension the program extension
 * @return the program or nil
 *
 * @exception SWTError <ul>
 *		<li>ERROR_NULL_ARGUMENT when extension is null</li>
 *	</ul>
 */
public static Program findProgram (String extension) {
	return findProgram( Display.getCurrent(), extension );
}

/*
 *  API: When support for multiple displays is added, this method will
 *       become public and the original method above can be deprecated.
 */
private static Program findProgram( Display display, String extension ) {
	if (extension == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	if (extension.length () == 0) return null;
	if (extension.charAt (0) != '.') extension = "." + extension;
	String command = null;
	String name = null;
	int desktop = getDesktop( display );
	Hashtable mimeInfo = null;
	if (desktop == DESKTOP_KDE)   mimeInfo = kde_getMimeInfo();
	if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo();
	if (desktop == DESKTOP_CDE)   mimeInfo = cde_getDataTypeInfo();
	if (mimeInfo == null) return null;

	// Find the data type matching the extension.
	Iterator keys = mimeInfo.keySet().iterator();
	while (name == null && keys.hasNext()) {
		String mimeType = (String) keys.next();
		Vector mimeExts = (Vector) mimeInfo.get( mimeType );
		for (int index = 0; index < mimeExts.size(); index++){
			if (extension.equals( mimeExts.elementAt( index ) )) {
				name = mimeType;
			}
		}
	}			
	if (name == null) return null;

	// Get the corresponding command for the mime type.
	if (desktop == DESKTOP_KDE)   command = kde_getMimeTypeCommand( name );
	if (desktop == DESKTOP_GNOME) command = gnome_getMimeValue( name, "open" );
	if (desktop == DESKTOP_CDE)   command = cde_getAction( name );
	if (command == null) return null;
	
	// Return the corresponding program.
	Program program   = new Program ();
	program.name      = name;
	program.command   = command;
	program.extension = extension;
	program.display   = display;
	return program;
}

/**
 * Answer all program extensions in the operating system.
 *
 * @return an array of extensions
 */
public static String [] getExtensions () {
	return getExtensions( Display.getCurrent() );
}

/*
 *  API: When support for multiple displays is added, this method will
 *       become public and the original method above can be deprecated.
 */
private static String[] getExtensions( Display display ) {
	int desktop = getDesktop( display );
	Hashtable mimeInfo = null;
	if (desktop == DESKTOP_KDE)   mimeInfo = kde_getMimeInfo();
	if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo();
	if (desktop == DESKTOP_CDE)   mimeInfo = cde_getDataTypeInfo();
	if (mimeInfo == null) return new String[0];

			
	// Create a unique set of the file extensions.
	Vector extensions = new Vector();
	Iterator keys = mimeInfo.keySet().iterator();
	while (keys.hasNext()) {
		String mimeType = (String) keys.next();
		Vector mimeExts = (Vector) mimeInfo.get( mimeType );
		for (int index = 0; index < mimeExts.size(); index++){
			if (!extensions.contains( mimeExts.elementAt( index ) )) {
				extensions.addElement( mimeExts.elementAt( index ) );
			}
		}
	}
			
	// Return the list of extensions.
	String[] extStrings = new String[ extensions.size() ];
	for (int index = 0; index < extensions.size(); index++) {
		extStrings[ index ] = (String) extensions.elementAt( index );
	}			
	return extStrings;
}

/**
 * Answers all available programs in the operating system.
 *
 * @return an array of programs
 */
public static Program [] getPrograms () {
	return getPrograms( Display.getCurrent() );
}

/*
 *  API: When support for multiple displays is added, this method will
 *       become public and the original method above can be deprecated.
 */
private static Program[] getPrograms( Display display ) {
	int desktop = getDesktop( display );
	Hashtable mimeInfo = null;
	if (desktop == DESKTOP_KDE)   mimeInfo = kde_getMimeInfo();
	if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo();
	if (desktop == DESKTOP_CDE)   mimeInfo = cde_getDataTypeInfo();
	if (mimeInfo == null) return new Program[0];
			
	// Create a list of programs with commands.
	Vector programs = new Vector();
	Iterator keys = mimeInfo.keySet().iterator();
	while (keys.hasNext()) {
		String mimeType  = (String) keys.next();
		Vector mimeExts  = (Vector) mimeInfo.get( mimeType );
		String extension = "";
		if (mimeExts.size() > 0){
			extension = (String) mimeExts.elementAt( 0 );
		}
		String command = null;
		if (desktop == DESKTOP_KDE)   command = kde_getMimeTypeCommand( mimeType );
		if (desktop == DESKTOP_GNOME) command = gnome_getMimeValue( mimeType, "open" );
		if (desktop == DESKTOP_CDE)   command = cde_getAction( mimeType );
		if (command != null) {
			Program program   = new Program ();
			program.name      = mimeType;
			program.command   = command;
			program.extension = extension;
			program.display   = display;
			programs.addElement( program );
		}
	}
			
	// Return the list of programs to the user.
	Program[] programList = new Program[ programs.size() ];
	for (int index = 0; index < programList.length; index++) {
		programList[ index ] = (Program) programs.elementAt( index );
	}
	return programList;
}

/*
 * Obtain the registered mime type information and
 * return it in a map. The key of each entry
 * in the map is the mime type name. The value is
 * a vector of the associated file extensions.
 */
  
private static Hashtable gnome_getMimeInfo() {
	Hashtable mimeInfo = new Hashtable();
	
	// Extract the mime info from the system directory.
	String mimeDirectory = gnome_getDataDirectory ("mime-info");
	gnome_getMimeInfoFromDirectory( mimeInfo, new File( mimeDirectory ) );
	
	// Append the mime info from the user's directory (if it exists).
	String userDirectory = gnome_getHomeDirectory();
	if (userDirectory != null) {
		userDirectory = userDirectory + File.separator + ".gnome" + File.separator + "mime-info";
		gnome_getMimeInfoFromDirectory( mimeInfo, new File( userDirectory ) );
	}

	return mimeInfo;
}

// Given a map and a directory, find all of the 
// mime information files (*.mime) and parse them for
// relavent mime type information. Each entry in the
// map corresponds to one mime type, and its
// associated file extensions.

private static void gnome_getMimeInfoFromDirectory( Hashtable info, File directory ) {
	// For each entry in the given directory (if it exists)
	if (directory.exists()) {
		File[] files = directory.listFiles();
		for (int i = 0; i < files.length; i++) {
		
			// If the entry is a subdirectory, process it and
			// merge the mime type into the given map.
			if (files[i].isDirectory()) {
				gnome_getMimeInfoFromDirectory( info, files[i] );
			}
		
			// else if the entry is a mime info file (*.mime)
			else if (files[i].getName().endsWith(".mime")) {
				try {
					// Parse the mime file and merge the info
					// into the given map.
					FileReader in = new FileReader( files[i] );
					BufferedReader reader = new BufferedReader( in );
					gnome_parseMimeFile( info, reader );
					reader.close();
					in.close();
				}
				catch (IOException e) {
					// Ignore file exceptions silently. If we
					// can't read it, the info is not available.
				}
			}
		}
	}
}

private static void gnome_parseMimeFile( Hashtable info, BufferedReader reader ) {
	Vector  mimeExts = null;
	String  mimeType = null;
	boolean saveType = false;
	String  line     = "#";
	while (line != null) {
		
		// Determine if the line contains a mime type name.
		boolean newType = (line.length() > 0 && Compatibility.isLetter( line.charAt(0) ));
				  
		// If there is valid data on this line to be processed
		String data = line.trim();
		if (data.length() > 0 && data.charAt(0) != '#') {
			
			// If this line defines a new mime type
			if (newType) {
				
				// If a previous mime type has not be saved yet
				if (mimeType != null) {
					// Save the type and process this line again.
					saveType = true;
				}
				// else initialize the mime type info
				else {
					int colon = data.indexOf( ':' );
					if (colon != -1) {
						mimeType = data.substring( 0, colon );
					}
					else {
						mimeType = data;
					}
					mimeExts = new Vector();
				}
			}
			
			// else if the line defines a list of extensions
			else if (data.indexOf( "ext" ) == 0 && mimeType != null) {
				
				// Get the extensions defined on the line
				String exts = "";
				int colon = data.indexOf( ':' );
				if ((colon != -1) && ((colon+1) < data.length())) {
					exts = data.substring( (colon+1) ).trim();
				}
				
				// While there are extensions to be processed (use space as separator)
				exts = exts.replace( '\t', ' ' );
				exts = exts.replace( ',', ' ' );
				while (exts.length() != 0) {
					// Extract the next entension from the list
					String newExt;
					int  space = exts.indexOf( ' ' );
					if (space != -1) {
						newExt = exts.substring( 0, space );
						exts = exts.substring( space ).trim();
					}
					else {
						newExt = exts;
						exts = "";
					}
					
					// Prefix an extension with a period.
					if (newExt.charAt(0) != '.') {
						newExt = "." + newExt;
					}
					mimeExts.addElement( newExt );
				} 
			}
			
			// else if the line defines a list of regular expressions
			else if (data.indexOf( "regex" ) == 0 && mimeType != null) {
				// Do nothing with these right now.
			}
		}
		
		
		// If the current mime type is still being processed
		if (!saveType) {
			// Get the next line			
			try {
				line = reader.readLine();
			}
			catch (IOException e) {
				line = null;
			}
		}
		
		// If the current type should be saved or if the end
		// of the file was reached
		if (saveType || (line == null)) {
			// If there is a mime type to be saved
			if (mimeType != null) {
			
				// If the mime type does not exist in the map, add it.
				Vector prevExts = (Vector) info.get( mimeType );
				if (prevExts == null) {
					info.put( mimeType, mimeExts );
				}
		
				// else append the new list of extensions.
				else {
					for (int i = 0; i < mimeExts.size(); i++) {
						prevExts.add( mimeExts.elementAt( i ) );
					}
				}
			}
			mimeType = null;
			mimeExts = null;
			saveType = false;
		}
	}
}

// Private method for parsing a command line into its arguments.
private static String[] parseCommand( String cmd ) {
	Vector args = new Vector();
	int sIndex = 0;
	int eIndex;
	while (sIndex < cmd.length()) {
		// Trim initial white space of argument.
		while (sIndex < cmd.length() && Compatibility.isWhitespace( cmd.charAt(sIndex) )) {
			sIndex++;
		}
		if (sIndex < cmd.length()) {
			// If the command is a quoted string
			if (cmd.charAt(sIndex) == '"' || cmd.charAt(sIndex) == '\''){
				// Find the terminating quote (or end of line).
				// This code currently does not handle escaped characters (e.g., " a\"b").
				eIndex = sIndex + 1;
				while (eIndex < cmd.length() && cmd.charAt(eIndex) != cmd.charAt(sIndex)) {
					eIndex++;
				}
				if (eIndex >= cmd.length()) { // the terminating quote was not found
					// Add the argument as is with only one initial quote.
					args.addElement( cmd.substring( sIndex, eIndex ) );
				}
				// else add the argument, trimming off the quotes.
				else {
					args.addElement( cmd.substring( sIndex+1, eIndex ) );
				}
				sIndex = eIndex + 1;
			}
			
			// else use white space for the delimiters.
			else {
				eIndex = sIndex;
				while (eIndex < cmd.length() && !Compatibility.isWhitespace( cmd.charAt(eIndex) )) {
					eIndex++;
				}
				args.addElement( cmd.substring( sIndex, eIndex ) );
				sIndex = eIndex + 1;
			}
		}
	}
	
	String[] strings = new String[ args.size() ];
	for (int index =0; index < args.size(); index++) {
		strings[ index ] = (String) args.elementAt( index );
	}
	return strings;
}


static String gnome_getDataDirectory(String dirName) {
	/* Use the character encoding for the default locale */
	byte [] nameBuffer = Converter.wcsToMbcs (null, dirName, true);
	int ptr = GNOME.gnome_datadir_file(nameBuffer);
	if (ptr == 0) return null;
	int length = OS.strlen(ptr);
	byte[] dirBuffer = new byte[length];
	OS.memmove(dirBuffer, ptr, length);
	/* Use the character encoding for the default locale */
	return new String(Converter.mbcsToWcs(null, dirBuffer));
}

static String gnome_getHomeDirectory() {
	int ptr = GNOME.g_get_home_dir();
	if (ptr == 0) return null;
	int length = OS.strlen(ptr);
	byte[] homeDirBuffer = new byte[length];
	OS.memmove(homeDirBuffer, ptr, length);
	/* Use the character encoding for the default locale */
	return new String(Converter.mbcsToWcs(null, homeDirBuffer));
}

static String gnome_getMimeType(String name) {
	/* Use the character encoding for the default locale */
	byte [] nameBuffer = Converter.wcsToMbcs (null, name, true);
	int ptr = GNOME.gnome_mime_type(nameBuffer);
	if (ptr == 0) return null;
	int length = OS.strlen(ptr);
	byte[] mimeBuffer = new byte[length];
	OS.memmove(mimeBuffer, ptr, length);
	/* Use the character encoding for the default locale */
	return new String(Converter.mbcsToWcs(null, mimeBuffer));
}

static String gnome_getMimeValue(String mimeType, String key) {
	/* Use the character encoding for the default locale */
	byte [] typeBuffer = Converter.wcsToMbcs (null, mimeType, true);
	byte [] keyBuffer = Converter.wcsToMbcs (null, key, true);
	int ptr = GNOME.gnome_mime_get_value(typeBuffer, keyBuffer);
	if (ptr == 0) return null;
	
	StringBuffer stringBuffer = new StringBuffer();
	int length = OS.strlen(ptr);
	byte[] valueBuffer = new byte[length];
	OS.memmove(valueBuffer, ptr, length);
	/* Use the character encoding for the default locale */
	return new String(Converter.mbcsToWcs(null, valueBuffer));
}

static boolean kde_init () {
	/* TEMPORARY CODE */
	if (true) return false;
	try {
		Callback.loadLibrary("swt-kde");
	} catch (SWTError e) {
		return false;
	}

	/* Use the character encoding for the default locale */
	byte [] nameBuffer = Converter.wcsToMbcs( null, "SWT", true );
	int qcString = KDE.QCString_new( nameBuffer );
	KDE.KApplication_new( qcString );
	KDE.QCString_delete( qcString );
	return true;
}

private static String kde_getMimeTypeCommand( String mimeType ) {
	/* Use the character encoding for the default locale */
	byte [] buffer = Converter.wcsToMbcs (null, mimeType, true);
	int qMimeType = KDE.QString_new( buffer );
	int serviceList = KDE.KMimeType_offers( qMimeType );
	KDE.QString_delete( qMimeType );
	if (serviceList == 0) return null;
	KDE.KServiceList_delete( serviceList );
	return "KRun::runURL(url,mimeType)";
}
/*
 * Obtain the registered mime type information and
 * return it in a map. The key of each entry
 * in the map is the mime type name. The value is
 * a vector of the associated file extensions.
 */
  
private static Hashtable kde_getMimeInfo() {
	Hashtable mimeInfo = new Hashtable();
	Vector    mimeExts = null;
	String    mimeType;
	
	// Get the list of all mime types available.
	int mimeTypeList = KDE.KMimeType_allMimeTypes();
	int iterator = KDE.KMimeTypeList_begin( mimeTypeList );
	int listEnd  = KDE.KMimeTypeList_end( mimeTypeList );
	while (KDE.KMimeTypeListIterator_equals( iterator, listEnd ) == 0) {
		// Get the next KMimeType from the list.
		int kMimeType = KDE.KMimeTypeListIterator_dereference( iterator );
		
		// Get the mime type name.
		int mimeName = KDE.KMimeType_name( kMimeType );
		mimeType = kde_convertQStringAndFree( mimeName );
		
		// Get the list of extension patterns.
		mimeExts = new Vector();
		String extension;
		
		// Add the mime type to the hash table with its extensions.
		int patternList = KDE.KMimeType_patterns( kMimeType );
		int patIterator = KDE.QStringList_begin( patternList );
		int patListEnd  = KDE.QStringList_end( patternList );
		while (KDE.QStringListIterator_equals( patIterator, patListEnd ) == 0) {
			// Get the next extension pattern from the list.
			int patString = KDE.QStringListIterator_dereference( patIterator );
			extension = kde_convertQStringAndFree( patString );
			int period = extension.indexOf( '.' );
			if (period != -1) {
				mimeExts.addElement( extension.substring( period ) );
			}

			// Advance to the next pattern.		
			KDE.QStringListIterator_increment( patIterator );
		}
		KDE.QStringListIterator_delete( patIterator );
		KDE.QStringListIterator_delete( patListEnd );
		KDE.QStringList_delete( patternList );
		
		// If there is at least one extension, save the mime type.
		if (mimeExts.size() > 0) {
			mimeInfo.put( mimeType, mimeExts );
		}

		// Advance to the next mime type.		
		KDE.KMimeTypeListIterator_increment( iterator );
	}
	KDE.KMimeTypeListIterator_delete( iterator );
	KDE.KMimeTypeListIterator_delete( listEnd );
	KDE.KMimeTypeList_delete( mimeTypeList );
	
	return mimeInfo;
}

static String kde_convertQStringAndFree (int qString) {
	int qCString = KDE.QString_utf8 (qString);
	int charString = KDE.QCString_data (qCString);
	
	StringBuffer stringBuffer = new StringBuffer ();
	int length = KDE.strlen (charString);
	byte[] buffer = new byte [length];
	KDE.memmove (buffer, charString, length);
	/* Use the character encoding for the default locale */
	String answer = new String (Converter.mbcsToWcs (null, buffer));
		
	KDE.QCString_delete (qCString);
	KDE.QString_delete (qString);
	return answer;
}

/**
 * Launches the executable associated with the file in
 * the operating system.  If the file is an executable,
 * then the executable is launched.
 *
 * @param fileName the file or program name
 * @return <code>true</code> if the file is launched, otherwise <code>false</code>
 * 
 * @exception SWTError <ul>
 *		<li>ERROR_NULL_ARGUMENT when fileName is null</li>
 *	</ul>
 */
public static boolean launch (String fileName) {
	return launch( Display.getCurrent(), fileName );
}

/*
 *  API: When support for multiple displays is added, this method will
 *       become public and the original method above can be deprecated.
 */
private static boolean launch( Display display, String fileName ) {
	if (fileName == null) SWT.error( SWT.ERROR_NULL_ARGUMENT );
	
	// If the argument appears to be a data file (it has an extension)
	int index = fileName.lastIndexOf('.');
	if (index > 0) {
		
		// Find the associated program, if one is defined.
		String extension = fileName.substring( index );
		Program program = Program.findProgram( display, extension ); 
		
		// If the associated program is defined and can be executed, return.
		if (program != null && program.execute( fileName )) return true;
	}
	
	// Otherwise, the argument was the program itself.
	try {
		Compatibility.exec(fileName);
		return true;
	} catch (IOException e) {
		return false;
	}
}

/**
 * Executes the program with the file as the single argument
 * in the operating system.  It is the responsibility of the
 * programmer to ensure that the file contains valid data for 
 * this program.  
 *
 * @param fileName is the argument (typically a file) for the program
 * @return <code>true</code> if the file is launched, otherwise <code>false</code>
 * 
 * @exception SWTError <ul>
 *		<li>ERROR_NULL_ARGUMENT when fileName is null</li>
 *	</ul>
 */
public boolean execute (String fileName) {
	if (fileName == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
	
	switch (getDesktop( display )) {
		case DESKTOP_KDE: {
			String urlString = "file://" + fileName;
			/* Use the character encoding for the default locale */
			byte[] buffer = Converter.wcsToMbcs( null, urlString, true );
			int qString = KDE.QString_new( buffer );
			int url = KDE.KURL_new( qString );
			KDE.QString_delete( qString );
			/* Use the character encoding for the default locale */
			buffer = Converter.wcsToMbcs (null, name, true);
			int mimeTypeName = KDE.QString_new( buffer );
			int pid = KDE.KRun_runURL( url, mimeTypeName );
			KDE.KURL_delete( url );
			KDE.QString_delete( mimeTypeName );
			return (pid != 0);
		}
		
		case DESKTOP_GNOME: {
			// Parse the command into its individual arguments.
			String[]  args = parseCommand( command );
			int       fileArg = -1;
			int       index;
			for (index=0; index < args.length; index++) {
				int j = args[ index ].indexOf( "%f" );
				if (j != -1) {
					String value = args[ index ];
					fileArg = index;
					args[ index ] = value.substring(0,j) + fileName + value.substring(j+2);
				}
			}
	
			// If a file name was given but the command did not have "%f"
			if ((fileName.length() > 0) && (fileArg < 0)) {
				String[] newArgs = new String[ args.length + 1 ];
				for (index=0; index < args.length; index++)
					newArgs[ index ] = args[ index ];
				newArgs[ args.length ] = fileName;
				args = newArgs;
			}
	
			// Execute the command.
			try {
				Compatibility.exec(args);
			} catch (IOException e) {
				return false;
			}
			return true;
		}
		
		case DESKTOP_CDE: {
			/* Use the character encoding for the default locale */
			byte[] action = Converter.wcsToMbcs( null, command, true );
			byte[] fileArg = Converter.wcsToMbcs( null, fileName, true );
			Integer shell = (Integer) display.getData( cdeShell );
			int actionID = 0;
			if (shell != null) {
				actionID = CDE.DtActionInvoke( shell.intValue(), action, fileArg, 1, null, null, null, 1, 0, 0 );
			}
			return (actionID != 0);
		}
	}

	return false;
}

/**
 * Returns the receiver's image data.  This is the icon
 * that is associated with the reciever in the operating
 * system.
 *
 * @return the image data for the program, may be null
 */
public ImageData getImageData () {
	String iconPath = null;
	switch (getDesktop( display )) {
		case DESKTOP_KDE: {
			/* Use the character encoding for the default locale */
			byte [] buffer = Converter.wcsToMbcs (null, name, true);
			int mimeTypeName = KDE.QString_new( buffer );
			int mimeType = KDE.KMimeType_mimeType( mimeTypeName );
			KDE.QString_delete( mimeTypeName );			
			if (mimeType == 0) return null;			
			int mimeIcon = KDE.KMimeType_icon(mimeType, 0, 0);
			int loader = KDE.KGlobal_iconLoader();
			int path = KDE.KIconLoader_iconPath(loader, mimeIcon, KDE.KICON_SMALL, 1);
			if (path == 0) return null;
			iconPath = kde_convertQStringAndFree(path);
			break;
		}
		
		case DESKTOP_GNOME: {
			String fakeFileName = "file" + extension;
			String mime = gnome_getMimeType(fakeFileName);
			if (mime == null) return null;
			iconPath = gnome_getMimeValue(mime, "icon-filename");
			if (iconPath == null) return null;
			break;
		}
		
		case DESKTOP_CDE: {
			return cde_getImageData();
		}
		
		case DESKTOP_UNKNOWN: {
			return null;
		}
	}
	if (iconPath.endsWith ("xpm")) {
		int xDisplay = display.xDisplay;
		int screen  = OS.XDefaultScreenOfDisplay( xDisplay );
		int fgPixel = OS.XWhitePixel( display.xDisplay, OS.XDefaultScreen( xDisplay ) );
		int bgPixel = OS.XBlackPixel( display.xDisplay, OS.XDefaultScreen( xDisplay ) );
		/* Use the character encoding for the default locale */
		byte [] iconName = Converter.wcsToMbcs (null, iconPath, true);
		int pixmap = OS.XmGetPixmap( screen, iconName, fgPixel, bgPixel );
    	if (pixmap == OS.XmUNSPECIFIED_PIXMAP) return null;
		Image image = Image.motif_new (display, SWT.BITMAP, pixmap, 0);
		ImageData imageData = image.getImageData ();
		
		// The pixmap returned from XmGetPixmap is cached by Motif
		// and must be deleted by XmDestroyPixmap. Because it cannot
		// be deleted directly by XFreePixmap, image.dispose() must not
		// be called. The following code should do an equivalent image.dispose().
		OS.XmDestroyPixmap( screen, pixmap );
		return imageData;		
	}
	try {
		return new ImageData (iconPath);
	} catch (Exception e) {
		return null;
	}
}

/**
 * Returns the receiver's name.  This is as short and
 * descriptive a name as possible for the program.  If
 * the program has no descriptive name, this string may
 * be the executable name, path or empty.
 *
 * @return an the name of the program
 */
public String getName () {
	return name;
}

/**
 * Returns true if the receiver and the argument represent
 * the same program.
 * 
 * @return true if the programs are the same
 */
public boolean equals(Object other) {
	if (this == other) return true;
	if (other instanceof Program) {
		final Program program = (Program) other;
		return display == program.display && extension.equals(program.extension) &&
			name.equals(program.name) && command.equals(program.command);
	}
	return false;
}

/**
 * Returns a hash code suitable for this object.
 * 
 * @return a hash code
 */
public int hashCode() {
	return extension.hashCode() ^ name.hashCode() ^ command.hashCode() ^ display.hashCode();
}

public String toString () {
	return "Program {" + name + "}";
}
static boolean gnome_init () {
	try {
		Callback.loadLibrary("swt-gnome");
	} catch (SWTError e) {
		return false;
	}
	return true;
}

/* CDE - Get Attribute Value
 * 
 * This method takes a data type name and an attribute name, and returns
 * the corresponding attribute value.
 */

static String cde_getAttribute(String dataType, String attrName) {
	/* Use the character encoding for the default locale */
	byte [] dataTypeBuf = Converter.wcsToMbcs (null, dataType, true);
    byte [] attrNameBuf = Converter.wcsToMbcs (null, attrName, true);
    byte [] optNameBuf  = null;
	int attrValue = CDE.DtDtsDataTypeToAttributeValue( dataTypeBuf, attrNameBuf, optNameBuf );
	if (attrValue == 0) return null;
    int length = OS.strlen(attrValue);
    byte[] attrValueBuf = new byte[length];
    OS.memmove(attrValueBuf, attrValue, length);
    CDE.DtDtsFreeAttributeValue( attrValue );
	/* Use the character encoding for the default locale */
    return new String(Converter.mbcsToWcs(null, attrValueBuf));
}

/* CDE - Get Default Action of Data Type
 * 
 * This method takes a data type and returns the corresponding default action.
 * By default, the "Open" action is used if it is available. If it is not
 * available, the first action in the list is used. Typically, if Open is not
 * available, there is usually only one action anyways.
 */

static String cde_getAction(String dataType) {
	String action  = null;
	String actions = cde_getAttribute( dataType, CDE.DtDTS_DA_ACTION_LIST );
	if (actions != null) {
		int index = actions.indexOf( "Open" );
		if (index != -1) {
			action = actions.substring( index, index+4 );
		}
		else {
			index = actions.indexOf( "," );
			if (index != -1) {
				action = actions.substring( 0, index );
			}
			else {
				action = actions;
			}
		}
	}
	return action;
}

/* CDE - Get Extension of Data Type
 * 
 * This method takes a data type and returns the corresponding extension.
 * The extension is obtained from the NAME TEMPLATE attribute.
 */

static String cde_getExtension(String dataType) {
    String fileExt = cde_getAttribute( dataType, CDE.DtDTS_DA_NAME_TEMPLATE );
    if (fileExt == null || fileExt.indexOf( "%s." ) == -1) return null;
    int dot = fileExt.indexOf( "." );
    return fileExt.substring( dot );
}

/* CDE - Get Data Types
 * 
 * This method returns the list of data type names available.
 * Each data type returned is valid, meaning it has an action and
 * an extension. 
 */

static Hashtable cde_getDataTypeInfo() {
	Hashtable dataTypeInfo = new Hashtable();
	int index;
	int dataTypeList = CDE.DtDtsDataTypeNames();
	if (dataTypeList != 0) {
		// For each data type name in the list
		index = 0; 
		int dataType = CDE.listElementAt( dataTypeList, index++ );
		while (dataType != 0) {
    		int length = OS.strlen(dataType);
    		byte[] dataTypeBuf = new byte[length];
    		OS.memmove(dataTypeBuf, dataType, length);
			/* Use the character encoding for the default locale */
     		String dataTypeName = new String(Converter.mbcsToWcs(null, dataTypeBuf));
     		
	   		// The data type is valid if it is not an action, and it has an extension and an action.
      		String extension = cde_getExtension( dataTypeName );
   			if (!CDE.DtDtsDataTypeIsAction( dataTypeBuf ) &&
				extension != null && cde_getAction( dataTypeName ) != null) {
				Vector exts = new Vector();
				exts.addElement( extension );
				dataTypeInfo.put( dataTypeName, exts );
	   		}
			dataType = CDE.listElementAt( dataTypeList, index++ );
		}
		CDE.DtDtsFreeDataTypeNames( dataTypeList );
	}
	
    return dataTypeInfo;
}

/* CDE - Get Image Data
 * 
 * This method returns the image data of the icon associated with
 * the data type. Since CDE supports multiple sizes of icons, several
 * attempts are made to locate an icon of the desired size and format.
 * CDE supports the sizes: tiny, small, medium and large. The best
 * search order is medium, large, small and then tiny. Althoug CDE supports
 * colour and monochrome bitmaps, only colour icons are tried. (The order is
 * defined by the  cdeIconExt and cdeMaskExt arrays above.)
 */

ImageData cde_getImageData() {
	int	xDisplay = display.xDisplay;
	int screen  = OS.XDefaultScreenOfDisplay( xDisplay );
	int fgPixel = OS.XWhitePixel( display.xDisplay, OS.XDefaultScreen( xDisplay ) );
	int bgPixel = OS.XBlackPixel( display.xDisplay, OS.XDefaultScreen( xDisplay ) );
	
    String icon = cde_getAttribute( name, CDE.DtDTS_DA_ICON );
    byte [] iconName;
    byte [] maskName = null;
    int    pixmap = 0;
    for (int index = 0; index < cdeIconExt.length && pixmap == 0; index++) {
		/* Use the character encoding for the default locale */
    	iconName = Converter.wcsToMbcs (null, icon + cdeIconExt[ index ], true);
    	maskName = Converter.wcsToMbcs (null, icon + cdeMaskExt[ index ], true);
		pixmap = OS.XmGetPixmap( screen, iconName, fgPixel, bgPixel );
    	if (pixmap == OS.XmUNSPECIFIED_PIXMAP) pixmap = 0;
   }
    
    if (pixmap != 0) {
    	int type = SWT.ICON;
    	// When creating the mask pixmap, do not use the screen's white and black
    	// pixel for the foreground and background respectively, because on some
    	// X servers (e.g., Solaris) pixel 0 is white and pixel 1 is black. Passing
    	// (screen, name, whitePixel, blackPixel, 1) to get the mask pixmap will
    	// result in an inverted mask. Instead explicitly use 1 (FG) and 0 (BG).
   		int mask = OS.XmGetPixmapByDepth( screen, maskName, 1, 0, 1 );
    	if (mask == OS.XmUNSPECIFIED_PIXMAP) {
    		type = SWT.BITMAP;
    		mask = 0;
    	}
		Image image = Image.motif_new (display, type, pixmap, mask );
		ImageData imageData = image.getImageData();
		
		// The pixmaps returned from XmGetPixmap... are cached by Motif
		// and must be deleted by XmDestroyPixmap. Because they cannot
		// be deleted directly by XFreePixmap, image.dispose() must not
		// be called. The following code should do an equivalent image.dispose().
		OS.XmDestroyPixmap( screen, pixmap );
		if (mask != 0) OS.XmDestroyPixmap( screen, mask ); 
		return imageData;		
    }
    return null;	
}

/* CDE - Initialize
 * 
 * This method loads the swt-cde library and initializes CDE itself.
 * The shell created fo DtAppInitialize is kept for DtActionInvoke calls.
 */
static boolean cde_init( Display display ) {
	try {
		Callback.loadLibrary("swt-cde");
	} catch (SWTError e) {
		return false;
	}

	/* Use the character encoding for the default locale */
	byte[] appName = Converter.wcsToMbcs( null, "SWT", true );
	int xtContext  = OS.XtDisplayToApplicationContext( display.xDisplay );
	int widgetClass = OS.TopLevelShellWidgetClass();
	int shell = OS.XtAppCreateShell( appName, appName, widgetClass, display.xDisplay, null, 0 );
	boolean initOK  = CDE.DtAppInitialize( xtContext, display.xDisplay, shell, appName, appName );
	if (!initOK) {
		OS.XtDestroyWidget( shell );
	}
	else {
		CDE.DtDbLoad();
		display.setData( cdeShell, new Integer(shell) );
		display.disposeExec( new Runnable() {
			public void run() {
				// This logic assumes that when the corresponding display is
				// being disposed, it must be the current one.
				Integer shell = (Integer) Display.getCurrent().getData( cdeShell );
				if (shell != null) {
					OS.XtDestroyWidget( shell.intValue() );
				}
			}
		});
	}	
	return initOK;
}
}
