diff options
author | Silenio Quarti | 2004-09-10 18:19:01 +0000 |
---|---|---|
committer | Silenio Quarti | 2004-09-10 18:19:01 +0000 |
commit | a9865ce41544b9634fe7b5cf08a114ae91a2faeb (patch) | |
tree | 8e580d851e281d1324989d671f3075d7cbf4caf9 /bundles | |
parent | dbb652fe193019d96be9d6af80af3f6e1918e181 (diff) | |
download | eclipse.platform.swt-a9865ce41544b9634fe7b5cf08a114ae91a2faeb.tar.gz eclipse.platform.swt-a9865ce41544b9634fe7b5cf08a114ae91a2faeb.tar.xz eclipse.platform.swt-a9865ce41544b9634fe7b5cf08a114ae91a2faeb.zip |
*** empty log message ***
Diffstat (limited to 'bundles')
-rw-r--r-- | bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.kde.KDE.properties | 3 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT PI/motif/library/make_linux.mak | 4 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT PI/motif/org/eclipse/swt/internal/motif/OS.java | 5 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Program/gtk/org/eclipse/swt/program/Program.java | 642 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde.cpp | 10 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.cpp (renamed from bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.c) | 5 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.h | 1 | ||||
-rw-r--r-- | bundles/org.eclipse.swt/Eclipse SWT Program/kde/org/eclipse/swt/internal/kde/KDE.java | 1 | ||||
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT Program/motif/org/eclipse/swt/program/Program.java | 1014 |
9 files changed, 926 insertions, 759 deletions
diff --git a/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.kde.KDE.properties b/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.kde.KDE.properties index 6c5be24cae..bf03b6e489 100644 --- a/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.kde.KDE.properties +++ b/bundles/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.kde.KDE.properties @@ -48,6 +48,9 @@ KDE_KMimeTypeList_end_0=cast=(KMimeType::List *) KDE_KMimeType_allMimeTypes=accessor=KMimeType::allMimeTypes,copy=KMimeType::List +KDE_KMimeType_delete=flags=delete +KDE_KMimeType_delete_0=cast=(KSharedPtr<KMimeType> *) + KDE_KMimeType_icon=copy=QString,flags=cpp KDE_KMimeType_icon_0=cast=(KSharedPtr<KMimeType> *),flags=struct KDE_KMimeType_icon_1=cast=(const QString&) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/motif/library/make_linux.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/motif/library/make_linux.mak index d3ffac008b..5bf2497387 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/motif/library/make_linux.mak +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/motif/library/make_linux.mak @@ -94,8 +94,8 @@ $(KDE_LIB): $(KDE_OBJS) kde.o: kde.cpp g++ $(KDE_CFLAGS) -o kde.o kde.cpp -kde_stats.o: kde_stats.c - gcc $(KDE_CFLAGS) -o kde_stats.o kde_stats.c +kde_stats.o: kde_stats.cpp + gcc $(KDE_CFLAGS) -o kde_stats.o kde_stats.cpp make_awt: $(AWT_LIB) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/motif/org/eclipse/swt/internal/motif/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/motif/org/eclipse/swt/internal/motif/OS.java index 4436995ae2..217fcf7989 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/motif/org/eclipse/swt/internal/motif/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/motif/org/eclipse/swt/internal/motif/OS.java @@ -38,6 +38,11 @@ public class OS { } public static final int CODESET = CODESET (); public static final int LC_CTYPE = LC_CTYPE (); + + public static final int PTR_SIZEOF; + static { + PTR_SIZEOF = 4; + } static final int RESOURCE_LENGTH = 1024 * 3; static final int RESOURCE_START = OS.XtMalloc (RESOURCE_LENGTH); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/gtk/org/eclipse/swt/program/Program.java b/bundles/org.eclipse.swt/Eclipse SWT Program/gtk/org/eclipse/swt/program/Program.java index fb6c741484..855aa3acdd 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/gtk/org/eclipse/swt/program/Program.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/gtk/org/eclipse/swt/program/Program.java @@ -14,8 +14,9 @@ package org.eclipse.swt.program; import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; -import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.internal.gnome.*; +import org.eclipse.swt.internal.kde.*; +import org.eclipse.swt.internal.gtk.*; import org.eclipse.swt.widgets.*; import java.io.*; @@ -26,10 +27,10 @@ import java.util.*; * their assoicated file extensions in the operating * system. */ -public final class Program { +public final class Program { String name; String command; - ImageData imageData; + String iconPath; Display display; /* Gnome specific @@ -38,10 +39,14 @@ public final class Program { */ boolean gnomeExpectUri; + static final String SHELL_HANDLE_KEY = "org.eclipse.swt.internal.motif.shellHandle"; + static final String[] CDE_ICON_EXT = { ".m.pm", ".l.pm", ".s.pm", ".t.pm" }; + static final String[] CDE_MASK_EXT = { ".m_m.bm", ".l_m.bm", ".s_m.bm", ".t_m.bm" }; static final String DESKTOP_DATA = "Program_DESKTOP"; static final int DESKTOP_UNKNOWN = 0; - static final int DESKTOP_KDE = 1; - static final int DESKTOP_GNOME = 2; + static final int DESKTOP_GNOME = 1; + static final int DESKTOP_KDE = 2; + static final int DESKTOP_CDE = 3; static final int PREFERRED_ICON_SIZE = 16; /** @@ -56,6 +61,28 @@ static int getDesktop(Display display) { Integer desktopValue = (Integer)display.getData(DESKTOP_DATA); if (desktopValue != null) return desktopValue.intValue(); int desktop = DESKTOP_UNKNOWN; + + /* Get the list of properties on the root window. */ + int xDisplay = display.xDisplay; + int rootWindow = OS.XDefaultRootWindow(xDisplay); + int[] numProp = new int[1]; + int propList = OS.XListProperties(xDisplay, rootWindow, numProp); + int[] property = new int[numProp[0]]; + if (propList != 0) { + OS.memmove(property, propList, (property.length * 4)); + OS.XFree(propList); + } + + /* KDE is detected by checking if the the KWIN_RUNNING exists */ + if (desktop == DESKTOP_UNKNOWN) { + byte[] kdeName = Converter.wcsToMbcs(null, "KWIN_RUNNING", true); + int kde = OS.XInternAtom(xDisplay, kdeName, true); + for (int index = 0; desktop == DESKTOP_UNKNOWN && index < property.length; index++) { + if (property[index] == OS.None) continue; + if (property[index] == kde && kde_init()) desktop = DESKTOP_KDE; + } + } + /* * Feature in Linux Desktop. There is currently no official way to * determine whether the Gnome window manager or gnome-vfs is @@ -67,12 +94,346 @@ static int getDesktop(Display display) { * compliant one (property _NET_SUPPORTING_WM_CHECK) and to attempt to load * our native library that depends on gnome-vfs. */ + if (desktop == DESKTOP_UNKNOWN) { + byte[] gnomeName = Converter.wcsToMbcs(null, "_NET_SUPPORTING_WM_CHECK", true); + int gnome = OS.XInternAtom(xDisplay, gnomeName, true); + if (gnome != OS.None && gnome_init()) { + desktop = DESKTOP_GNOME; + } + } - if (isWindowManagerCompliant() && gnome_init()) desktop = DESKTOP_GNOME; + System.out.println("desktop=" + desktop); display.setData(DESKTOP_DATA, new Integer(desktop)); return desktop; } +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. */ + args.addElement(cmd.substring(sIndex + 1, eIndex)); + } + sIndex = eIndex + 1; + } + else { + /* Use white space for the delimiters. */ + 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; +} + +/** + * GNOME - Execute the program for the given file. + */ +boolean gnome_execute(String fileName) { + if (gnomeExpectUri) { + /* Convert the given path into a URL */ + fileName = "file://" + fileName; + } + + /* 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; +} + +/** + * GNOME - Get Image Data + * + */ +ImageData gnome_getImageData() { + if (iconPath == null) return null; + try { + return new ImageData(iconPath); + } catch (Exception e) {} + return null; +} + +/** + * GNOME - Get mime types + * + * 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. + */ +static Hashtable gnome_getMimeInfo() { + Hashtable mimeInfo = new Hashtable(); + int /*long*/[] mimeData = new int /*long*/[1]; + int /*long*/[] extensionData = new int /*long*/[1]; + int /*long*/ mimeList = GNOME.gnome_vfs_get_registered_mime_types(); + int /*long*/ mimeElement = mimeList; + while (mimeElement != 0) { + OS.memmove (mimeData, mimeElement, OS.PTR_SIZEOF); + int /*long*/ mimePtr = mimeData[0]; + int mimeLength = OS.strlen(mimePtr); + byte[] mimeTypeBuffer = new byte[mimeLength]; + OS.memmove(mimeTypeBuffer, mimePtr, mimeLength); + String mimeType = new String(Converter.mbcsToWcs(null, mimeTypeBuffer)); + int /*long*/ extensionList = GNOME.gnome_vfs_mime_get_extensions_list(mimePtr); + if (extensionList != 0) { + Vector extensions = new Vector(); + int /*long*/ extensionElement = extensionList; + while (extensionElement != 0) { + OS.memmove(extensionData, extensionElement, OS.PTR_SIZEOF); + int /*long*/ extensionPtr = extensionData[0]; + int extensionLength = OS.strlen(extensionPtr); + byte[] extensionBuffer = new byte[extensionLength]; + OS.memmove(extensionBuffer, extensionPtr, extensionLength); + String extension = new String(Converter.mbcsToWcs(null, extensionBuffer)); + extension = '.' + extension; + extensions.addElement(extension); + extensionElement = GNOME.g_list_next(extensionElement); + } + GNOME.gnome_vfs_mime_extensions_list_free(extensionList); + if (extensions.size() > 0) mimeInfo.put(mimeType, extensions); + } + mimeElement = GNOME.g_list_next(mimeElement); + } + if (mimeList != 0) GNOME.gnome_vfs_mime_registered_mime_type_list_free(mimeList); + return mimeInfo; +} + +static Program gnome_getProgram(Display display, String mimeType) { + Program program = null; + byte[] mimeTypeBuffer = Converter.wcsToMbcs(null, mimeType, true); + int /*long*/ ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); + if (ptr != 0) { + program = new Program(); + program.display = display; + program.name = mimeType; + GnomeVFSMimeApplication application = new GnomeVFSMimeApplication(); + GNOME.memmove(application, ptr, GnomeVFSMimeApplication.sizeof); + int length = OS.strlen(application.command); + byte[] buffer = new byte[length]; + OS.memmove(buffer, application.command, length); + program.command = new String(Converter.mbcsToWcs(null, buffer)); + program.gnomeExpectUri = application.expects_uris == GNOME.GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS; + + length = OS.strlen(application.id); + buffer = new byte[length + 1]; + OS.memmove(buffer, application.id, length); + /* + * Note. gnome_icon_theme_new uses g_object_new to allocate the data it returns. + * Use g_object_unref to free the pointer it returns. + */ + int /*long*/ icon_theme = GNOME.gnome_icon_theme_new(); + int /*long*/ icon_name = GNOME.gnome_icon_lookup(icon_theme, 0, null, buffer, 0, mimeTypeBuffer, + GNOME.GNOME_ICON_LOOKUP_FLAGS_NONE, null); + int /*long*/ path = 0; + if (icon_name != 0) path = GNOME.gnome_icon_theme_lookup_icon(icon_theme, icon_name, PREFERRED_ICON_SIZE, null, null); + GNOME.g_object_unref(icon_theme); + if (path != 0) { + length = OS.strlen(path); + if (length > 0) { + buffer = new byte[length]; + OS.memmove(buffer, path, length); + program.iconPath = new String(Converter.mbcsToWcs(null, buffer)); + } + GNOME.g_free(path); + } + if (icon_name != 0) GNOME.g_free(icon_name); + GNOME.gnome_vfs_mime_application_free(ptr); + } + return program; +} + +static boolean gnome_init() { + try { + return GNOME.gnome_vfs_init(); + } catch (Throwable e) { + return false; + } +} + +static String kde_convertQStringAndFree(int qString) { + if (qString == 0) return null; + int qCString = KDE.QString_utf8(qString); + int charString = KDE.QCString_data(qCString); + + int length = OS.strlen(charString); + byte[] buffer = new byte[length]; + OS.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; +} + +static boolean kde_init() { + try { + Library.loadLibrary("swt-kde"); + } catch (Throwable e) { + return false; + } + + /* Use the character encoding for the default locale */ + byte[] nameBuffer = Converter.wcsToMbcs(null, "SWT", true); + int qcString = KDE.QCString_new(nameBuffer); + int ptr = KDE.malloc(nameBuffer.length); + OS.memmove(ptr, nameBuffer, nameBuffer.length); + int[] argv = new int[]{ptr, 0}; + KDE.KApplication_new(1, argv, qcString, false, false); + KDE.free(ptr); + KDE.QCString_delete(qcString); + return true; +} + +boolean kde_execute(String fileName) { + String urlString = "file://" + fileName; + /* Use the character encoding for the default locale */ + byte[] buffer = Converter.wcsToMbcs(null, urlString, true); + int /*long*/ qString = KDE.QString_new(buffer); + int /*long*/ url = KDE.KURL_new(qString); + KDE.QString_delete(qString); + /* Use the character encoding for the default locale */ + buffer = Converter.wcsToMbcs(null, name, true); + int /*long*/ mimeTypeName = KDE.QString_new(buffer); + int pid = KDE.KRun_runURL(url, mimeTypeName); + KDE.KURL_delete(url); + KDE.QString_delete(mimeTypeName); + return pid != 0; +} + +ImageData kde_getImageData() { + if (iconPath == null) return null; + try { + return new ImageData(iconPath); + } catch (Exception e) {} + return null; +} + +static Hashtable kde_getMimeInfo() { + Hashtable mimeInfo = new Hashtable(); + Vector mimeExts = null; + String mimeType; + + /* Get the list of all mime types available. */ + int /*long*/ mimeTypeList = KDE.KMimeType_allMimeTypes(); + int /*long*/ iterator = KDE.KMimeTypeList_begin(mimeTypeList); + int /*long*/ listEnd = KDE.KMimeTypeList_end(mimeTypeList); + while (!KDE.KMimeTypeListIterator_equals(iterator, listEnd)) { + int /*long*/ kMimeType = KDE.KMimeTypeListIterator_dereference(iterator); + int /*long*/ 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 /*long*/ patternList = KDE.KMimeType_patterns(kMimeType); + int /*long*/ patIterator = KDE.QStringList_begin(patternList); + int /*long*/ patListEnd = KDE.QStringList_end(patternList); + while (!KDE.QStringListIterator_equals(patIterator, patListEnd)) { + /* Get the next extension pattern from the list. */ + int /*long*/ 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 Program kde_getProgram(Display display, String mimeType) { + Program program = null; + /* Use the character encoding for the default locale */ + byte[] buffer = Converter.wcsToMbcs(null, mimeType, true); + int /*long*/ mimeTypeName = KDE.QString_new(buffer); + int /*long*/ serviceList = KDE.KMimeType_offers(mimeTypeName); + if (serviceList != 0) { + KDE.KServiceList_delete(serviceList); + program = new Program(); + program.display = display; + program.name = mimeType; + program.command = "KRun::runURL(url,mimeType)"; + //TODO - LEAK?? + int /*long*/ kMimeType = KDE.KMimeType_mimeType(mimeTypeName); + if (kMimeType != 0) { + //TODO - LEAK?? + int /*long*/ mimeIcon = KDE.KMimeType_icon(kMimeType, 0, false); + int /*long*/ loader = KDE.KGlobal_iconLoader(); + int /*long*/ path = KDE.KIconLoader_iconPath(loader, mimeIcon, KDE.KICON_SMALL, true); + program.iconPath = kde_convertQStringAndFree(path); + } + + } + KDE.QString_delete(mimeTypeName); + return program; +} + /** * Finds the program that is associated with an extension. * The extension may or may not begin with a '.'. Note that @@ -98,27 +459,31 @@ 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 name = null; int desktop = getDesktop(display); Hashtable mimeInfo = null; - if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo(display); + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + } if (mimeInfo == null) return null; - - /* Find the data type matching the extension. */ + String mimeType = null; Enumeration keys = mimeInfo.keys(); - while (name == null && keys.hasMoreElements()) { - String mimeType = (String)keys.nextElement(); - Vector mimeExts = (Vector)mimeInfo.get(mimeType); + while (mimeType == null && keys.hasMoreElements()) { + String type = (String)keys.nextElement(); + Vector mimeExts = (Vector)mimeInfo.get(type); for (int index = 0; index < mimeExts.size(); index++){ if (extension.equals(mimeExts.elementAt(index))) { - name = mimeType; + mimeType = type; break; } } } - if (name == null) return null; + if (mimeType == null) return null; Program program = null; - if (desktop == DESKTOP_GNOME) program = gnome_getProgram(display, name); + switch (desktop) { + case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; + case DESKTOP_KDE: program = kde_getProgram(display, mimeType); break; + } return program; } @@ -140,7 +505,10 @@ public static String[] getExtensions() { static String[] getExtensions(Display display) { int desktop = getDesktop(display); Hashtable mimeInfo = null; - if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo(display); + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + } if (mimeInfo == null) return new String[0]; /* Create a unique set of the file extensions. */ @@ -182,20 +550,22 @@ public static Program[] getPrograms() { static Program[] getPrograms(Display display) { int desktop = getDesktop(display); Hashtable mimeInfo = null; - if (desktop == DESKTOP_GNOME) mimeInfo = gnome_getMimeInfo(display); + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + } if (mimeInfo == null) return new Program[0]; - - /* Create a list of programs with commands. */ Vector programs = new Vector(); Enumeration keys = mimeInfo.keys(); while (keys.hasMoreElements()) { String mimeType = (String)keys.nextElement(); Program program = null; - if (desktop == DESKTOP_GNOME) program = gnome_getProgram(display, mimeType); + switch (desktop) { + case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; + case DESKTOP_KDE: program = kde_getProgram(display, mimeType); break; + } if (program != null) 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); @@ -203,124 +573,6 @@ static Program[] getPrograms(Display display) { 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. - */ -static Hashtable gnome_getMimeInfo(Display display) { - Hashtable mimeInfo = new Hashtable(); - int /*long*/[] mimeData = new int /*long*/[1]; - int /*long*/[] extensionData = new int /*long*/[1]; - int /*long*/ mimeList = GNOME.gnome_vfs_get_registered_mime_types(); - int /*long*/ mimeElement = mimeList; - while (mimeElement != 0) { - OS.memmove (mimeData, mimeElement, OS.PTR_SIZEOF); - int /*long*/ mimePtr = mimeData[0]; - int mimeLength = OS.strlen(mimePtr); - byte[] mimeTypeBuffer = new byte[mimeLength]; - OS.memmove(mimeTypeBuffer, mimePtr, mimeLength); - String mimeType = new String(Converter.mbcsToWcs(null, mimeTypeBuffer)); - int /*long*/ extensionList = GNOME.gnome_vfs_mime_get_extensions_list(mimePtr); - if (extensionList != 0) { - Vector extensions = new Vector(); - int /*long*/ extensionElement = extensionList; - while (extensionElement != 0) { - OS.memmove(extensionData, extensionElement, OS.PTR_SIZEOF); - int /*long*/ extensionPtr = extensionData[0]; - int extensionLength = OS.strlen(extensionPtr); - byte[] extensionBuffer = new byte[extensionLength]; - OS.memmove(extensionBuffer, extensionPtr, extensionLength); - String extension = new String(Converter.mbcsToWcs(null, extensionBuffer)); - extension = '.' + extension; - extensions.addElement(extension); - extensionElement = GNOME.g_list_next(extensionElement); - } - GNOME.gnome_vfs_mime_extensions_list_free(extensionList); - if (extensions.size() > 0) mimeInfo.put(mimeType, extensions); - } - mimeElement = GNOME.g_list_next(mimeElement); - } - if (mimeList != 0) GNOME.gnome_vfs_mime_registered_mime_type_list_free(mimeList); - return mimeInfo; -} - -static Program gnome_getProgram(Display display, String mimeType) { - Program program = null; - GnomeVFSMimeApplication application = new GnomeVFSMimeApplication(); - byte[] mimeTypeBuffer = Converter.wcsToMbcs(null, mimeType, true); - int /*long*/ ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); - if (ptr != 0) { - program = new Program(); - program.display = display; - program.name = mimeType; - GNOME.memmove(application, ptr, GnomeVFSMimeApplication.sizeof); - int length = OS.strlen(application.command); - byte[] buffer = new byte[length]; - OS.memmove(buffer, application.command, length); - program.command = new String(Converter.mbcsToWcs(null, buffer)); - program.gnomeExpectUri = application.expects_uris == GNOME.GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS; - - length = OS.strlen(application.id); - buffer = new byte[length + 1]; - OS.memmove(buffer, application.id, length); - /* - * Note. gnome_icon_theme_new uses g_object_new to allocate the data it returns. - * Use g_object_unref to free the pointer it returns. - */ - int /*long*/ icon_theme = GNOME.gnome_icon_theme_new(); - int /*long*/ icon_name = GNOME.gnome_icon_lookup(icon_theme, 0, null, buffer, 0, mimeTypeBuffer, - GNOME.GNOME_ICON_LOOKUP_FLAGS_NONE, null); - int /*long*/ path = 0; - if (icon_name != 0) path = GNOME.gnome_icon_theme_lookup_icon(icon_theme, icon_name, PREFERRED_ICON_SIZE, null, null); - GNOME.g_object_unref(icon_theme); - if (path != 0) { - length = OS.strlen(path); - if (length > 0) { - buffer = new byte[length]; - OS.memmove(buffer, path, length); - String result = new String(Converter.mbcsToWcs(null, buffer)); - try { - program.imageData = new ImageData(result); - } catch (Exception e) { - } - } - GNOME.g_free(icon_name); - GNOME.g_free(path); - } - GNOME.gnome_vfs_mime_application_free(ptr); - } - return program; -} - -static boolean gnome_init() { - try { - return GNOME.gnome_vfs_init(); - } catch (Throwable e) { - return false; - } -} - -static boolean isWindowManagerCompliant() { - byte[] name = Converter.wcsToMbcs(null, "_NET_SUPPORTING_WM_CHECK", true); - /* - * Bug in GDK. The flag only_if_exists is ignored and gdk_atom_intern - * never returns GDK_NONE. The workaround is to not rely on this function - * to detect an atom. - */ - int /*long*/ atom = OS.gdk_atom_intern(name, true); - if (atom == OS.GDK_NONE) return false; - int /*long*/[] actualType = new int /*long*/[1]; - int[] actualFormat = new int[1]; - int[] actualLength = new int[1]; - int /*long*/[] data = new int /*long*/[1]; - if (!OS.gdk_property_get(OS.GDK_ROOT_PARENT(), atom, OS.XA_WINDOW, - 0, 1, 0, actualType, actualFormat, actualLength, data)) return false; - if (data[0] != 0) OS.g_free(data[0]); - return actualLength[0] > 0; -} - /** * Launches the executable associated with the file in * the operating system. If the file is an executable, @@ -366,52 +618,6 @@ static boolean launch(Display display, String fileName) { } } -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. */ - args.addElement(cmd.substring(sIndex+1, eIndex)); - } - sIndex = eIndex + 1; - } - else { - /* Use white space for the delimiters. */ - 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; -} - /** * Returns true if the receiver and the argument represent * the same program. @@ -420,12 +626,9 @@ static String[] parseCommand(String cmd) { */ public boolean equals(Object other) { if (this == other) return true; - if (other instanceof Program) { - final Program program = (Program)other; - return display == program.display && name.equals(program.name) && - command.equals(program.command); - } - return false; + if (!(other instanceof Program)) return false; + Program program = (Program)other; + return display == program.display && name.equals(program.name) && command.equals(program.command); } /** @@ -441,46 +644,13 @@ public boolean equals(Object other) { * <li>ERROR_NULL_ARGUMENT when fileName is null</li> * </ul> */ -public boolean execute (String fileName) { +public boolean execute(String fileName) { if (fileName == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); - int desktop = getDesktop(display); - if (desktop == DESKTOP_GNOME) { - if (gnomeExpectUri) { - /* Convert the given path into a URL */ - fileName = "file://" + fileName; - } - - /* 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; - } - + switch (desktop) { + case DESKTOP_GNOME: return gnome_execute(fileName); + case DESKTOP_KDE: return kde_execute(fileName); + } return false; } @@ -491,8 +661,12 @@ public boolean execute (String fileName) { * * @return the image data for the program, may be null */ -public ImageData getImageData () { - return imageData; +public ImageData getImageData() { + switch (getDesktop(display)) { + case DESKTOP_GNOME: return gnome_getImageData(); + case DESKTOP_KDE: return kde_getImageData(); + } + return null; } /** @@ -503,7 +677,7 @@ public ImageData getImageData () { * * @return an the name of the program */ -public String getName () { +public String getName() { return name; } diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde.cpp b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde.cpp index 37fe2d8ede..e32e02c3d8 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde.cpp +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde.cpp @@ -170,6 +170,16 @@ JNIEXPORT jint JNICALL KDE_NATIVE(KMimeType_1allMimeTypes) } #endif +#ifndef NO_KMimeType_1delete +JNIEXPORT void JNICALL KDE_NATIVE(KMimeType_1delete) + (JNIEnv *env, jclass that, jint arg0) +{ + KDE_NATIVE_ENTER(env, that, KMimeType_1delete_FUNC); + delete (KSharedPtr<KMimeType> *)arg0; + KDE_NATIVE_EXIT(env, that, KMimeType_1delete_FUNC); +} +#endif + #ifndef NO_KMimeType_1icon JNIEXPORT jint JNICALL KDE_NATIVE(KMimeType_1icon) (JNIEnv *env, jclass that, jint arg0, jint arg1, jboolean arg2) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.c b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.cpp index 721c6d97d6..cc9e6be00b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.cpp @@ -14,8 +14,8 @@ #ifdef NATIVE_STATS -int KDE_nativeFunctionCount = 36; -int KDE_nativeFunctionCallCount[36]; +int KDE_nativeFunctionCount = 37; +int KDE_nativeFunctionCallCount[37]; char * KDE_nativeFunctionNames[] = { "KApplication_1new", "KGlobal_1iconLoader", @@ -28,6 +28,7 @@ char * KDE_nativeFunctionNames[] = { "KMimeTypeList_1delete", "KMimeTypeList_1end", "KMimeType_1allMimeTypes", + "KMimeType_1delete", "KMimeType_1icon", "KMimeType_1mimeType", "KMimeType_1name", diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.h b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.h index 602f7630db..9d3427e97e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/library/kde_stats.h @@ -31,6 +31,7 @@ typedef enum { KMimeTypeList_1delete_FUNC, KMimeTypeList_1end_FUNC, KMimeType_1allMimeTypes_FUNC, + KMimeType_1delete_FUNC, KMimeType_1icon_FUNC, KMimeType_1mimeType_FUNC, KMimeType_1name_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/org/eclipse/swt/internal/kde/KDE.java b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/org/eclipse/swt/internal/kde/KDE.java index 3620e9c0ce..1a53736708 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/kde/org/eclipse/swt/internal/kde/KDE.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/kde/org/eclipse/swt/internal/kde/KDE.java @@ -19,6 +19,7 @@ public class KDE { public static final synchronized native int /*long*/ KApplication_new(int argc, int /*long*/ [] argv, int /*long*/ rAppName, boolean allowStyles, boolean GUIenabled); public static final synchronized native int /*long*/ KGlobal_iconLoader(); public static final synchronized native int /*long*/ KIconLoader_iconPath(int /*long*/ loader, int /*long*/ name, int group_or_size, boolean canReturnNull); +public static final synchronized native void KMimeType_delete(int /*long*/ mimeType); public static final synchronized native int /*long*/ KMimeType_mimeType(int /*long*/ _name); public static final synchronized native int /*long*/ KMimeType_icon(int /*long*/ mimeType, int /*long*/ unused1, boolean unused2); public static final synchronized native int /*long*/ KMimeType_name(int /*long*/ mimeType); diff --git a/bundles/org.eclipse.swt/Eclipse SWT Program/motif/org/eclipse/swt/program/Program.java b/bundles/org.eclipse.swt/Eclipse SWT Program/motif/org/eclipse/swt/program/Program.java index 70012b5154..858a722105 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT Program/motif/org/eclipse/swt/program/Program.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Program/motif/org/eclipse/swt/program/Program.java @@ -10,8 +10,7 @@ *******************************************************************************/ package org.eclipse.swt.program; -import java.io.*; -import java.util.*; + import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; @@ -21,16 +20,18 @@ import org.eclipse.swt.internal.cde.*; import org.eclipse.swt.internal.motif.*; import org.eclipse.swt.widgets.*; +import java.io.*; +import java.util.*; + /** * Instances of this class represent programs and * their assoicated file extensions in the operating * system. */ -public final class Program { - String command; - String extension; +public final class Program { String name; - ImageData imageData; + String command; + String iconPath; Display display; /* Gnome specific @@ -39,13 +40,13 @@ public final class Program { */ boolean gnomeExpectUri; - static final String CDE_SHELL = "Program_CDE_SHELL"; /* Hidden shell used for DtAppInitialize and DtActionInvoke */ + static final String SHELL_HANDLE_KEY = "org.eclipse.swt.internal.motif.shellHandle"; static final String[] CDE_ICON_EXT = { ".m.pm", ".l.pm", ".s.pm", ".t.pm" }; static final String[] CDE_MASK_EXT = { ".m_m.bm", ".l_m.bm", ".s_m.bm", ".t_m.bm" }; static final String DESKTOP_DATA = "Program_DESKTOP"; static final int DESKTOP_UNKNOWN = 0; - static final int DESKTOP_KDE = 1; - static final int DESKTOP_GNOME = 2; + static final int DESKTOP_GNOME = 1; + static final int DESKTOP_KDE = 2; static final int DESKTOP_CDE = 3; static final int PREFERRED_ICON_SIZE = 16; @@ -55,13 +56,88 @@ public final class Program { Program() { } -/* 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. - */ +/* Determine the desktop for the given display. */ +static int getDesktop(Display display) { + if (display == null) return DESKTOP_UNKNOWN; + Integer desktopValue = (Integer)display.getData(DESKTOP_DATA); + if (desktopValue != null) return desktopValue.intValue(); + int desktop = DESKTOP_UNKNOWN; + + /* Get the list of properties on the root window. */ + int xDisplay = display.xDisplay; + int rootWindow = OS.XDefaultRootWindow(xDisplay); + int[] numProp = new int[1]; + int propList = OS.XListProperties(xDisplay, rootWindow, numProp); + int[] property = new int[numProp[0]]; + if (propList != 0) { + OS.memmove(property, propList, (property.length * 4)); + OS.XFree(propList); + } + + /* KDE is detected by checking if the the KWIN_RUNNING exists */ + if (desktop == DESKTOP_UNKNOWN) { + byte[] kdeName = Converter.wcsToMbcs(null, "KWIN_RUNNING", true); + int kde = OS.XInternAtom(xDisplay, kdeName, true); + for (int index = 0; desktop == DESKTOP_UNKNOWN && index < property.length; index++) { + if (property[index] == OS.None) continue; + if (property[index] == kde && kde_init()) desktop = DESKTOP_KDE; + } + } + + /* + * Feature in Linux Desktop. There is currently no official way to + * determine whether the Gnome window manager or gnome-vfs is + * available. Earlier versions including Red Hat 9 and Suse 9 provide + * a documented Gnome specific property on the root window + * WIN_SUPPORTING_WM_CHECK. This property is no longer supported in newer + * versions such as Fedora Core 2. + * The workaround is to simply check that the window manager is a + * compliant one (property _NET_SUPPORTING_WM_CHECK) and to attempt to load + * our native library that depends on gnome-vfs. + */ + if (desktop == DESKTOP_UNKNOWN) { + byte[] gnomeName = Converter.wcsToMbcs(null, "_NET_SUPPORTING_WM_CHECK", true); + int gnome = OS.XInternAtom(xDisplay, gnomeName, true); + if (gnome != OS.None && gnome_init()) { + desktop = DESKTOP_GNOME; + } + } + + /* + * On CDE, the atom below may exist without DTWM running. If the atom + * below is defined, the CDE database exists and the available + * applications can be queried. + */ + if (desktop == DESKTOP_UNKNOWN) { + byte[] cdeName = Converter.wcsToMbcs(null, "_DT_SM_PREFERENCES", true); + int cde = OS.XInternAtom(xDisplay, cdeName, true); + 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] == cde && cde_init(display)) desktop = DESKTOP_CDE; + } + } + + display.setData(DESKTOP_DATA, new Integer(desktop)); + return desktop; +} + +boolean cde_execute(String fileName) { + /* 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(SHELL_HANDLE_KEY); + int actionID = 0; + if (shell != null) { + int ptr = OS.XtMalloc(fileArg.length); + OS.memmove(ptr, fileArg, fileArg.length); + DtActionArg args = new DtActionArg(); + args.argClass = CDE.DtACTION_FILE; + args.name = ptr; + actionID = CDE.DtActionInvoke(shell.intValue(), action, args, 1, null, null, null, 1, 0, 0); + OS.XtFree(ptr); + } + return actionID != 0; +} static String cde_getAction(String dataType) { String action = null; @@ -78,12 +154,6 @@ static String cde_getAction(String dataType) { return action; } -/* 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); @@ -99,13 +169,6 @@ static String cde_getAttribute(String dataType, String attrName) { return new String(Converter.mbcsToWcs(null, attrValueBuf)); } -/* 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; @@ -138,12 +201,6 @@ static Hashtable cde_getDataTypeInfo() { return dataTypeInfo; } -/* 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; @@ -151,11 +208,70 @@ static String cde_getExtension(String dataType) { return fileExt.substring(dot); } -/* CDE - Initialize +/** + * CDE - Get Image Data * - * This method loads the swt-cde library and initializes CDE itself. - * The shell created fo DtAppInitialize is kept for DtActionInvoke calls. + * 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() { + if (iconPath == null) return null; + 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)); + byte[] iconName; + byte[] maskName = null; + int pixmap = 0; + for (int index = 0; index < CDE_ICON_EXT.length && pixmap == 0; index++) { + /* Use the character encoding for the default locale */ + iconName = Converter.wcsToMbcs(null, iconPath + CDE_ICON_EXT[index], true); + maskName = Converter.wcsToMbcs(null, iconPath + CDE_MASK_EXT[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; +} + +static Program cde_getProgram(Display display, String mimeType) { + Program program = new Program(); + program.display = display; + program.name = mimeType; + program.command = cde_getAction(mimeType); + program.iconPath = cde_getAttribute(program.name, CDE.DtDTS_DA_ICON); + return program; +} + static boolean cde_init(Display display) { try { Library.loadLibrary("swt-cde"); @@ -166,240 +282,111 @@ static boolean cde_init(Display display) { /* 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(CDE_SHELL, 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 shellData = (Integer)Display.getCurrent().getData(CDE_SHELL); - if (shellData != null) OS.XtDestroyWidget(shellData.intValue()); - } - }); - } + Integer shell = (Integer)display.getData(SHELL_HANDLE_KEY); + boolean initOK = CDE.DtAppInitialize(xtContext, display.xDisplay, shell.intValue(), appName, appName); + if (initOK) CDE.DtDbLoad(); return initOK; } -/** - * Finds the program that is associated with an extension. - * The extension may or may not begin with a '.'. Note that - * a <code>Display</code> must already exist to guarantee that - * this method returns an appropriate result. - * - * @param extension the program extension - * @return the program or <code>null</code> - * - * @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. - */ -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 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. */ - Enumeration keys = mimeInfo.keys(); - while (name == null && keys.hasMoreElements()) { - String mimeType = (String)keys.nextElement(); - Vector mimeExts = (Vector)mimeInfo.get(mimeType); - for (int index = 0; index < mimeExts.size(); index++){ - if (extension.equals(mimeExts.elementAt(index))) { - name = mimeType; - break; - } +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 (name == null) return null; - Program program = null; - if (desktop == DESKTOP_GNOME) { - program = gnome_getProgram(display, name); - } else { - String command = null; - if (desktop == DESKTOP_KDE) command = kde_getMimeTypeCommand(name); - if (desktop == DESKTOP_CDE) command = cde_getAction(name); - if (command != null) { - program = new Program(); - program.name = name; - program.command = command; - program.extension = extension; - program.display = display; + 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. */ + args.addElement(cmd.substring(sIndex + 1, eIndex)); + } + sIndex = eIndex + 1; + } + else { + /* Use white space for the delimiters. */ + eIndex = sIndex; + while (eIndex < cmd.length() && !Compatibility.isWhitespace(cmd.charAt(eIndex))) eIndex++; + args.addElement(cmd.substring(sIndex, eIndex)); + sIndex = eIndex + 1; + } } } - return program; -} - -/* Determine the desktop for the given display. */ -static int getDesktop(Display display) { - if (display == null) return DESKTOP_UNKNOWN; - Integer desktopValue = (Integer)display.getData(DESKTOP_DATA); - if (desktopValue != null) return desktopValue.intValue(); - int desktop = DESKTOP_UNKNOWN; - if (isGnomeDesktop(display) && gnome_init()) { - desktop = DESKTOP_GNOME; - display.setData(DESKTOP_DATA, new Integer(desktop)); - return desktop; - } - - int xDisplay = display.xDisplay; - /* Use the character encoding for the default locale */ - byte[] cdeName = Converter.wcsToMbcs(null, "_DT_SM_PREFERENCES", true); - byte[] kdeName = Converter.wcsToMbcs(null, "KWIN_RUNNING", true); - /* Obtain the atoms for the various window manager signature properties. - * On CDE, the atom below may exist without DTWM running. If the atom - * below is defined, the CDE database exists and the available - * applications can be queried. - */ - 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] == cde && cde_init(display)) desktop = DESKTOP_CDE; - if (property[index] == kde && kde_init()) desktop = DESKTOP_KDE; + String[] strings = new String[args.size()]; + for (int index =0; index < args.size(); index++) { + strings[index] = (String)args.elementAt(index); } - - display.setData(DESKTOP_DATA, new Integer(desktop)); - return desktop; + return strings; } /** - * Answer all program extensions in the operating system. Note - * that a <code>Display</code> must already exist to guarantee - * that this method returns an appropriate result. - * - * @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. + * GNOME - Execute the program for the given file. */ -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]; +boolean gnome_execute(String fileName) { + if (gnomeExpectUri) { + /* Convert the given path into a URL */ + fileName = "file://" + fileName; + } - /* Create a unique set of the file extensions. */ - Vector extensions = new Vector(); - Enumeration keys = mimeInfo.keys(); - while (keys.hasMoreElements()) { - String mimeType = (String)keys.nextElement(); - 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)); - } + /* 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); } } - - /* 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. Note - * that a <code>Display</code> must already exist to guarantee - * that this method returns an appropriate result. - * - * @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. - */ -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(); - boolean[] gnomeExpectUri = null; - if (desktop == DESKTOP_GNOME) gnomeExpectUri = new boolean[1]; - Enumeration keys = mimeInfo.keys(); - while (keys.hasMoreElements()) { - String mimeType = (String)keys.nextElement(); - Vector mimeExts = (Vector)mimeInfo.get(mimeType); - String extension = ""; - if (mimeExts.size() > 0) extension = (String)mimeExts.elementAt(0); - Program program = null; - if (desktop == DESKTOP_GNOME) { - program = gnome_getProgram(display, mimeType); - } else { - String command = null; - if (desktop == DESKTOP_KDE) command = kde_getMimeTypeCommand(mimeType); - if (desktop == DESKTOP_CDE) command = cde_getAction(mimeType); - if (command != null) { - program = new Program(); - program.name = mimeType; - program.command = command; - program.extension = extension; - program.display = display; - } - } - if (program != null) programs.addElement(program); + /* 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; } - - /* 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); + + /* Execute the command. */ + try { + Compatibility.exec(args); + } catch (IOException e) { + return false; } - return programList; + return true; } -/* +/** + * GNOME - Get Image Data + * + */ +ImageData gnome_getImageData() { + if (iconPath == null) return null; + try { + return new ImageData(iconPath); + } catch (Exception e) {} + return null; +} + +/** + * GNOME - Get mime types + * * 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 @@ -407,24 +394,24 @@ static Program[] getPrograms(Display display) { */ static Hashtable gnome_getMimeInfo() { Hashtable mimeInfo = new Hashtable(); - int[] mimeData = new int[1]; - int[] extensionData = new int[1]; - int mimeList = GNOME.gnome_vfs_get_registered_mime_types(); - int mimeElement = mimeList; + int /*long*/[] mimeData = new int /*long*/[1]; + int /*long*/[] extensionData = new int /*long*/[1]; + int /*long*/ mimeList = GNOME.gnome_vfs_get_registered_mime_types(); + int /*long*/ mimeElement = mimeList; while (mimeElement != 0) { - OS.memmove (mimeData, mimeElement, 4); - int mimePtr = mimeData[0]; + OS.memmove (mimeData, mimeElement, OS.PTR_SIZEOF); + int /*long*/ mimePtr = mimeData[0]; int mimeLength = OS.strlen(mimePtr); byte[] mimeTypeBuffer = new byte[mimeLength]; OS.memmove(mimeTypeBuffer, mimePtr, mimeLength); String mimeType = new String(Converter.mbcsToWcs(null, mimeTypeBuffer)); - int extensionList = GNOME.gnome_vfs_mime_get_extensions_list(mimePtr); + int /*long*/ extensionList = GNOME.gnome_vfs_mime_get_extensions_list(mimePtr); if (extensionList != 0) { Vector extensions = new Vector(); - int extensionElement = extensionList; + int /*long*/ extensionElement = extensionList; while (extensionElement != 0) { - OS.memmove(extensionData, extensionElement, 4); - int extensionPtr = extensionData[0]; + OS.memmove(extensionData, extensionElement, OS.PTR_SIZEOF); + int /*long*/ extensionPtr = extensionData[0]; int extensionLength = OS.strlen(extensionPtr); byte[] extensionBuffer = new byte[extensionLength]; OS.memmove(extensionBuffer, extensionPtr, extensionLength); @@ -444,13 +431,13 @@ static Hashtable gnome_getMimeInfo() { static Program gnome_getProgram(Display display, String mimeType) { Program program = null; - GnomeVFSMimeApplication application = new GnomeVFSMimeApplication(); byte[] mimeTypeBuffer = Converter.wcsToMbcs(null, mimeType, true); - int ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); + int /*long*/ ptr = GNOME.gnome_vfs_mime_get_default_application(mimeTypeBuffer); if (ptr != 0) { program = new Program(); program.display = display; program.name = mimeType; + GnomeVFSMimeApplication application = new GnomeVFSMimeApplication(); GNOME.memmove(application, ptr, GnomeVFSMimeApplication.sizeof); int length = OS.strlen(application.command); byte[] buffer = new byte[length]; @@ -465,10 +452,10 @@ static Program gnome_getProgram(Display display, String mimeType) { * Note. gnome_icon_theme_new uses g_object_new to allocate the data it returns. * Use g_object_unref to free the pointer it returns. */ - int icon_theme = GNOME.gnome_icon_theme_new(); - int icon_name = GNOME.gnome_icon_lookup(icon_theme, 0, null, buffer, 0, mimeTypeBuffer, + int /*long*/ icon_theme = GNOME.gnome_icon_theme_new(); + int /*long*/ icon_name = GNOME.gnome_icon_lookup(icon_theme, 0, null, buffer, 0, mimeTypeBuffer, GNOME.GNOME_ICON_LOOKUP_FLAGS_NONE, null); - int path = 0; + int /*long*/ path = 0; if (icon_name != 0) path = GNOME.gnome_icon_theme_lookup_icon(icon_theme, icon_name, PREFERRED_ICON_SIZE, null, null); GNOME.g_object_unref(icon_theme); if (path != 0) { @@ -476,15 +463,11 @@ static Program gnome_getProgram(Display display, String mimeType) { if (length > 0) { buffer = new byte[length]; OS.memmove(buffer, path, length); - String result = new String(Converter.mbcsToWcs(null, buffer)); - try { - program.imageData = new ImageData(result); - } catch (Exception e) { - } + program.iconPath = new String(Converter.mbcsToWcs(null, buffer)); } - GNOME.g_free(icon_name); GNOME.g_free(path); } + if (icon_name != 0) GNOME.g_free(icon_name); GNOME.gnome_vfs_mime_application_free(ptr); } return program; @@ -498,14 +481,8 @@ static boolean gnome_init() { } } -static boolean isGnomeDesktop(Display display) { - int xDisplay = display.xDisplay; - byte[] name = Converter.wcsToMbcs(null, "_WIN_SUPPORTING_WM_CHECK", true); - int atom_set = OS.XInternAtom(xDisplay, name, true); - return atom_set != OS.None; -} - static String kde_convertQStringAndFree(int qString) { + if (qString == 0) return null; int qCString = KDE.QString_utf8(qString); int charString = KDE.QCString_data(qCString); @@ -530,33 +507,72 @@ static boolean kde_init() { /* Use the character encoding for the default locale */ byte[] nameBuffer = Converter.wcsToMbcs(null, "SWT", true); int qcString = KDE.QCString_new(nameBuffer); - int ptr = OS.XtMalloc(nameBuffer.length); + int ptr = KDE.malloc(nameBuffer.length); OS.memmove(ptr, nameBuffer, nameBuffer.length); int[] argv = new int[]{ptr, 0}; KDE.KApplication_new(1, argv, qcString, false, false); - OS.XtFree(ptr); + KDE.free(ptr); KDE.QCString_delete(qcString); return true; } -/* - * 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. - */ +boolean kde_execute(String fileName) { + String urlString = "file://" + fileName; + /* Use the character encoding for the default locale */ + byte[] buffer = Converter.wcsToMbcs(null, urlString, true); + int /*long*/ qString = KDE.QString_new(buffer); + int /*long*/ url = KDE.KURL_new(qString); + KDE.QString_delete(qString); + /* Use the character encoding for the default locale */ + buffer = Converter.wcsToMbcs(null, name, true); + int /*long*/ mimeTypeName = KDE.QString_new(buffer); + int pid = KDE.KRun_runURL(url, mimeTypeName); + KDE.KURL_delete(url); + KDE.QString_delete(mimeTypeName); + return pid != 0; +} + +ImageData kde_getImageData() { + if (iconPath == null) 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(); + imageData.transparentPixel = 0; + + /* 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; +} + 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); + int /*long*/ mimeTypeList = KDE.KMimeType_allMimeTypes(); + int /*long*/ iterator = KDE.KMimeTypeList_begin(mimeTypeList); + int /*long*/ listEnd = KDE.KMimeTypeList_end(mimeTypeList); while (!KDE.KMimeTypeListIterator_equals(iterator, listEnd)) { - int kMimeType = KDE.KMimeTypeListIterator_dereference(iterator); - int mimeName = KDE.KMimeType_name(kMimeType); + int /*long*/ kMimeType = KDE.KMimeTypeListIterator_dereference(iterator); + int /*long*/ mimeName = KDE.KMimeType_name(kMimeType); mimeType = kde_convertQStringAndFree(mimeName); /* Get the list of extension patterns. */ @@ -564,12 +580,12 @@ static Hashtable kde_getMimeInfo() { 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); + int /*long*/ patternList = KDE.KMimeType_patterns(kMimeType); + int /*long*/ patIterator = KDE.QStringList_begin(patternList); + int /*long*/ patListEnd = KDE.QStringList_end(patternList); while (!KDE.QStringListIterator_equals(patIterator, patListEnd)) { /* Get the next extension pattern from the list. */ - int patString = KDE.QStringListIterator_dereference(patIterator); + int /*long*/ patString = KDE.QStringListIterator_dereference(patIterator); extension = kde_convertQStringAndFree(patString); int period = extension.indexOf('.'); if (period != -1) mimeExts.addElement(extension.substring(period)); @@ -593,15 +609,175 @@ static Hashtable kde_getMimeInfo() { return mimeInfo; } -static String kde_getMimeTypeCommand(String mimeType) { +static Program kde_getProgram(Display display, String mimeType) { + Program program = null; /* 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)"; + int /*long*/ mimeTypeName = KDE.QString_new(buffer); + int /*long*/ serviceList = KDE.KMimeType_offers(mimeTypeName); + if (serviceList != 0) { + KDE.KServiceList_delete(serviceList); + program = new Program(); + program.display = display; + program.name = mimeType; + program.command = "KRun::runURL(url,mimeType)"; + int /*long*/ kMimeType = KDE.KMimeType_mimeType(mimeTypeName); + if (kMimeType != 0) { + int /*long*/ mimeIcon = KDE.KMimeType_icon(kMimeType, 0, false); + int /*long*/ loader = KDE.KGlobal_iconLoader(); + int /*long*/ path = KDE.KIconLoader_iconPath(loader, mimeIcon, KDE.KICON_SMALL, true); + program.iconPath = kde_convertQStringAndFree(path); + KDE.QString_delete(mimeIcon); + KDE.KMimeType_delete(kMimeType); + } + + } + KDE.QString_delete(mimeTypeName); + return program; +} + +/** + * Finds the program that is associated with an extension. + * The extension may or may not begin with a '.'. Note that + * a <code>Display</code> must already exist to guarantee that + * this method returns an appropriate result. + * + * @param extension the program extension + * @return the program or <code>null</code> + * + * @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. + */ +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; + int desktop = getDesktop(display); + Hashtable mimeInfo = null; + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break; + } + if (mimeInfo == null) return null; + String mimeType = null; + Enumeration keys = mimeInfo.keys(); + while (mimeType == null && keys.hasMoreElements()) { + String type = (String)keys.nextElement(); + Vector mimeExts = (Vector)mimeInfo.get(type); + for (int index = 0; index < mimeExts.size(); index++){ + if (extension.equals(mimeExts.elementAt(index))) { + mimeType = type; + break; + } + } + } + if (mimeType == null) return null; + Program program = null; + switch (desktop) { + case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; + case DESKTOP_KDE: program = kde_getProgram(display, mimeType); break; + case DESKTOP_CDE: program = cde_getProgram(display, mimeType); break; + } + return program; +} + +/** + * Answer all program extensions in the operating system. Note + * that a <code>Display</code> must already exist to guarantee + * that this method returns an appropriate result. + * + * @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. + */ +static String[] getExtensions(Display display) { + int desktop = getDesktop(display); + Hashtable mimeInfo = null; + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break; + } + if (mimeInfo == null) return new String[0]; + + /* Create a unique set of the file extensions. */ + Vector extensions = new Vector(); + Enumeration keys = mimeInfo.keys(); + while (keys.hasMoreElements()) { + String mimeType = (String)keys.nextElement(); + 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. Note + * that a <code>Display</code> must already exist to guarantee + * that this method returns an appropriate result. + * + * @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. + */ +static Program[] getPrograms(Display display) { + int desktop = getDesktop(display); + Hashtable mimeInfo = null; + switch (desktop) { + case DESKTOP_GNOME: mimeInfo = gnome_getMimeInfo(); break; + case DESKTOP_KDE: mimeInfo = kde_getMimeInfo(); break; + case DESKTOP_CDE: mimeInfo = cde_getDataTypeInfo(); break; + } + if (mimeInfo == null) return new Program[0]; + Vector programs = new Vector(); + Enumeration keys = mimeInfo.keys(); + while (keys.hasMoreElements()) { + String mimeType = (String)keys.nextElement(); + Program program = null; + switch (desktop) { + case DESKTOP_GNOME: program = gnome_getProgram(display, mimeType); break; + case DESKTOP_KDE: program = kde_getProgram(display, mimeType); break; + case DESKTOP_CDE: program = cde_getProgram(display, mimeType); break; + } + if (program != null) programs.addElement(program); + } + Program[] programList = new Program[programs.size()]; + for (int index = 0; index < programList.length; index++) { + programList[index] = (Program)programs.elementAt(index); + } + return programList; } /** @@ -631,7 +807,7 @@ static boolean launch(Display display, String fileName) { /* If the argument appears to be a data file (it has an extension) */ int index = fileName.lastIndexOf('.'); - if (index > 0) { + if (index > 0) { /* Find the associated program, if one is defined. */ String extension = fileName.substring(index); Program program = Program.findProgram(display, extension); @@ -649,49 +825,6 @@ static boolean launch(Display display, String fileName) { } } -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. */ - args.addElement(cmd.substring(sIndex + 1, eIndex)); - } - sIndex = eIndex + 1; - } - else { - /* Use white space for the delimiters. */ - 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; -} - /** * Returns true if the receiver and the argument represent * the same program. @@ -700,12 +833,9 @@ static String[] parseCommand(String cmd) { */ public boolean equals(Object other) { if (this == other) return true; - if (other instanceof Program) { - Program program = (Program)other; - return display == program.display && extension.equals(program.extension) && - name.equals(program.name) && command.equals(program.command); - } - return false; + if (!(other instanceof Program)) return false; + Program program = (Program)other; + return display == program.display && name.equals(program.name) && command.equals(program.command); } /** @@ -723,74 +853,11 @@ public boolean equals(Object other) { */ 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: { - if (gnomeExpectUri) { - /* convert the given path into a URL */ - fileName = "file://" + fileName; - } - - /* 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(CDE_SHELL); - int actionID = 0; - if (shell != null) { - int ptr = OS.XtMalloc(fileArg.length); - OS.memmove(ptr, fileArg, fileArg.length); - DtActionArg args = new DtActionArg(); - args.argClass = CDE.DtACTION_FILE; - args.name = ptr; - actionID = CDE.DtActionInvoke(shell.intValue(), action, args, 1, null, null, null, 1, 0, 0); - OS.XtFree(ptr); - } - return (actionID != 0); - } + int desktop = getDesktop(display); + switch (desktop) { + case DESKTOP_GNOME: return gnome_execute(fileName); + case DESKTOP_KDE: return kde_execute(fileName); + case DESKTOP_CDE: return cde_execute(fileName); } return false; } @@ -803,51 +870,12 @@ public boolean execute(String fileName) { * @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, false); - int loader = KDE.KGlobal_iconLoader(); - int path = KDE.KIconLoader_iconPath(loader, mimeIcon, KDE.KICON_SMALL, true); - if (path == 0) return null; - iconPath = kde_convertQStringAndFree(path); - break; - } - case DESKTOP_GNOME: return imageData; + case DESKTOP_GNOME: return gnome_getImageData(); + case DESKTOP_KDE: return kde_getImageData(); 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; } + return null; } /** @@ -868,66 +896,10 @@ public String getName() { * @return a hash code */ public int hashCode() { - return extension.hashCode() ^ name.hashCode() ^ command.hashCode() ^ display.hashCode(); + return name.hashCode() ^ command.hashCode() ^ display.hashCode(); } public String toString() { return "Program {" + name + "}"; } - -/* 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 < CDE_ICON_EXT.length && pixmap == 0; index++) { - /* Use the character encoding for the default locale */ - iconName = Converter.wcsToMbcs(null, icon + CDE_ICON_EXT[index], true); - maskName = Converter.wcsToMbcs(null, icon + CDE_MASK_EXT[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; -} } |