1 #include <jni.h>
   2 #include <stdio.h>
   3 #include <jni_util.h>
   4 #include <string.h>
   5 #include "gtk2_interface.h"
   6 #include "sun_awt_X11_GtkDirectoryDialogPeer.h"
   7 
   8 static JavaVM *jvm;
   9 static GtkWidget *dialog = NULL;
  10 
  11 /* To cache some method IDs */
  12 static jmethodID setDirectoryInternalMethodID = NULL;
  13 
  14 /*
  15  * Class:     sun_awt_X11_GtkDirectoryDialogPeer
  16  * Method:    quit
  17  * Signature: ()V
  18  */
  19 JNIEXPORT void JNICALL Java_sun_awt_X11_GtkDirectoryDialogPeer_quit
  20 (JNIEnv * env, jobject jpeer)
  21 {
  22     if (dialog != NULL)
  23     {
  24         fp_gtk_widget_hide (dialog);
  25         fp_gtk_widget_destroy (dialog);
  26 
  27         fp_gtk_main_quit ();
  28         dialog = NULL;
  29     }
  30 }
  31 
  32 static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
  33 {
  34     JNIEnv *env;
  35     char *current_folder;
  36     jclass cx;
  37     jstring jcurrent_folder;
  38 
  39     env = (JNIEnv *) JNU_GetEnv(jvm, JNI_VERSION_1_2);
  40     current_folder = NULL;
  41 
  42     if (responseId == GTK_RESPONSE_ACCEPT) {
  43         current_folder = fp_gtk_file_chooser_get_current_folder(
  44                 GTK_FILE_CHOOSER(dialog));
  45     }
  46 
  47     if (setDirectoryInternalMethodID == NULL) {
  48         cx = (*env)->GetObjectClass(env, (jobject) obj);
  49         if (cx == NULL) {
  50             JNU_ThrowInternalError(env, "Could not get GTK peer class");
  51             return;
  52         }
  53 
  54         setDirectoryInternalMethodID = (*env)->GetMethodID(env, cx,
  55                 "setDirectoryInternal", "(Ljava/lang/String;)V");
  56         if (setDirectoryInternalMethodID == NULL) {
  57             JNU_ThrowInternalError(env,
  58                     "Could not get setDirectoryInternalMethodID method id");
  59             return;
  60         }
  61     }
  62 
  63     jcurrent_folder = (*env)->NewStringUTF(env, current_folder);
  64 
  65     (*env)->CallVoidMethod(env, obj, setDirectoryInternalMethodID, jcurrent_folder);
  66     fp_g_free(current_folder);
  67 
  68     Java_sun_awt_X11_GtkDirectoryDialogPeer_quit(NULL, NULL);
  69 }
  70 
  71 /*
  72  * Class:     sun_awt_X11_GtkDirectoryDialogPeer
  73  * Method:    run
  74  * Signature: (Ljava/lang/String;ILjava/lang/String;)V
  75  */
  76 JNIEXPORT void JNICALL
  77 Java_sun_awt_X11_GtkDirectoryDialogPeer_run(JNIEnv * env, jobject jpeer,
  78         jstring jtitle, jstring jdir)
  79 {
  80     if (jvm == NULL) {
  81         (*env)->GetJavaVM(env, &jvm);
  82     }
  83 
  84     fp_gdk_threads_init();
  85     fp_gdk_threads_enter();
  86 
  87     const char *title = (*env)->GetStringUTFChars(env, jtitle, 0);
  88 
  89     /* Action SELECT_FOLDER */
  90     dialog = fp_gtk_file_chooser_dialog_new(title, NULL,
  91             GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL,
  92             GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
  93 
  94     (*env)->ReleaseStringUTFChars(env, jtitle, title);
  95 
  96     /* Set the directory */
  97     if (jdir != NULL) {
  98         const char *dir = (*env)->GetStringUTFChars(env, jdir, 0);
  99         fp_gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), dir);
 100         (*env)->ReleaseStringUTFChars(env, jdir, dir);
 101     }
 102 
 103     fp_g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(
 104             handle_response), jpeer);
 105     fp_gtk_widget_show(dialog);
 106 
 107     fp_gtk_main();
 108     fp_gdk_threads_leave();
 109 }