comparison android/dw.cpp @ 2494:b3e28eed0e50

Android: Fix the basics of notebook control... return actual page IDs. Also need to ensure the box packed in notebookPagePack is MATCH_PARENT. Also prevent multiple calls to dwindowsInit() from spawning multiple instances of dwmain().
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 02 May 2021 10:46:21 +0000
parents bca7e0ab0ccc
children 5664c91d03fb
comparison
equal deleted inserted replaced
2493:bca7e0ab0ccc 2494:b3e28eed0e50
82 * to call the dwmain() entrypoint... then we wait for dw_main() 82 * to call the dwmain() entrypoint... then we wait for dw_main()
83 * to be called and return. 83 * to be called and return.
84 * Parameters: 84 * Parameters:
85 * path: The path to the Android app. 85 * path: The path to the Android app.
86 */ 86 */
87 JNIEXPORT jstring JNICALL 87 JNIEXPORT void JNICALL
88 Java_org_dbsoft_dwindows_DWindows_dwindowsInit(JNIEnv* env, jobject obj, jstring path) 88 Java_org_dbsoft_dwindows_DWindows_dwindowsInit(JNIEnv* env, jobject obj, jstring path)
89 { 89 {
90 char *arg = strdup(env->GetStringUTFChars((jstring) path, NULL)); 90 static int runcount = 0;
91 91
92 /* Save our class object pointer for later */ 92 /* Safety check to prevent multiple initializations */
93 _dw_obj = env->NewGlobalRef(obj); 93 if(runcount == 1)
94 94 {
95 /* Save the JNIEnv for the main thread */ 95 char *arg = strdup(env->GetStringUTFChars((jstring) path, NULL));
96 pthread_key_create(&_dw_env_key, NULL); 96
97 pthread_setspecific(_dw_env_key, env); 97 /* Save our class object pointer for later */
98 98 _dw_obj = env->NewGlobalRef(obj);
99 /* Create the dwmain event */ 99
100 _dw_main_event = dw_event_new(); 100 /* Save the JNIEnv for the main thread */
101 101 pthread_key_create(&_dw_env_key, NULL);
102 /* Launch the new thread to execute dwmain() */ 102 pthread_setspecific(_dw_env_key, env);
103 dw_thread_new((void *)_dw_main_launch, arg, 0); 103
104 104 /* Create the dwmain event */
105 /* Wait until dwmain() calls dw_main() then return */ 105 _dw_main_event = dw_event_new();
106 dw_event_wait(_dw_main_event, DW_TIMEOUT_INFINITE); 106
107 return env->NewStringUTF("Hello from JNI!"); 107 /* Launch the new thread to execute dwmain() */
108 dw_thread_new((void *) _dw_main_launch, arg, 0);
109
110 /* Wait until dwmain() calls dw_main() then return */
111 dw_event_wait(_dw_main_event, DW_TIMEOUT_INFINITE);
112 }
113 runcount++;
108 } 114 }
109 115
110 typedef struct _sighandler 116 typedef struct _sighandler
111 { 117 {
112 struct _sighandler *next; 118 struct _sighandler *next;
482 jmethodID dwindowsExit = env->GetMethodID(clazz, "dwindowsExit", 488 jmethodID dwindowsExit = env->GetMethodID(clazz, "dwindowsExit",
483 "(I)V"); 489 "(I)V");
484 // Call the method on the object 490 // Call the method on the object
485 env->CallVoidMethod(_dw_obj, dwindowsExit, exitcode); 491 env->CallVoidMethod(_dw_obj, dwindowsExit, exitcode);
486 } 492 }
493 // We shouldn't get here, but in case JNI can't call dwindowsExit...
487 exit(exitcode); 494 exit(exitcode);
488 } 495 }
489 496
490 /* 497 /*
491 * Free's memory allocated by dynamic windows. 498 * Free's memory allocated by dynamic windows.
2967 { 2974 {
2968 // First get the class that contains the method you need to call 2975 // First get the class that contains the method you need to call
2969 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 2976 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
2970 // Get the method that you want to call 2977 // Get the method that you want to call
2971 jmethodID notebookPageNew = env->GetMethodID(clazz, "notebookPageNew", 2978 jmethodID notebookPageNew = env->GetMethodID(clazz, "notebookPageNew",
2972 "(Landroid/widget/RelativeLayout;JI)Ljava/lang/Object;"); 2979 "(Landroid/widget/RelativeLayout;JI)J");
2973 // Call the method on the object 2980 // Call the method on the object
2974 result = DW_POINTER_TO_INT(env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, notebookPageNew, handle, (jlong)flags, front))); 2981 result = (unsigned long)env->CallLongMethod(_dw_obj, notebookPageNew, handle, (jlong)flags, front);
2975 } 2982 }
2976 return result; 2983 return result;
2977 } 2984 }
2978 2985
2979 /* 2986 /*
2986 { 2993 {
2987 JNIEnv *env; 2994 JNIEnv *env;
2988 2995
2989 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) 2996 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
2990 { 2997 {
2991 jobject tab = (jobject)DW_INT_TO_POINTER(pageid);
2992
2993 // First get the class that contains the method you need to call 2998 // First get the class that contains the method you need to call
2994 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 2999 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
2995 // Get the method that you want to call 3000 // Get the method that you want to call
2996 jmethodID notebookPageDestroy = env->GetMethodID(clazz, "notebookPageDestroy", 3001 jmethodID notebookPageDestroy = env->GetMethodID(clazz, "notebookPageDestroy",
2997 "(Landroid/widget/RelativeLayout;Lcom/google/android/material/tabs/TabLayout/Tab;)V"); 3002 "(Landroid/widget/RelativeLayout;J)V");
2998 // Call the method on the object 3003 // Call the method on the object
2999 env->CallVoidMethod(_dw_obj, notebookPageDestroy, handle, tab); 3004 env->CallVoidMethod(_dw_obj, notebookPageDestroy, handle, (jlong)pageid);
3000
3001 // Release the global reference
3002 env->DeleteWeakGlobalRef(tab);
3003 } 3005 }
3004 } 3006 }
3005 3007
3006 /* 3008 /*
3007 * Queries the currently visible page ID. 3009 * Queries the currently visible page ID.
3018 if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { 3020 if(handle && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) {
3019 // First get the class that contains the method you need to call 3021 // First get the class that contains the method you need to call
3020 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 3022 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
3021 // Get the method that you want to call 3023 // Get the method that you want to call
3022 jmethodID notebookPageGet = env->GetMethodID(clazz, "notebookPageGet", 3024 jmethodID notebookPageGet = env->GetMethodID(clazz, "notebookPageGet",
3023 "(Landroid/widget/RelativeLayout;)Lcom/google/android/material/tabs/TabLayout/Tab;"); 3025 "(Landroid/widget/RelativeLayout;)J");
3024 // Call the method on the object 3026 // Call the method on the object
3025 result = DW_POINTER_TO_INT(env->CallObjectMethod(_dw_obj, notebookPageGet, handle)); 3027 result = (unsigned long)env->CallLongMethod(_dw_obj, notebookPageGet, handle);
3026 } 3028 }
3027 return result; 3029 return result;
3028 } 3030 }
3029 3031
3030 /* 3032 /*
3036 void API dw_notebook_page_set(HWND handle, unsigned int pageid) 3038 void API dw_notebook_page_set(HWND handle, unsigned int pageid)
3037 { 3039 {
3038 JNIEnv *env; 3040 JNIEnv *env;
3039 3041
3040 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) { 3042 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) {
3041 jobject tab = (jobject) DW_INT_TO_POINTER(pageid);
3042
3043 // First get the class that contains the method you need to call 3043 // First get the class that contains the method you need to call
3044 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 3044 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
3045 // Get the method that you want to call 3045 // Get the method that you want to call
3046 jmethodID notebookPageSet = env->GetMethodID(clazz, "notebookPageSet", 3046 jmethodID notebookPageSet = env->GetMethodID(clazz, "notebookPageSet",
3047 "(Landroid/widget/RelativeLayout;Lcom/google/android/material/tabs/TabLayout/Tab;)V"); 3047 "(Landroid/widget/RelativeLayout;J)V");
3048 // Call the method on the object 3048 // Call the method on the object
3049 env->CallVoidMethod(_dw_obj, notebookPageSet, handle, tab); 3049 env->CallVoidMethod(_dw_obj, notebookPageSet, handle, (jlong)pageid);
3050 } 3050 }
3051 } 3051 }
3052 3052
3053 /* 3053 /*
3054 * Sets the text on the specified notebook tab. 3054 * Sets the text on the specified notebook tab.
3061 { 3061 {
3062 JNIEnv *env; 3062 JNIEnv *env;
3063 3063
3064 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) 3064 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
3065 { 3065 {
3066 jobject tab = (jobject)DW_INT_TO_POINTER(pageid);
3067
3068 // Construct a String 3066 // Construct a String
3069 jstring jstr = env->NewStringUTF(text); 3067 jstring jstr = env->NewStringUTF(text);
3070 // First get the class that contains the method you need to call 3068 // First get the class that contains the method you need to call
3071 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 3069 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
3072 // Get the method that you want to call 3070 // Get the method that you want to call
3073 jmethodID notebookPageSetText = env->GetMethodID(clazz, "notebookPageSetText", 3071 jmethodID notebookPageSetText = env->GetMethodID(clazz, "notebookPageSetText",
3074 "(Landroid/widget/RelativeLayout;Lcom/google/android/material/tabs/TabLayout/Tab;Ljava/lang/String;)V"); 3072 "(Landroid/widget/RelativeLayout;JLjava/lang/String;)V");
3075 // Call the method on the object 3073 // Call the method on the object
3076 env->CallVoidMethod(_dw_obj, notebookPageSetText, handle, tab, jstr); 3074 env->CallVoidMethod(_dw_obj, notebookPageSetText, handle, (jlong)pageid, jstr);
3077 } 3075 }
3078 } 3076 }
3079 3077
3080 /* 3078 /*
3081 * Sets the text on the specified notebook tab status area. 3079 * Sets the text on the specified notebook tab status area.
3099 { 3097 {
3100 JNIEnv *env; 3098 JNIEnv *env;
3101 3099
3102 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) 3100 if(handle && pageid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
3103 { 3101 {
3104 jobject tab = (jobject)DW_INT_TO_POINTER(pageid);
3105
3106 // First get the class that contains the method you need to call 3102 // First get the class that contains the method you need to call
3107 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 3103 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
3108 // Get the method that you want to call 3104 // Get the method that you want to call
3109 jmethodID notebookPack = env->GetMethodID(clazz, "notebookPack", 3105 jmethodID notebookPagePack = env->GetMethodID(clazz, "notebookPagePack",
3110 "(Landroid/widget/RelativeLayout;Lcom/google/android/material/tabs/TabLayout/Tab;Landroid/widget/LinearLayout;)V"); 3106 "(Landroid/widget/RelativeLayout;JLandroid/widget/LinearLayout;)V");
3111 // Call the method on the object 3107 // Call the method on the object
3112 env->CallVoidMethod(_dw_obj, notebookPack, handle, tab, page); 3108 env->CallVoidMethod(_dw_obj, notebookPagePack, handle, (jlong)pageid, page);
3113 } 3109 }
3114 } 3110 }
3115 3111
3116 /* 3112 /*
3117 * Create a new Window Frame. 3113 * Create a new Window Frame.
3785 { 3781 {
3786 JNIEnv *env; 3782 JNIEnv *env;
3787 3783
3788 if(timerid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key))) 3784 if(timerid && (env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
3789 { 3785 {
3790 // Use a long paramater 3786 // Use a long parameter
3791 jobject timer = (jobject)timerid; 3787 jobject timer = (jobject)timerid;
3792 // First get the class that contains the method you need to call 3788 // First get the class that contains the method you need to call
3793 jclass clazz = _dw_find_class(env, DW_CLASS_NAME); 3789 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
3794 // Get the method that you want to call 3790 // Get the method that you want to call
3795 jmethodID timerDisconnect = env->GetMethodID(clazz, "timerDisconnect", 3791 jmethodID timerDisconnect = env->GetMethodID(clazz, "timerDisconnect",
4800 /* 4796 /*
4801 * Cleanly terminates a DW session, should be signal handler safe. 4797 * Cleanly terminates a DW session, should be signal handler safe.
4802 */ 4798 */
4803 void API dw_shutdown(void) 4799 void API dw_shutdown(void)
4804 { 4800 {
4801 JNIEnv *env;
4802
4803 if((env = (JNIEnv *)pthread_getspecific(_dw_env_key)))
4804 {
4805 // First get the class that contains the method you need to call
4806 jclass clazz = _dw_find_class(env, DW_CLASS_NAME);
4807 // Get the method that you want to call
4808 jmethodID dwindowsShutdown = env->GetMethodID(clazz, "dwindowsShutdown",
4809 "()V");
4810 // Call the method on the object
4811 env->CallVoidMethod(_dw_obj, dwindowsShutdown);
4812 }
4805 } 4813 }
4806 4814
4807 /* 4815 /*
4808 * Execute and external program in a seperate session. 4816 * Execute and external program in a seperate session.
4809 * Parameters: 4817 * Parameters:
4947 */ 4955 */
4948 int API dw_feature_get(DWFEATURE feature) 4956 int API dw_feature_get(DWFEATURE feature)
4949 { 4957 {
4950 switch(feature) 4958 switch(feature)
4951 { 4959 {
4952 #if 0
4953 case DW_FEATURE_HTML: /* Supports the HTML Widget */ 4960 case DW_FEATURE_HTML: /* Supports the HTML Widget */
4954 case DW_FEATURE_HTML_RESULT: /* Supports the DW_SIGNAL_HTML_RESULT callback */ 4961 case DW_FEATURE_HTML_RESULT: /* Supports the DW_SIGNAL_HTML_RESULT callback */
4955 case DW_FEATURE_WINDOW_BORDER: /* Supports custom window border sizes */
4956 case DW_FEATURE_WINDOW_TRANSPARENCY: /* Supports window frame transparency */
4957 case DW_FEATURE_DARK_MODE: /* Supports Dark Mode user interface */ 4962 case DW_FEATURE_DARK_MODE: /* Supports Dark Mode user interface */
4963 case DW_FEATURE_NOTIFICATION: /* Supports sending system notifications */
4964 case DW_FEATURE_UTF8_UNICODE: /* Supports UTF8 encoded Unicode text */
4958 case DW_FEATURE_MLE_AUTO_COMPLETE: /* Supports auto completion in Multi-line Edit boxes */ 4965 case DW_FEATURE_MLE_AUTO_COMPLETE: /* Supports auto completion in Multi-line Edit boxes */
4959 case DW_FEATURE_MLE_WORD_WRAP: /* Supports word wrapping in Multi-line Edit boxes */ 4966 case DW_FEATURE_MLE_WORD_WRAP: /* Supports word wrapping in Multi-line Edit boxes */
4960 case DW_FEATURE_CONTAINER_STRIPE: /* Supports striped line display in container widgets */ 4967 case DW_FEATURE_CONTAINER_STRIPE: /* Supports striped line display in container widgets */
4961 case DW_FEATURE_MDI: /* Supports Multiple Document Interface window frame */
4962 case DW_FEATURE_NOTEBOOK_STATUS_TEXT: /* Supports status text area on notebook/tabbed controls */
4963 case DW_FEATURE_NOTIFICATION: /* Supports sending system notifications */
4964 case DW_FEATURE_UTF8_UNICODE: /* Supports UTF8 encoded Unicode text */
4965 case DW_FEATURE_MLE_RICH_EDIT: /* Supports Rich Edit based MLE control (Windows) */
4966 case DW_FEATURE_TASK_BAR: /* Supports icons in the taskbar or similar system widget */
4967 case DW_FEATURE_TREE: .* Supports the Tree Widget */
4968 return DW_FEATURE_ENABLED; 4968 return DW_FEATURE_ENABLED;
4969 #endif
4970 default: 4969 default:
4971 return DW_FEATURE_UNSUPPORTED; 4970 return DW_FEATURE_UNSUPPORTED;
4972 } 4971 }
4973 } 4972 }
4974 4973
4988 int API dw_feature_set(DWFEATURE feature, int state) 4987 int API dw_feature_set(DWFEATURE feature, int state)
4989 { 4988 {
4990 switch(feature) 4989 switch(feature)
4991 { 4990 {
4992 /* These features are supported but not configurable */ 4991 /* These features are supported but not configurable */
4993 #if 0
4994 case DW_FEATURE_HTML: /* Supports the HTML Widget */ 4992 case DW_FEATURE_HTML: /* Supports the HTML Widget */
4995 case DW_FEATURE_HTML_RESULT: /* Supports the DW_SIGNAL_HTML_RESULT callback */ 4993 case DW_FEATURE_HTML_RESULT: /* Supports the DW_SIGNAL_HTML_RESULT callback */
4996 case DW_FEATURE_WINDOW_BORDER: /* Supports custom window border sizes */
4997 case DW_FEATURE_WINDOW_TRANSPARENCY: /* Supports window frame transparency */
4998 case DW_FEATURE_DARK_MODE: /* Supports Dark Mode user interface */ 4994 case DW_FEATURE_DARK_MODE: /* Supports Dark Mode user interface */
4995 case DW_FEATURE_NOTIFICATION: /* Supports sending system notifications */
4996 case DW_FEATURE_UTF8_UNICODE: /* Supports UTF8 encoded Unicode text */
4999 case DW_FEATURE_MLE_AUTO_COMPLETE: /* Supports auto completion in Multi-line Edit boxes */ 4997 case DW_FEATURE_MLE_AUTO_COMPLETE: /* Supports auto completion in Multi-line Edit boxes */
5000 case DW_FEATURE_MLE_WORD_WRAP: /* Supports word wrapping in Multi-line Edit boxes */ 4998 case DW_FEATURE_MLE_WORD_WRAP: /* Supports word wrapping in Multi-line Edit boxes */
5001 case DW_FEATURE_CONTAINER_STRIPE: /* Supports striped line display in container widgets */ 4999 case DW_FEATURE_CONTAINER_STRIPE: /* Supports striped line display in container widgets */
5002 case DW_FEATURE_MDI: /* Supports Multiple Document Interface window frame */
5003 case DW_FEATURE_NOTEBOOK_STATUS_TEXT: /* Supports status text area on notebook/tabbed controls */
5004 case DW_FEATURE_NOTIFICATION: /* Supports sending system notifications */
5005 case DW_FEATURE_UTF8_UNICODE: /* Supports UTF8 encoded Unicode text */
5006 case DW_FEATURE_MLE_RICH_EDIT: /* Supports Rich Edit based MLE control (Windows) */
5007 case DW_FEATURE_TASK_BAR: /* Supports icons in the taskbar or similar system widget */
5008 case DW_FEATURE_TREE: .* Supports the Tree Widget */
5009 return DW_ERROR_GENERAL; 5000 return DW_ERROR_GENERAL;
5010 #endif
5011 /* These features are supported and configurable */ 5001 /* These features are supported and configurable */
5012 default: 5002 default:
5013 return DW_FEATURE_UNSUPPORTED; 5003 return DW_FEATURE_UNSUPPORTED;
5014 } 5004 }
5015 } 5005 }