diff options
Diffstat (limited to 'src/newt/native/bcm_vc_iv.c')
-rw-r--r-- | src/newt/native/bcm_vc_iv.c | 325 |
1 files changed, 297 insertions, 28 deletions
diff --git a/src/newt/native/bcm_vc_iv.c b/src/newt/native/bcm_vc_iv.c index f3474ee34..50f0c140a 100644 --- a/src/newt/native/bcm_vc_iv.c +++ b/src/newt/native/bcm_vc_iv.c @@ -39,15 +39,36 @@ #define VERBOSE_ON 1 #ifdef VERBOSE_ON - #define DBG_PRINT(...) fprintf(stdout, __VA_ARGS__) + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #else #define DBG_PRINT(...) #endif +typedef struct { + DISPMANX_ELEMENT_HANDLE_T handle; // magic BCM EGL position (EGL_DISPMANX_WINDOW_T) + int width; // magic BCM EGL position (EGL_DISPMANX_WINDOW_T) + int height; // magic BCM EGL position (EGL_DISPMANX_WINDOW_T) + int x; + int y; + int32_t layer; +} BCM_ELEMENT_T; + +typedef struct { + DISPMANX_RESOURCE_HANDLE_T handle; + VC_IMAGE_TYPE_T type; + uint32_t native_image_handle; +} BCM_RESOURCE_T; + +typedef struct { + BCM_ELEMENT_T element; + BCM_RESOURCE_T resource; + int hotX, hotY; +} POINTER_ICON_T; + static jmethodID setScreenSizeID = NULL; -static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; +static jmethodID positionChangedID = NULL; static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; @@ -64,11 +85,210 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_initI return JNI_TRUE; } -JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages - (JNIEnv *env, jobject obj) +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_OpenBCMDisplay0 + (JNIEnv *env, jclass clazz) +{ + DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + DBG_PRINT( "BCM.Display Open %p\n", (void*)(intptr_t)dispman_display); + return (jlong) (intptr_t) dispman_display; +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_CloseBCMDisplay0 + (JNIEnv *env, jclass clazz, jlong display) +{ + DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display; + DBG_PRINT( "BCM.Display Close %p\n", (void*)(intptr_t)dispman_display); + vc_dispmanx_display_close( dispman_display ); +} + + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DispatchMessages0 + (JNIEnv *env, jclass clazz) { } +static void bcm_moveTo(DISPMANX_ELEMENT_HANDLE_T element, uint32_t layer, int x, int y, int width, int height) { + VC_RECT_T src_rect; + VC_RECT_T dst_rect; + uint32_t change_flags = DISPMANX_ELEMENT_CHANGE_DEST_RECT | DISPMANX_ELEMENT_CHANGE_SRC_RECT; + DISPMANX_RESOURCE_HANDLE_T mask = 0; + DISPMANX_TRANSFORM_T transform = 0; + + uint8_t opacity = 0; // NOP + + dst_rect.x = x; + dst_rect.y = y; + dst_rect.width = width; + dst_rect.height = height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = width << 16; + src_rect.height = height << 16; + + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); + vc_dispmanx_element_change_attributes( dispman_update, + element, + change_flags, + layer, + opacity, + &dst_rect, + &src_rect, + mask, + transform ); + vc_dispmanx_update_submit_sync( dispman_update ); +} + +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_CreatePointerIcon0 + (JNIEnv *env, jclass clazz, jobject pixels, jint pixels_byte_offset, jboolean pixels_is_direct, jint width, jint height, jint hotX, jint hotY) +{ + if( 0 == pixels ) { + return 0; + } + int32_t success = 0; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + int x = 0; + int y = 0; + int pitch = width * 4; // RGBA + + const unsigned char * pixelPtr = (const unsigned char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, pixels) : + (*env)->GetPrimitiveArrayCritical(env, pixels, NULL) ); + + POINTER_ICON_T * p = calloc(1, sizeof(POINTER_ICON_T)); + p->hotX = hotX; + p->hotY = hotY; + p->element.layer = 2000; + p->element.x = x; + p->element.y = y; + p->element.width = width; + p->element.height = height; + p->resource.type = VC_IMAGE_ARGB8888; /* 32bpp with 8bit alpha at MS byte, with R, G, B (LS byte) */ + p->resource.handle = vc_dispmanx_resource_create( p->resource.type, + width, + height, + &(p->resource.native_image_handle) ); + + dst_rect.x = x; + dst_rect.y = y; + dst_rect.width = width; + dst_rect.height = height; + + vc_dispmanx_resource_write_data( p->resource.handle, + p->resource.type, + pitch, + (void*)(intptr_t)(pixelPtr + pixels_byte_offset), + &dst_rect ); + + if ( JNI_FALSE == pixels_is_direct ) { + (*env)->ReleasePrimitiveArrayCritical(env, pixels, (void*)pixelPtr, JNI_ABORT); + } + + DBG_PRINT( "BCM.Display PointerIcon.Create PI %p, resource %p\n", p, (void*)(intptr_t)p->resource.handle); + return (jlong) (intptr_t) p; +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_DestroyPointerIcon0 + (JNIEnv *env, jclass clazz, jlong handle) +{ + POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ; + if( 0 == p ) { + return; + } + + DBG_PRINT( "BCM.Display PointerIcon.Destroy.0 PI %p, resource %p, element %p\n", + p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle); + + if( 0 != p->element.handle ) { + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); + vc_dispmanx_element_remove( dispman_update, p->element.handle ); + p->element.handle = 0; + vc_dispmanx_update_submit_sync( dispman_update ); + } + if( 0 != p->resource.handle ) { + vc_dispmanx_resource_delete( p->resource.handle ); + p->resource.handle = 0; + } + free( p ); +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_SetPointerIcon0 + (JNIEnv *env, jclass clazz, jlong display, jlong handle, jboolean enable, jint x, jint y) +{ + DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display; + POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ; + VC_RECT_T dst_rect; + VC_RECT_T src_rect; + + if( 0 == dispman_display || NULL == p || 0 == p->resource.handle ) { + return; + } + + DBG_PRINT( "BCM.Display PointerIcon.Set.0 %p, PI %p, resource %p, element %p - enable %d - %d/%d\n", + (void*)(intptr_t)display, p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, enable, x, y); + + if( enable ) { + if( 0 != p->element.handle ) { + return; + } + + p->element.x = x; + p->element.y = y; + dst_rect.x = p->element.x - p->hotX; + dst_rect.y = p->element.y - p->hotY; + dst_rect.width = p->element.width; + dst_rect.height = p->element.height; + + src_rect.x = 0; + src_rect.y = 0; + src_rect.width = p->element.width << 16; + src_rect.height = p->element.height << 16; + + VC_DISPMANX_ALPHA_T dispman_alpha; + memset(&dispman_alpha, 0x0, sizeof(VC_DISPMANX_ALPHA_T)); + dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE ; + dispman_alpha.opacity = 0xFF; + dispman_alpha.mask = 0xFF; + + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); + p->element.handle = vc_dispmanx_element_add ( dispman_update, dispman_display, + p->element.layer, &dst_rect, + p->resource.handle /*src*/, + &src_rect, DISPMANX_PROTECTION_NONE, + &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/); + vc_dispmanx_update_submit_sync( dispman_update ); + } else { + // DISABLE + if( 0 == p->element.handle ) { + return; + } + p->element.x = x; + p->element.y = y; + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); + vc_dispmanx_element_remove( dispman_update, p->element.handle ); + p->element.handle = 0; + vc_dispmanx_update_submit_sync( dispman_update ); + } + DBG_PRINT( "BCM.Display PointerIcon.Set.X %p, PI %p, resource %p, element %p - enable %d - %d/%d\n", + (void*)(intptr_t)display, p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, enable, x, y); +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_DisplayDriver_MovePointerIcon0 + (JNIEnv *env, jclass clazz, jlong handle, jint x, jint y) +{ + POINTER_ICON_T * p = (POINTER_ICON_T *) (intptr_t) handle ; + + if( NULL == p || 0 == p->element.handle ) { + return; + } + DBG_PRINT( "BCM.Display PointerIcon.Move.0 PI %p, resource %p, element %p - %d/%d\n", + p, (void*)(intptr_t)p->resource.handle, (void*)(intptr_t)p->element.handle, x, y); + p->element.x = x; + p->element.y = y; + bcm_moveTo( p->element.handle, p->element.layer, p->element.x - p->hotX, p->element.y - p->hotY, p->element.width, p->element.height); +} + /** * Screen */ @@ -111,12 +331,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_ScreenDriver_initNative JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initIDs (JNIEnv *env, jclass clazz) { - windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V"); + positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z"); - if (windowCreatedID == NULL || - sizeChangedID == NULL || + if (sizeChangedID == NULL || + positionChangedID == NULL || visibleChangedID == NULL || windowDestroyNotifyID == NULL) { DBG_PRINT( "initIDs failed\n" ); @@ -126,20 +346,23 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_initID return JNI_TRUE; } -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow - (JNIEnv *env, jobject obj, jint width, jint height, jboolean opaque, jint alphaBits) +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWindow0 + (JNIEnv *env, jobject obj, jlong display, jint x, jint y, jint width, jint height, jboolean opaque, jint alphaBits) { int32_t success = 0; VC_RECT_T dst_rect; VC_RECT_T src_rect; + if( 0 == display ) { + return; + } dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = width; dst_rect.height = height; - src_rect.x = 0; - src_rect.y = 0; + src_rect.x = x; + src_rect.y = y; src_rect.width = width << 16; src_rect.height = height << 16; @@ -156,37 +379,52 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CreateWin dispman_alpha.mask = 0xFF; } - DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open( 0 /* LCD */); + DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display; + + DBG_PRINT( "BCM.Display Window.Create.0 %p, %d/%d %dx%d, opaque %d, alphaBits %d\n", + (void*)(intptr_t)dispman_display, x, y, width, height, opaque, alphaBits); + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display, 0/*layer*/, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha */, 0/*clamp*/, 0/*transform*/); - EGL_DISPMANX_WINDOW_T * nativeWindowPtr = calloc(1, sizeof(EGL_DISPMANX_WINDOW_T)); - nativeWindowPtr->element = dispman_element; - nativeWindowPtr->width = width; - nativeWindowPtr->height = height; + BCM_ELEMENT_T * p = calloc(1, sizeof(BCM_ELEMENT_T)); + p->handle = dispman_element; + p->layer = 0; + p->x = x; + p->y = y; + p->width = width; + p->height = height; vc_dispmanx_update_submit_sync( dispman_update ); (*env)->CallVoidMethod(env, obj, visibleChangedID, JNI_FALSE, JNI_TRUE); // FIXME: or defer=true ? - return (jlong) (intptr_t) nativeWindowPtr; -} + DBG_PRINT( "BCM.Display Window.Create.X %p, element %p\n", + (void*)(intptr_t)dispman_display, (void*)(intptr_t)p->handle); -JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_RealizeWindow - (JNIEnv *env, jobject obj, jlong window) -{ - return (jlong) (intptr_t) 0; + return (jlong) (intptr_t) p; } -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow - (JNIEnv *env, jobject obj, jlong window, jlong juserData) +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_CloseWindow0 + (JNIEnv *env, jobject obj, jlong display, jlong window) { - EGL_DISPMANX_WINDOW_T * nativeWindowPtr = (EGL_DISPMANX_WINDOW_T *) (intptr_t) window ; - free( nativeWindowPtr ); - return 0; + DISPMANX_DISPLAY_HANDLE_T dispman_display = (DISPMANX_DISPLAY_HANDLE_T) (intptr_t) display; + BCM_ELEMENT_T * p = (BCM_ELEMENT_T *) (intptr_t) window ; + + DBG_PRINT( "BCM.Display Window.Close %p, element %p\n", + (void*)(intptr_t)dispman_display, (void*)(intptr_t)p->handle); + + if( 0 == dispman_display || NULL == p || 0 == p->handle ) { + return; + } + DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start( 0 ); + vc_dispmanx_element_remove( dispman_update, p->handle ); + p->handle = 0; + vc_dispmanx_update_submit_sync( dispman_update ); + free( p ); } /* @@ -204,10 +442,41 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setFullScr { } +JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setPos0 + (JNIEnv *env, jobject obj, jlong window, jint x, jint y) +{ + BCM_ELEMENT_T * p = (BCM_ELEMENT_T *) (intptr_t) window ; + + if( NULL == p || 0 == p->handle ) { + return; + } + p->x = x; + p->y = y; + + DBG_PRINT( "BCM.Display Window.Pos %p, element %p - %d/%d %dx%d\n", + p, (void*)(intptr_t)p->handle, p->x, p->y, p->width, p->height); + + bcm_moveTo( p->handle, p->layer, p->x, p->y, p->width, p->height); + (*env)->CallVoidMethod(env, obj, positionChangedID, JNI_FALSE, x, y); +} + + JNIEXPORT void JNICALL Java_jogamp_newt_driver_bcm_vc_iv_WindowDriver_setSize0 (JNIEnv *env, jobject obj, jlong window, jint width, jint height) { - // FIXME RESIZE (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE); + BCM_ELEMENT_T * p = (BCM_ELEMENT_T *) (intptr_t) window ; + + if( NULL == p || 0 == p->handle ) { + return; + } + p->width = width; + p->height = height; + + DBG_PRINT( "BCM.Display Window.Resize %p, element %p - %d/%d %dx%d\n", + p, (void*)(intptr_t)p->handle, p->x, p->y, p->width, p->height); + + bcm_moveTo( p->handle, p->layer, p->x, p->y, p->width, p->height); + (*env)->CallVoidMethod(env, obj, sizeChangedID, JNI_FALSE, (jint) width, (jint) height, JNI_FALSE); } |