annotate src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c @ 3225:4becb3dd7861

6998592: FileDialog tests crashed on solaris Summary: Override GtkFileDialogPeer.toFront() Reviewed-by: art, dcherepanov
author anthony
date Tue, 30 Nov 2010 17:36:56 +0300
parents 9c7c5ecea41a
children 78364959fc73
rev   line source
anthony@2452 1 #include <jni.h>
anthony@2452 2 #include <stdio.h>
anthony@2452 3 #include <jni_util.h>
anthony@2452 4 #include <string.h>
anthony@2452 5 #include "gtk2_interface.h"
anthony@2452 6 #include "sun_awt_X11_GtkFileDialogPeer.h"
anthony@3168 7 #include "debug_assert.h"
anthony@2452 8
anthony@2452 9 static JavaVM *jvm;
anthony@2452 10
anthony@2452 11 /* To cache some method IDs */
anthony@2452 12 static jmethodID filenameFilterCallbackMethodID = NULL;
anthony@2452 13 static jmethodID setFileInternalMethodID = NULL;
anthony@3168 14 static jfieldID widgetFieldID = NULL;
anthony@3168 15
anthony@3168 16 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_initIDs
anthony@3168 17 (JNIEnv *env, jclass cx)
anthony@3168 18 {
anthony@3168 19 filenameFilterCallbackMethodID = (*env)->GetMethodID(env, cx,
anthony@3168 20 "filenameFilterCallback", "(Ljava/lang/String;)Z");
anthony@3168 21 DASSERT(filenameFilterCallbackMethodID != NULL);
anthony@3168 22
anthony@3168 23 setFileInternalMethodID = (*env)->GetMethodID(env, cx,
anthony@3168 24 "setFileInternal", "(Ljava/lang/String;[Ljava/lang/String;)V");
anthony@3168 25 DASSERT(setFileInternalMethodID != NULL);
anthony@3168 26
anthony@3168 27 widgetFieldID = (*env)->GetFieldID(env, cx, "widget", "J");
anthony@3168 28 DASSERT(widgetFieldID != NULL);
anthony@3168 29 }
anthony@2452 30
anthony@2452 31 static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gpointer obj)
anthony@2452 32 {
anthony@2452 33 JNIEnv *env;
anthony@2452 34 jclass cx;
anthony@2452 35 jstring filename;
anthony@2452 36
anthony@2452 37 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
anthony@2452 38
anthony@2452 39 filename = (*env)->NewStringUTF(env, filter_info->filename);
anthony@2452 40
anthony@2452 41 return (*env)->CallBooleanMethod(env, obj, filenameFilterCallbackMethodID,
anthony@2452 42 filename);
anthony@2452 43 }
anthony@2452 44
anthony@3168 45 static void quit(JNIEnv * env, jobject jpeer, gboolean isSignalHandler)
dcherepanov@2649 46 {
anthony@3168 47 GtkWidget * dialog = (GtkWidget*)jlong_to_ptr(
anthony@3168 48 (*env)->GetLongField(env, jpeer, widgetFieldID));
anthony@3168 49
dcherepanov@2649 50 if (dialog != NULL)
dcherepanov@2649 51 {
dcherepanov@2649 52 // Callbacks from GTK signals are made within the GTK lock
dcherepanov@2649 53 // So, within a signal handler there is no need to call
dcherepanov@2649 54 // gdk_threads_enter() / fp_gdk_threads_leave()
dcherepanov@2649 55 if (!isSignalHandler) {
dcherepanov@2649 56 fp_gdk_threads_enter();
dcherepanov@2649 57 }
dcherepanov@2649 58
dcherepanov@2649 59 fp_gtk_widget_hide (dialog);
dcherepanov@2649 60 fp_gtk_widget_destroy (dialog);
dcherepanov@2649 61
dcherepanov@2649 62 fp_gtk_main_quit ();
anthony@3168 63
anthony@3168 64 (*env)->SetLongField(env, jpeer, widgetFieldID, 0);
dcherepanov@2649 65
dcherepanov@2649 66 if (!isSignalHandler) {
dcherepanov@2649 67 fp_gdk_threads_leave();
dcherepanov@2649 68 }
dcherepanov@2649 69 }
dcherepanov@2649 70 }
dcherepanov@2649 71
anthony@2452 72 /*
anthony@2452 73 * Class: sun_awt_X11_GtkFileDialogPeer
anthony@2452 74 * Method: quit
anthony@2452 75 * Signature: ()V
anthony@2452 76 */
anthony@2452 77 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
anthony@2452 78 (JNIEnv * env, jobject jpeer)
anthony@2452 79 {
anthony@3168 80 quit(env, jpeer, FALSE);
anthony@2452 81 }
anthony@2452 82
anthony@3225 83 /*
anthony@3225 84 * Class: sun_awt_X11_GtkFileDialogPeer
anthony@3225 85 * Method: toFront
anthony@3225 86 * Signature: ()V
anthony@3225 87 */
anthony@3225 88 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_toFront
anthony@3225 89 (JNIEnv * env, jobject jpeer)
anthony@3225 90 {
anthony@3225 91 GtkWidget * dialog;
anthony@3225 92
anthony@3225 93 fp_gdk_threads_enter();
anthony@3225 94
anthony@3225 95 dialog = (GtkWidget*)jlong_to_ptr(
anthony@3225 96 (*env)->GetLongField(env, jpeer, widgetFieldID));
anthony@3225 97
anthony@3225 98 if (dialog != NULL) {
anthony@3225 99 fp_gtk_window_present((GtkWindow*)dialog);
anthony@3225 100 }
anthony@3225 101
anthony@3225 102 fp_gdk_threads_leave();
anthony@3225 103 }
anthony@3225 104
anthony@2452 105 /**
anthony@2452 106 * Convert a GSList to an array of filenames (without the parent folder)
anthony@2452 107 */
anthony@2452 108 static jobjectArray toFilenamesArray(JNIEnv *env, GSList* list)
anthony@2452 109 {
anthony@2452 110 jstring str;
anthony@2452 111 jclass stringCls;
anthony@2452 112 GSList *iterator;
anthony@2452 113 jobjectArray array;
anthony@2452 114 int i;
anthony@2452 115 char* entry;
anthony@2452 116
anthony@2452 117 if (NULL == list) {
anthony@2452 118 return NULL;
anthony@2452 119 }
anthony@2452 120
anthony@2452 121 stringCls = (*env)->FindClass(env, "java/lang/String");
anthony@2452 122 if (stringCls == NULL) {
anthony@2452 123 JNU_ThrowInternalError(env, "Could not get java.lang.String class");
anthony@2452 124 return NULL;
anthony@2452 125 }
anthony@2452 126
anthony@2452 127 array = (*env)->NewObjectArray(env, fp_gtk_g_slist_length(list), stringCls,
anthony@2452 128 NULL);
anthony@2452 129 if (array == NULL) {
anthony@2452 130 JNU_ThrowInternalError(env, "Could not instantiate array files array");
anthony@2452 131 return NULL;
anthony@2452 132 }
anthony@2452 133
anthony@2452 134 i = 0;
anthony@2452 135 for (iterator = list; iterator; iterator = iterator->next) {
anthony@2452 136 entry = (char*) iterator->data;
anthony@2452 137 entry = strrchr(entry, '/') + 1;
anthony@2452 138 str = (*env)->NewStringUTF(env, entry);
anthony@2452 139 (*env)->SetObjectArrayElement(env, array, i, str);
anthony@2452 140 i++;
anthony@2452 141 }
anthony@2452 142
anthony@2452 143 return array;
anthony@2452 144 }
anthony@2452 145
anthony@2452 146 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
anthony@2452 147 {
anthony@2452 148 JNIEnv *env;
anthony@2452 149 char *current_folder;
anthony@2452 150 GSList *filenames;
anthony@2452 151 jclass cx;
anthony@2452 152 jstring jcurrent_folder;
anthony@2452 153 jobjectArray jfilenames;
anthony@2452 154
anthony@2452 155 env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
anthony@2452 156 current_folder = NULL;
anthony@2452 157 filenames = NULL;
anthony@2452 158
anthony@2452 159 if (responseId == GTK_RESPONSE_ACCEPT) {
anthony@2452 160 current_folder = fp_gtk_file_chooser_get_current_folder(
anthony@3168 161 GTK_FILE_CHOOSER(aDialog));
anthony@3168 162 filenames = fp_gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(aDialog));
anthony@2452 163 }
anthony@2452 164
anthony@2452 165 jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
anthony@2452 166 jfilenames = toFilenamesArray(env, filenames);
anthony@2452 167
anthony@2452 168 (*env)->CallVoidMethod(env, obj, setFileInternalMethodID, jcurrent_folder,
anthony@2452 169 jfilenames);
anthony@2452 170 fp_g_free(current_folder);
anthony@2452 171
anthony@3168 172 quit(env, (jobject)obj, TRUE);
anthony@2452 173 }
anthony@2452 174
anthony@2452 175 /*
anthony@2452 176 * Class: sun_awt_X11_GtkFileDialogPeer
anthony@2452 177 * Method: run
anthony@2452 178 * Signature: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/io/FilenameFilter;Z;)V
anthony@2452 179 */
anthony@2452 180 JNIEXPORT void JNICALL
anthony@2452 181 Java_sun_awt_X11_GtkFileDialogPeer_run(JNIEnv * env, jobject jpeer,
anthony@2452 182 jstring jtitle, jint mode, jstring jdir, jstring jfile,
anthony@2452 183 jobject jfilter, jboolean multiple)
anthony@2452 184 {
anthony@3168 185 GtkWidget *dialog = NULL;
anthony@2452 186 GtkFileFilter *filter;
anthony@2452 187
anthony@2452 188 if (jvm == NULL) {
anthony@2452 189 (*env)->GetJavaVM(env, &jvm);
anthony@2452 190 }
anthony@2452 191
anthony@2452 192 fp_gdk_threads_enter();
anthony@2452 193
anthony@2452 194 const char *title = (*env)->GetStringUTFChars(env, jtitle, 0);
anthony@2452 195
anthony@2452 196 if (mode == 1) {
anthony@2452 197 /* Save action */
anthony@2452 198 dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
anthony@2452 199 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL,
anthony@2452 200 GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
anthony@2452 201 }
anthony@2452 202 else {
anthony@2452 203 /* Default action OPEN */
anthony@2452 204 dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
anthony@2452 205 GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL,
anthony@2452 206 GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
anthony@2452 207
anthony@2452 208 /* Set multiple selection mode, that is allowed only in OPEN action */
anthony@2452 209 if (multiple) {
anthony@2452 210 fp_gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog),
anthony@2452 211 multiple);
anthony@2452 212 }
anthony@2452 213 }
anthony@2452 214
anthony@2452 215 (*env)->ReleaseStringUTFChars(env, jtitle, title);
anthony@2452 216
anthony@2452 217 /* Set the directory */
anthony@2452 218 if (jdir != NULL) {
anthony@2452 219 const char *dir = (*env)->GetStringUTFChars(env, jdir, 0);
anthony@2452 220 fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
anthony@2452 221 (*env)->ReleaseStringUTFChars(env, jdir, dir);
anthony@2452 222 }
anthony@2452 223
anthony@2452 224 /* Set the filename */
anthony@2452 225 if (jfile != NULL) {
anthony@2452 226 const char *filename = (*env)->GetStringUTFChars(env, jfile, 0);
anthony@2452 227 fp_gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename);
anthony@2452 228 (*env)->ReleaseStringUTFChars(env, jfile, filename);
anthony@2452 229 }
anthony@2452 230
anthony@2452 231 /* Set the file filter */
anthony@2452 232 if (jfilter != NULL) {
anthony@2452 233 filter = fp_gtk_file_filter_new();
anthony@2452 234 fp_gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
anthony@2452 235 filenameFilterCallback, jpeer, NULL);
anthony@2452 236 fp_gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
anthony@2452 237 }
anthony@2452 238
anthony@2452 239 /* Other Properties */
anthony@2452 240 if (fp_gtk_check_version(2, 8, 0) == NULL) {
anthony@2452 241 fp_gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(
anthony@2452 242 dialog), TRUE);
anthony@2452 243 }
anthony@2452 244
anthony@2452 245 fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
anthony@2452 246 handle_response), jpeer);
anthony@3168 247
anthony@3168 248 (*env)->SetLongField(env, jpeer, widgetFieldID, ptr_to_jlong(dialog));
anthony@3168 249
anthony@2452 250 fp_gtk_widget_show(dialog);
anthony@2452 251
anthony@2452 252 fp_gtk_main();
anthony@2452 253 fp_gdk_threads_leave();
anthony@2452 254 }
anthony@3168 255