diff --git a/make/sun/xawt/FILES_c_unix.gmk b/make/sun/xawt/FILES_c_unix.gmk --- a/make/sun/xawt/FILES_c_unix.gmk +++ b/make/sun/xawt/FILES_c_unix.gmk @@ -79,4 +79,5 @@ gtk2_interface.c \ swing_GTKEngine.c \ swing_GTKStyle.c \ - rect.c + rect.c \ + sun_awt_X11_GtkFileDialogPeer.c diff --git a/make/sun/xawt/FILES_export_unix.gmk b/make/sun/xawt/FILES_export_unix.gmk --- a/make/sun/xawt/FILES_export_unix.gmk +++ b/make/sun/xawt/FILES_export_unix.gmk @@ -33,4 +33,5 @@ sun/awt/X11/XDesktopPeer.java \ sun/awt/X11/XToolkit.java \ sun/awt/X11/XComponentPeer.java \ - sun/awt/X11/XInputMethod.java + sun/awt/X11/XInputMethod.java \ + sun/awt/X11/GtkFileDialogPeer.java diff --git a/make/sun/xawt/mapfile-vers b/make/sun/xawt/mapfile-vers --- a/make/sun/xawt/mapfile-vers +++ b/make/sun/xawt/mapfile-vers @@ -172,6 +172,7 @@ Java_sun_awt_UNIXToolkit_load_1stock_1icon; Java_sun_awt_UNIXToolkit_load_1gtk_1icon; Java_sun_awt_UNIXToolkit_nativeSync; + Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl; Java_java_awt_AWTEvent_initIDs; Java_java_awt_event_InputEvent_initIDs; Java_java_awt_event_KeyEvent_initIDs; @@ -396,6 +397,9 @@ Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetClassValue; Java_com_sun_java_swing_plaf_gtk_GTKStyle_nativeGetPangoFontName; + Java_sun_awt_X11_GtkFileDialogPeer_run; + Java_sun_awt_X11_GtkFileDialogPeer_quit; + Java_sun_print_CUPSPrinter_initIDs; Java_sun_print_CUPSPrinter_getCupsServer; Java_sun_print_CUPSPrinter_getCupsPort; diff --git a/src/solaris/classes/sun/awt/UNIXToolkit.java b/src/solaris/classes/sun/awt/UNIXToolkit.java --- a/src/solaris/classes/sun/awt/UNIXToolkit.java +++ b/src/solaris/classes/sun/awt/UNIXToolkit.java @@ -314,4 +314,27 @@ } return new RenderingHints(KEY_TEXT_ANTIALIASING, aaHint); } + + private native boolean gtkCheckVersionImpl(int major, int minor, + int micro); + + /** + * Returns {@code true} if the GTK+ library is compatible with the given + * version. + * + * @param major + * The required major version. + * @param minor + * The required minor version. + * @param micro + * The required micro version. + * @return {@code true} if the GTK+ library is compatible with the given + * version. + */ + public boolean checkGtkVersion(int major, int minor, int micro) { + if(loadGTK()) { + return gtkCheckVersionImpl(major, minor, micro); + } + return false; + } } diff --git a/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java new file mode 100644 --- /dev/null +++ b/src/solaris/classes/sun/awt/X11/GtkFileDialogPeer.java @@ -0,0 +1,123 @@ +/* + * Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package sun.awt.X11; + +import java.awt.Dialog; +import java.awt.FileDialog; +import java.awt.peer.FileDialogPeer; +import java.io.File; +import java.io.FilenameFilter; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; + +/** + * FileDialogPeer for the GtkFileChooser. + * + * @author Costantino Cerbo (c.cerbo@gmail.com) + */ +class GtkFileDialogPeer extends XDialogPeer implements FileDialogPeer { + + private FileDialog fd; + + public GtkFileDialogPeer(FileDialog fd) { + super((Dialog) fd); + this.fd = fd; + } + + private native void run(String title, int mode, String dir, String file, + FilenameFilter filter); + + private native void quit(); + + /** + * Called exclusively by the native C code. + */ + private void setFileInternal(String filename) { + if (filename == null || filename.trim().isEmpty()) { + fd.setFile(null); + fd.setDirectory(null); + } else { + File filen = new File(filename); + fd.setFile(filen.getName()); + fd.setDirectory(filen.getParent() + File.separator); + } + } + + /** + * Called exclusively by the native C code. + */ + private boolean filenameFilterCallback(String fullname) { + if (fd.getFilenameFilter() == null) { + // no filter, accept all. + return true; + } + + File filen = new File(fullname); + return fd.getFilenameFilter().accept(new File(filen.getParent()), + filen.getName()); + } + + @Override + public void setVisible(boolean b) { + XToolkit.awtLock(); + try { + if (b) { + run(fd.getTitle(), fd.getMode(), fd.getDirectory(), + fd.getFile(), fd.getFilenameFilter()); + + fd.setVisible(false); + } else { + quit(); + fd.setVisible(false); + } + } finally { + XToolkit.awtUnlock(); + } + } + + @Override + public void dispose() { + quit(); + super.dispose(); + } + + @Override + public void setDirectory(String dir) { + // We do not implement this method because we + // have delegated to FileDialog#setDirectory + } + + @Override + public void setFile(String file) { + // We do not implement this method because we + // have delegated to FileDialog#setFile + } + + @Override + public void setFilenameFilter(FilenameFilter filter) { + // We do not implement this method because we + // have delegated to FileDialog#setFilenameFilter + } +} diff --git a/src/solaris/classes/sun/awt/X11/XToolkit.java b/src/solaris/classes/sun/awt/X11/XToolkit.java --- a/src/solaris/classes/sun/awt/X11/XToolkit.java +++ b/src/solaris/classes/sun/awt/X11/XToolkit.java @@ -1041,7 +1041,9 @@ } public FileDialogPeer createFileDialog(FileDialog target) { - FileDialogPeer peer = new XFileDialogPeer(target); + // The current GtkFileChooser is available from GTK+ 2.4 + FileDialogPeer peer = checkGtkVersion(2, 4, 0) ? new GtkFileDialogPeer( + target) : new XFileDialogPeer(target); targetCreatedPeer(target, peer); return peer; } diff --git a/src/solaris/native/sun/awt/awt_UNIXToolkit.c b/src/solaris/native/sun/awt/awt_UNIXToolkit.c --- a/src/solaris/native/sun/awt/awt_UNIXToolkit.c +++ b/src/solaris/native/sun/awt/awt_UNIXToolkit.c @@ -260,3 +260,21 @@ } dlclose(hSplashLib); } + +/* + * Class: sun_awt_UNIXToolkit + * Method: gtkCheckVersionImpl + * Signature: (III)Ljava/lang/String; + */ +JNIEXPORT jboolean JNICALL +Java_sun_awt_UNIXToolkit_gtkCheckVersionImpl + (JNIEnv *env, jobject this, jint major, jint minor, jint micro) +{ + char *ret = fp_gtk_check_version(major, minor, micro); + if (ret == NULL) { + return TRUE; + } + + free(ret); + return FALSE; +} diff --git a/src/solaris/native/sun/awt/gtk2_interface.c b/src/solaris/native/sun/awt/gtk2_interface.c --- a/src/solaris/native/sun/awt/gtk2_interface.c +++ b/src/solaris/native/sun/awt/gtk2_interface.c @@ -32,6 +32,7 @@ #include "java_awt_Transparency.h" #define GTK2_LIB "libgtk-x11-2.0.so.0" +#define GTHREAD_LIB "libgthread-2.0.so" #define G_TYPE_INVALID G_TYPE_MAKE_FUNDAMENTAL (0) #define G_TYPE_NONE G_TYPE_MAKE_FUNDAMENTAL (1) @@ -75,6 +76,7 @@ const gint DEFAULT = 1 << 10; static void *gtk2_libhandle = NULL; +static void *gthread_libhandle = NULL; static jmp_buf j; /* Widgets */ @@ -150,7 +152,6 @@ /************************* * Glib function pointers *************************/ -static void (*fp_g_free)(gpointer mem); static gboolean (*fp_g_main_context_iteration)(GMainContext *context, gboolean may_block); @@ -204,9 +205,6 @@ /************************ * Gtk function pointers ************************/ -static gchar* (*fp_gtk_check_version)(guint required_major, - guint required_minor, - guint required_micro); static gboolean (*fp_gtk_init_check)(int* argc, char** argv); /* Painting */ @@ -330,7 +328,6 @@ static void (*fp_gtk_menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu); static void (*fp_gtk_widget_realize)(GtkWidget *widget); -static void (*fp_gtk_widget_destroy)(GtkWidget *widget); static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget, const gchar *stock_id, GtkIconSize size, const gchar *detail); static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name); @@ -388,6 +385,15 @@ return result; } +static void* dl_symbol_gthread(const char* name) +{ + void* result = dlsym(gthread_libhandle, name); + if (!result) + longjmp(j, NO_SYMBOL_EXCEPTION); + + return result; +} + gboolean gtk2_check_version() { if (gtk2_libhandle != NULL) { @@ -414,6 +420,26 @@ } } +/** + * Functions for sun_awt_X11_GtkFileDialogPeer.c + */ +void gtk2_file_chooser_load() +{ + fp_gtk_file_chooser_get_filename = dl_symbol( + "gtk_file_chooser_get_filename"); + fp_gtk_file_chooser_dialog_new = dl_symbol("gtk_file_chooser_dialog_new"); + fp_gtk_file_chooser_set_current_folder = dl_symbol( + "gtk_file_chooser_set_current_folder"); + fp_gtk_file_chooser_set_filename = dl_symbol( + "gtk_file_chooser_set_filename"); + fp_gtk_file_filter_add_custom = dl_symbol("gtk_file_filter_add_custom"); + fp_gtk_file_chooser_set_filter = dl_symbol("gtk_file_chooser_set_filter"); + fp_gtk_file_chooser_get_type = dl_symbol("gtk_file_chooser_get_type"); + fp_gtk_file_filter_new = dl_symbol("gtk_file_filter_new"); + fp_gtk_file_chooser_set_do_overwrite_confirmation = dl_symbol( + "gtk_file_chooser_set_do_overwrite_confirmation"); +} + gboolean gtk2_load() { gboolean result; @@ -423,7 +449,9 @@ char *gtk_modules_env; gtk2_libhandle = dlopen(GTK2_LIB, RTLD_LAZY | RTLD_LOCAL); - if (gtk2_libhandle == NULL) + gthread_libhandle = dlopen(GTHREAD_LIB, RTLD_LAZY | RTLD_LOCAL); + + if (gtk2_libhandle == NULL || gthread_libhandle == NULL) return FALSE; if (setjmp(j) == 0) @@ -597,6 +625,29 @@ fp_gtk_range_get_adjustment = dl_symbol("gtk_range_get_adjustment"); + fp_gtk_widget_hide = dl_symbol("gtk_widget_hide"); + fp_gtk_main_quit = dl_symbol("gtk_main_quit"); + fp_g_signal_connect_data = dl_symbol("g_signal_connect_data"); + fp_gtk_widget_show = dl_symbol("gtk_widget_show"); + fp_gtk_main = dl_symbol("gtk_main"); + + /** + * GLib thread system + */ + fp_g_thread_get_initialized = dl_symbol_gthread("g_thread_get_initialized"); + fp_g_thread_init = dl_symbol_gthread("g_thread_init"); + fp_gdk_threads_init = dl_symbol("gdk_threads_init"); + fp_gdk_threads_enter = dl_symbol("gdk_threads_enter"); + fp_gdk_threads_leave = dl_symbol("gdk_threads_leave"); + + /** + * Functions for sun_awt_X11_GtkFileDialogPeer.c + */ + if (fp_gtk_check_version(2, 4, 0) == NULL) { + // The current GtkFileChooser is available from GTK+ 2.4 + gtk2_file_chooser_load(); + } + /* Some functions may be missing in pre-2.4 GTK. We handle them specially here. */ @@ -626,6 +677,10 @@ { dlclose(gtk2_libhandle); gtk2_libhandle = NULL; + + dlclose(gthread_libhandle); + gthread_libhandle = NULL; + return FALSE; } @@ -678,6 +733,19 @@ */ handler = XSetErrorHandler(NULL); io_handler = XSetIOErrorHandler(NULL); + + if (fp_gtk_check_version(2, 2, 0) == NULL) + { + // Init the thread system to use GLib in a thread-safe mode + if (!fp_g_thread_get_initialized()) + { + fp_g_thread_init(NULL); + + //According the GTK documentation, gdk_threads_init() should be + //called before gtk_init() or gtk_init_check() + fp_gdk_threads_init(); + } + } result = (*fp_gtk_init_check)(NULL, NULL); XSetErrorHandler(handler); @@ -722,6 +790,7 @@ dlerror(); dlclose(gtk2_libhandle); + dlclose(gthread_libhandle); if ((gtk2_error = dlerror()) != NULL) { return FALSE; diff --git a/src/solaris/native/sun/awt/gtk2_interface.h b/src/solaris/native/sun/awt/gtk2_interface.h --- a/src/solaris/native/sun/awt/gtk2_interface.h +++ b/src/solaris/native/sun/awt/gtk2_interface.h @@ -28,6 +28,21 @@ #include #include +#define _G_TYPE_CIC(ip, gt, ct) ((ct*) ip) +#define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type) (_G_TYPE_CIC ((instance), (g_type), c_type)) +#define GTK_TYPE_FILE_CHOOSER (fp_gtk_file_chooser_get_type ()) +#define GTK_FILE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FILE_CHOOSER, GtkFileChooser)) +#define fp_g_signal_connect(instance, detailed_signal, c_handler, data) \ + fp_g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) +#define G_CALLBACK(f) ((GCallback) (f)) +#define G_TYPE_FUNDAMENTAL_SHIFT (2) +#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT)) +#define G_TYPE_OBJECT G_TYPE_MAKE_FUNDAMENTAL (20) +#define G_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_OBJECT, GObject)) +#define GTK_STOCK_CANCEL "gtk-cancel" +#define GTK_STOCK_SAVE "gtk-save" +#define GTK_STOCK_OPEN "gtk-open" + typedef enum _WidgetType { BUTTON, /* GtkButton */ @@ -556,6 +571,66 @@ guint ellipsize : 3; }; +typedef enum { + GTK_RESPONSE_NONE = -1, + GTK_RESPONSE_REJECT = -2, + GTK_RESPONSE_ACCEPT = -3, + GTK_RESPONSE_DELETE_EVENT = -4, + GTK_RESPONSE_OK = -5, + GTK_RESPONSE_CANCEL = -6, + GTK_RESPONSE_CLOSE = -7, + GTK_RESPONSE_YES = -8, + GTK_RESPONSE_NO = -9, + GTK_RESPONSE_APPLY = -10, + GTK_RESPONSE_HELP = -11 +} GtkResponseType; + +typedef struct _GtkWindow GtkWindow; + +typedef struct _GtkFileChooser GtkFileChooser; + +typedef enum { + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, + GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER +} GtkFileChooserAction; + +typedef struct _GtkFileFilter GtkFileFilter; + +typedef enum { + GTK_FILE_FILTER_FILENAME = 1 << 0, + GTK_FILE_FILTER_URI = 1 << 1, + GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2, + GTK_FILE_FILTER_MIME_TYPE = 1 << 3 +} GtkFileFilterFlags; + +typedef struct { + GtkFileFilterFlags contains; + + const gchar *filename; + const gchar *uri; + const gchar *display_name; + const gchar *mime_type; +} GtkFileFilterInfo; + +typedef gboolean (*GtkFileFilterFunc)(const GtkFileFilterInfo *filter_info, + gpointer data); + +typedef void (*GDestroyNotify)(gpointer data); + +typedef void (*GCallback)(void); + +typedef struct _GClosure GClosure; + +typedef void (*GClosureNotify)(gpointer data, GClosure *closure); + +typedef enum { + G_CONNECT_AFTER = 1 << 0, G_CONNECT_SWAPPED = 1 << 1 +} GConnectFlags; + +typedef struct _GThreadFunctions GThreadFunctions; + /* * Converts java.lang.String object to UTF-8 character string. */ @@ -569,6 +644,13 @@ */ gboolean gtk2_check_version(); +/** + * Returns : + * NULL if the GTK+ library is compatible with the given version, or a string + * describing the version mismatch. + */ +gchar* (*fp_gtk_check_version)(guint required_major, guint required_minor, + guint required_micro); /* * Load the gtk2 library. If the library is already loaded this method has no * effect and returns success. @@ -651,6 +733,7 @@ void gtk2_set_range_value(WidgetType widget_type, jdouble value, jdouble min, jdouble max, jdouble visible); +void (*fp_g_free)(gpointer mem); void (*fp_g_object_unref)(gpointer object); int (*fp_gdk_pixbuf_get_bits_per_sample)(const GdkPixbuf *pixbuf); guchar *(*fp_gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf); @@ -660,5 +743,41 @@ int (*fp_gdk_pixbuf_get_rowstride)(const GdkPixbuf *pixbuf); int (*fp_gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf); GdkPixbuf *(*fp_gdk_pixbuf_new_from_file)(const char *filename, GError **error); +void (*fp_gtk_widget_destroy)(GtkWidget *widget); + + +/** + * Function Pointers for GtkFileChooser + */ +gchar* (*fp_gtk_file_chooser_get_filename)(GtkFileChooser *chooser); +void (*fp_gtk_widget_hide)(GtkWidget *widget); +void (*fp_gtk_main_quit)(void); +GtkWidget* (*fp_gtk_file_chooser_dialog_new)(const gchar *title, + GtkWindow *parent, GtkFileChooserAction action, + const gchar *first_button_text, ...); +gboolean (*fp_gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser, + const gchar *filename); +gboolean (*fp_gtk_file_chooser_set_filename)(GtkFileChooser *chooser, + const char *filename); +void (*fp_gtk_file_filter_add_custom)(GtkFileFilter *filter, + GtkFileFilterFlags needed, GtkFileFilterFunc func, gpointer data, + GDestroyNotify notify); +void (*fp_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, + GtkFileFilter *filter); +GType (*fp_gtk_file_chooser_get_type)(void); +GtkFileFilter* (*fp_gtk_file_filter_new)(void); +void (*fp_gtk_file_chooser_set_do_overwrite_confirmation)( + GtkFileChooser *chooser, gboolean do_overwrite_confirmation); +gulong (*fp_g_signal_connect_data)(gpointer instance, + const gchar *detailed_signal, GCallback c_handler, gpointer data, + GClosureNotify destroy_data, GConnectFlags connect_flags); +void (*fp_gtk_widget_show)(GtkWidget *widget); +void (*fp_gtk_main)(void); + +gboolean (*fp_g_thread_get_initialized)(void); +void (*fp_g_thread_init)(GThreadFunctions *vtable); +void (*fp_gdk_threads_init)(void); +void (*fp_gdk_threads_enter)(void); +void (*fp_gdk_threads_leave)(void); #endif /* !_GTK2_INTERFACE_H */ diff --git a/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c new file mode 100644 --- /dev/null +++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c @@ -0,0 +1,137 @@ +#include +#include +#include "gtk2_interface.h" +#include "sun_awt_X11_GtkFileDialogPeer.h" + +static JavaVM *jvm; +static GtkWidget *dialog = NULL; + +// In order to Cache some method IDs +static jmethodID filenameFilterCallbackMethodID = NULL; +static jmethodID setFileInternalMethodID = NULL; + +static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, + gpointer obj) +{ + JNIEnv *env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + + if (filenameFilterCallbackMethodID == NULL) { + jclass cx = (*env)->GetObjectClass(env, (jobject) obj); + filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx, + "filenameFilterCallback", "(Ljava/lang/String;)Z"); + } + + jstring filename = (*env)->NewStringUTF(env, filter_info->filename); + + return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID, + filename); +} + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: hide + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit +(JNIEnv * env, jobject jpeer) +{ + if (dialog != NULL) + { + fp_gtk_widget_hide (dialog); + fp_gtk_widget_destroy (dialog); + + fp_gtk_main_quit (); + dialog = NULL; + } +} + +static void handle_response(GtkWidget * aDialog, gint responseId, gpointer obj) +{ + JNIEnv *env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2); + + char *filename = NULL; + + if (responseId == GTK_RESPONSE_ACCEPT) { + filename = fp_gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(aDialog)); + } + + if (setFileInternalMethodID == NULL) { + jclass cx = (*env)->GetObjectClass(env, (jobject) obj); + setFileInternalMethodID = (*env)->GetMethodID(env, cx, + "setFileInternal", "(Ljava/lang/String;)V"); + } + + jstring jfilename = (*env)->NewStringUTF(env, filename); + + (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jfilename); + fp_g_free(filename); + + Java_sun_awt_X11_GtkFileDialogPeer_quit(NULL, NULL); +} + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: show + * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;)V + */ +JNIEXPORT void JNICALL +Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer, + jstring jtitle, jint mode, jstring jdir, jstring jfile, jobject jfilter) +{ + if (jvm == NULL) { + (*env)->GetJavaVM(env, &jvm); + } + + const char *title = (*env)->GetStringUTFChars(env, jtitle, 0); + + if (mode == 1) { + // Save action + dialog = fp_gtk_file_chooser_dialog_new(title, NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); + } else { + // Default action OPEN + dialog = fp_gtk_file_chooser_dialog_new(title, NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + } + + (*env)->ReleaseStringUTFChars(env, jtitle, title); + + // Set the directory + if (jdir != NULL) { + const char *dir = (*env)->GetStringUTFChars(env, jdir, 0); + fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir); + (*env)->ReleaseStringUTFChars(env, jdir, dir); + } + + // Set the filename + if (jfile != NULL) { + const char *filename = (*env)->GetStringUTFChars(env, jfile, 0); + fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename); + (*env)->ReleaseStringUTFChars(env, jfile, filename); + } + + // Set the file filter + if (jfilter != NULL) { + GtkFileFilter *filter; + filter = fp_gtk_file_filter_new(); + fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, + filenameFilterCallback, jpeer, NULL); + fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter); + } + + //Other Properties + if (fp_gtk_check_version(2, 8, 0) == NULL) { + fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER( + dialog), TRUE); + } + + fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK( + handle_response), jpeer); + fp_gtk_widget_show(dialog); + + fp_gdk_threads_enter(); + fp_gtk_main(); + fp_gdk_threads_leave(); +} diff --git a/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h new file mode 100644 --- /dev/null +++ b/src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.h @@ -0,0 +1,31 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class sun_awt_X11_GtkFileDialogPeer */ + +#ifndef _Included_sun_awt_X11_GtkFileDialogPeer +#define _Included_sun_awt_X11_GtkFileDialogPeer +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: run + * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;)V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_run + (JNIEnv *, jobject, jstring, jint, jstring, jstring, jobject); + +/* + * Class: sun_awt_X11_GtkFileDialogPeer + * Method: quit + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit + (JNIEnv *, jobject); + +#ifdef __cplusplus +} +#endif +#endif