diff options
author | Sven Gothel <[email protected]> | 2019-11-29 07:32:52 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2019-11-29 07:32:52 +0100 |
commit | 381858b82c5197193ba2f490a8282149536a54f7 (patch) | |
tree | 4e416ce275283f84c051afb6d2b76496e09f137e /src/newt/native/drm_gbm.c | |
parent | bdbdcdc800294db3a84926b79503fc2e0e919128 (diff) |
Bug 1156: DRM/GBM: Add full PointerIcon (Cursor) Support
DRM allows 64x64 pixel cursor images, using GBM_FORMAT_ARGB888 only.
Notable: GBM_FORMAT_ARGB888 == PixelFormat.BGRA8888
Having fixed mouse and keyboard input with previous commit,
the demo com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT
shows via key press
- i -> pointer visible/invisible
- c -> pointer icon change
Diffstat (limited to 'src/newt/native/drm_gbm.c')
-rw-r--r-- | src/newt/native/drm_gbm.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/newt/native/drm_gbm.c b/src/newt/native/drm_gbm.c index 93b02dbe7..fd1879d88 100644 --- a/src/newt/native/drm_gbm.c +++ b/src/newt/native/drm_gbm.c @@ -49,6 +49,111 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_DispatchMes { } +JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_CreatePointerIcon0 + (JNIEnv *env, jclass clazz, jlong jgbmDevice, jobject jpixels, jint pixels_byte_offset, jboolean pixels_is_direct, + jint width, jint height, jint hotX, jint hotY) +{ + const uint32_t *pixels = NULL; + struct gbm_device * gbmDevice = (struct gbm_device *) (intptr_t) jgbmDevice; + struct gbm_bo *bo = NULL; + uint32_t bo_handle; + uint32_t buf[64 * 64]; + int i, j; + + ERR_PRINT("cursor.cstr %dx%d %d/%d\n", width, height, hotX, hotY); + + if ( NULL == jpixels ) { + ERR_PRINT("CreateCursor: null icon pixels\n"); + return 0; + } + if( 0 >= width || width > 64 || 0 >= height || height > 64 ) { + ERR_PRINT("CreateCursor: icon must be of size [1..64] x [1..64]\n"); + return 0; + } + { + const char * c1 = (const char *) ( JNI_TRUE == pixels_is_direct ? + (*env)->GetDirectBufferAddress(env, jpixels) : + (*env)->GetPrimitiveArrayCritical(env, jpixels, NULL) ); + pixels = (uint32_t *) ( c1 + pixels_byte_offset ); + } + + bo = gbm_bo_create(gbmDevice, 64, 64, + GBM_FORMAT_ARGB8888, + // GBM_FORMAT_BGRA8888, + GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE); + if( NULL == bo ) { + ERR_PRINT("cursor.cstr gbm_bo_create failed\n"); + return 0; + } + + // align user data width x height -> 64 x 64 + memset(buf, 0, sizeof(buf)); // cleanup + for(int i=0; i<height; i++) { + memcpy(buf + i * 64, pixels + i * width, width * 4); + } + if ( gbm_bo_write(bo, buf, sizeof(buf)) < 0 ) { + ERR_PRINT("cursor.cstr gbm_bo_write failed\n"); + gbm_bo_destroy(bo); + return 0; + } + return (jlong) (intptr_t) bo; +} + +JNIEXPORT void JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_DestroyPointerIcon0 + (JNIEnv *env, jclass clazz, jlong jcursor) +{ + struct gbm_bo *bo = (struct gbm_bo *) (intptr_t) jcursor; + + if ( NULL == bo ) { + ERR_PRINT("DestroyCursor: null cursor\n"); + return; + } + gbm_bo_destroy(bo); +} + +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_SetPointerIcon0 + (JNIEnv *env, jobject obj, jint drmFd, jint jcrtc_id, jlong jcursor, jboolean enable, jint x, jint y) +{ + uint32_t crtc_id = (uint32_t)jcrtc_id; + struct gbm_bo *bo = (struct gbm_bo *) (intptr_t) jcursor; + uint32_t bo_handle = gbm_bo_get_handle(bo).u32; + int ret; + + // int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height); + // int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y); + if( enable ) { + ret = drmModeSetCursor(drmFd, crtc_id, bo_handle, 64, 64); + if( ret ) { + ERR_PRINT("SetCursor enable failed: %d %s\n", ret, strerror(errno)); + } else { + ret = drmModeMoveCursor(drmFd, crtc_id, x, y); + if( ret ) { + ERR_PRINT("SetCursor move failed: %d %s\n", ret, strerror(errno)); + } + } + } else { + ret = drmModeSetCursor(drmFd, crtc_id, 0, 0, 0); + if( ret ) { + ERR_PRINT("SetCursor disable failed: %d %s\n", ret, strerror(errno)); + } + } + return ret ? JNI_FALSE : JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_egl_gbm_DisplayDriver_MovePointerIcon0 + (JNIEnv *env, jobject obj, jint drmFd, jint jcrtc_id, jint x, jint y) +{ + uint32_t crtc_id = (uint32_t)jcrtc_id; + int ret; + + ret = drmModeMoveCursor(drmFd, crtc_id, x, y); + if( ret ) { + ERR_PRINT("cursor drmModeMoveCursor failed: %d %s\n", ret, strerror(errno)); + return JNI_FALSE; + } + return JNI_TRUE; +} + /** * Screen */ |