/* * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * */ #ifdef _WIN32 #include #endif #include #include #include /* This typedef is apparently needed for Microsoft compilers before VC8, and on Windows CE */ #if (_MSC_VER < 1400) || defined(UNDER_CE) #ifdef _WIN64 typedef long long intptr_t; #else typedef int intptr_t; #endif #else #include #endif #include #include #include "com_sun_javafx_newt_opengl_kd_KDWindow.h" #include "EventListener.h" #include "MouseEvent.h" #include "KeyEvent.h" // #define VERBOSE_ON 1 #ifdef VERBOSE_ON #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__) #else #define DBG_PRINT(...) #endif #ifdef VERBOSE_ON #ifdef _WIN32_WCE #define STDOUT_FILE "\\Storage Card\\stdout.txt" #define STDERR_FILE "\\Storage Card\\stderr.txt" #endif #endif /** * Window */ static jmethodID sizeChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs (JNIEnv *env, jclass clazz) { #ifdef VERBOSE_ON #ifdef _WIN32_WCE _wfreopen(TEXT(STDOUT_FILE),L"w",stdout); _wfreopen(TEXT(STDERR_FILE),L"w",stderr); #endif #endif sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); if (sizeChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || sendMouseEventID == NULL || sendKeyEventID == NULL) { DBG_PRINT( "initIDs failed\n" ); return JNI_FALSE; } DBG_PRINT( "initIDs ok\n" ); return JNI_TRUE; } JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CreateWindow (JNIEnv *env, jobject obj, jint owner, jlong display, jintArray jAttrs) { jint * attrs = NULL; jsize attrsLen; EGLDisplay dpy = (EGLDisplay)(intptr_t)display; KDWindow *window = 0; DBG_PRINT( "[CreateWindow]: owner %d\n", owner); if(dpy==NULL) { fprintf(stderr, "[CreateWindow] invalid display connection..\n"); return 0; } attrsLen = (*env)->GetArrayLength(env, jAttrs); if(0==attrsLen) { fprintf(stderr, "[CreateWindow] attribute array size 0..\n"); return 0; } attrs = (*env)->GetIntArrayElements(env, jAttrs, 0); if(NULL==attrs) { fprintf(stderr, "[CreateWindow] attribute array NULL..\n"); return 0; } /* passing the KDWindow instance for the eventuserptr */ window = kdCreateWindow(dpy, attrs, (void *)(intptr_t)owner); (*env)->ReleaseIntArrayElements(env, jAttrs, attrs, 0); if(NULL==window) { fprintf(stderr, "[CreateWindow] failed: 0x%X\n", kdGetError()); } DBG_PRINT( "[CreateWindow] ok: %p, owner %d\n", window, (void *)(intptr_t)owner); return (jlong) (intptr_t) window; } JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_RealizeWindow (JNIEnv *env, jobject obj, jlong window) { KDWindow *w = (KDWindow*) (intptr_t) window; EGLNativeWindowType nativeWindow=0; jint res = kdRealizeWindow(w, &nativeWindow); if(res) { fprintf(stderr, "[RealizeWindow] failed: 0x%X, 0x%X\n", res, kdGetError()); nativeWindow = NULL; } DBG_PRINT( "[RealizeWindow] ok: %p\n", nativeWindow); return (jlong) (intptr_t) nativeWindow; } JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CloseWindow (JNIEnv *env, jobject obj, jlong window) { KDWindow *w = (KDWindow*) (intptr_t) window; int res = kdDestroyWindow(w); DBG_PRINT( "[CloseWindow] res: %d\n", res); return res; } /* * Class: com_sun_javafx_newt_kd_KDWindow * Method: setVisible0 * Signature: (JJZ)V */ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setVisible0 (JNIEnv *env, jobject obj, jlong window, jboolean visible) { KDWindow *w = (KDWindow*) (intptr_t) window; KDboolean v = (visible==JNI_TRUE)?KD_TRUE:KD_FALSE; kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &v); DBG_PRINT( "[setVisible] v=%d\n", visible); } JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_DispatchMessages (JNIEnv *env, jobject obj, jint owner, jlong window, jint eventMask) { KDWindow *w = (KDWindow*) (intptr_t) window; const KDEvent * evt; // Periodically take a break while( NULL!=(evt=kdWaitEvent(0)) ) { jint src_owner = (jint)(intptr_t)evt->userptr; if(src_owner != owner) { DBG_PRINT( "event unrelated: src: %d, caller: %d, evt type: 0x%X\n", src_owner, owner, evt->type); continue; } DBG_PRINT( "[DispatchMessages]: caller %d, evt type: 0x%X\n", owner, evt->type); switch(evt->type) { case KD_EVENT_INPUT_POINTER: if( ! ( eventMask & EVENT_MOUSE ) ) { DBG_PRINT( "event mouse ignored: src: %d\n", owner); continue; } break; /* case KeyPress: case KeyRelease: if( ! ( eventMask & EVENT_KEY ) ) { DBG_PRINT( "event key ignored: src: %d\n", owner); continue; } break; */ case KD_EVENT_WINDOW_FOCUS: case KD_EVENT_WINDOW_CLOSE: case KD_EVENT_WINDOWPROPERTY_CHANGE: case KD_EVENT_WINDOW_REDRAW: if( ! ( eventMask & EVENT_WINDOW ) ) { DBG_PRINT( "event window ignored: src: %d\n", owner); continue; } break; } // FIXME: support resize and window re-positioning events switch(evt->type) { case KD_EVENT_WINDOW_FOCUS: { KDboolean hasFocus; kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_FOCUS, &hasFocus); DBG_PRINT( "event window focus : src: %d\n", owner); } break; case KD_EVENT_WINDOW_CLOSE: { DBG_PRINT( "event window close : src: %d\n", owner); (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID); // Called by Window.java: DestroyWindow(wnd); // (*env)->CallVoidMethod(env, obj, windowDestroyedID); } break; case KD_EVENT_WINDOWPROPERTY_CHANGE: { const KDEventWindowProperty* prop = &evt->data.windowproperty; switch (prop->pname) { case KD_WINDOWPROPERTY_SIZE: { KDint32 v[2]; if(!kdGetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v)) { DBG_PRINT( "event window size change : src: %d %dx%d\n", owner, v[0], v[1]); (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) v[0], (jint) v[1]); } else { DBG_PRINT( "event window size change error: src: %d %dx%d\n", owner, v[0], v[1]); } } break; case KD_WINDOWPROPERTY_FOCUS: DBG_PRINT( "event window focus: src: %d\n", owner); break; case KD_WINDOWPROPERTY_VISIBILITY: { KDboolean visible; kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &visible); DBG_PRINT( "event window visibility: src: %d, v:%d\n", owner, visible); } break; default: break; } } break; case KD_EVENT_INPUT_POINTER: { const KDEventInputPointer* ptr = &(evt->data.inputpointer); // button idx: evt->data.input.index // pressed = ev->data.input.value.i // time = ev->timestamp if(KD_INPUT_POINTER_SELECT==ptr->index) { DBG_PRINT( "event mouse click: src: %d, s:%d, (%d,%d)\n", owner, ptr->select, ptr->x, ptr->y); (*env)->CallVoidMethod(env, obj, sendMouseEventID, (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED, (jint) 0, (jint) ptr->x, (jint) ptr->y, 1); } else { DBG_PRINT( "event mouse: src: %d, s:%d, i:0x%X (%d,%d)\n", owner, ptr->select, ptr->index, ptr->x, ptr->y); (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED, 0, (jint) ptr->x, (jint) ptr->y, 0); } } break; } } } JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setFullScreen0 (JNIEnv *env, jobject obj, jlong window, jboolean fullscreen) { KDWindow *w = (KDWindow*) (intptr_t) window; KDboolean v = fullscreen; int res = kdSetWindowPropertybv(w, KD_WINDOWPROPERTY_FULLSCREEN_NV, &v); DBG_PRINT( "[setFullScreen] v=%d, res=%d\n", fullscreen, res); (void)res; } JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setSize0 (JNIEnv *env, jobject obj, jlong window, jint width, jint height) { KDWindow *w = (KDWindow*) (intptr_t) window; KDint32 v[] = { width, height }; int res = kdSetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v); DBG_PRINT( "[setSize] v=%dx%d, res=%d\n", width, height, res); (void)res; (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); }