aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
authorPo Lu2023-09-25 13:01:44 +0800
committerPo Lu2023-09-25 13:01:44 +0800
commitdf5a9a78b51f2f42d2dbb010e811a239fc014732 (patch)
tree748ced4f467648d2cdcb0e1845130bcac9bc6d7c /src/android.c
parent947409d408ed763a9fc35f9f7df97fec28a16837 (diff)
downloademacs-df5a9a78b51f2f42d2dbb010e811a239fc014732.tar.gz
emacs-df5a9a78b51f2f42d2dbb010e811a239fc014732.zip
Update Android port
* doc/lispref/os.texi (Desktop Notifications): Revise documentation for android-notifications-notify to reflect changes. * java/org/gnu/emacs/EmacsDesktopNotification.java (display1): Convert notification importance to a legacy priority between Android 7.1 and 4.1. * java/org/gnu/emacs/EmacsPixmap.java (EmacsPixmap): Remove immutable bitmap constructor, as the underlying Android API functions are erroneously implemented. * src/android.c (android_init_emacs_pixmap): Cease searching for deleted constructor. (android_create_pixmap_from_bitmap_data): Create a pixmap, then fill it with the contents of the bitmap, in lieu of employing the aforementioned constructor. * src/androidselect.c (Fandroid_notifications_notify): Revise doc string.
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c129
1 files changed, 66 insertions, 63 deletions
diff --git a/src/android.c b/src/android.c
index 0996a84823d..4df9d71b1b1 100644
--- a/src/android.c
+++ b/src/android.c
@@ -73,7 +73,6 @@ bool android_init_gui;
73struct android_emacs_pixmap 73struct android_emacs_pixmap
74{ 74{
75 jclass class; 75 jclass class;
76 jmethodID constructor;
77 jmethodID constructor_mutable; 76 jmethodID constructor_mutable;
78}; 77};
79 78
@@ -1649,7 +1648,6 @@ android_init_emacs_pixmap (void)
1649 name, signature); \ 1648 name, signature); \
1650 assert (pixmap_class.c_name); 1649 assert (pixmap_class.c_name);
1651 1650
1652 FIND_METHOD (constructor, "<init>", "(S[IIII)V");
1653 FIND_METHOD (constructor_mutable, "<init>", "(SIII)V"); 1651 FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
1654 1652
1655#undef FIND_METHOD 1653#undef FIND_METHOD
@@ -3404,86 +3402,91 @@ android_create_pixmap_from_bitmap_data (char *data, unsigned int width,
3404 unsigned long background, 3402 unsigned long background,
3405 unsigned int depth) 3403 unsigned int depth)
3406{ 3404{
3407 android_handle prev_max_handle;
3408 jobject object;
3409 jintArray colors;
3410 android_pixmap pixmap; 3405 android_pixmap pixmap;
3406 jobject object;
3407 AndroidBitmapInfo info;
3408 unsigned int *depth_24;
3409 unsigned char *depth_8;
3410 void *bitmap_data;
3411 unsigned int x, y; 3411 unsigned int x, y;
3412 jint *region; 3412 unsigned int r, g, b;
3413 3413
3414 USE_SAFE_ALLOCA; 3414 /* Create a pixmap with the right dimensions and depth. */
3415 pixmap = android_create_pixmap (width, height, depth);
3415 3416
3416 /* Create the color array holding the data. */ 3417 /* Lock the bitmap data. */
3417 colors = (*android_java_env)->NewIntArray (android_java_env, 3418 bitmap_data = android_lock_bitmap (pixmap, &info, &object);
3418 width * height); 3419
3419 android_exception_check (); 3420 /* Merely return if locking the bitmap fails. */
3421 if (!bitmap_data)
3422 return pixmap;
3420 3423
3421 SAFE_NALLOCA (region, sizeof *region, width); 3424 eassert (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888
3425 || info.format == ANDROID_BITMAP_FORMAT_A_8);
3422 3426
3423 for (y = 0; y < height; ++y) 3427 /* Begin copying each line. */
3428
3429 switch (info.format)
3424 { 3430 {
3425 for (x = 0; x < width; ++x) 3431 case ANDROID_BITMAP_FORMAT_RGBA_8888:
3432
3433 /* Swizzle the pixels into ABGR format. Android uses Skia's
3434 ``native color type'', which is ABGR. This is despite the
3435 format being named ``ARGB'', and more confusingly
3436 `ANDROID_BITMAP_FORMAT_RGBA_8888' in bitmap.h. */
3437
3438 r = background & 0x00ff0000;
3439 g = background & 0x0000ff00;
3440 b = background & 0x000000ff;
3441 background = (r >> 16) | g | (b << 16) | 0xff000000;
3442 r = foreground & 0x00ff0000;
3443 g = foreground & 0x0000ff00;
3444 b = foreground & 0x000000ff;
3445 foreground = (r >> 16) | g | (b << 16) | 0xff000000;
3446
3447 for (y = 0; y < height; ++y)
3426 { 3448 {
3427 if (depth == 24) 3449 depth_24 = (void *) ((char *) bitmap_data + y * info.stride);
3428 {
3429 /* The alpha channels must be set, or otherwise, the
3430 pixmap will be created entirely transparent. */
3431 3450
3432 if (data[x / 8] & (1 << (x % 8))) 3451 for (x = 0; x < width; ++x)
3433 region[x] = foreground | 0xff000000; 3452 depth_24[x] = ((data[x / 8] & (1 << (x % 8)))
3434 else 3453 ? foreground : background);
3435 region[x] = background | 0xff000000; 3454
3436 } 3455 data += (width + 7) / 8;
3437 else
3438 {
3439 if (data[x / 8] & (1 << (x % 8)))
3440 region[x] = foreground;
3441 else
3442 region[x] = background;
3443 }
3444 } 3456 }
3445 3457
3446 (*android_java_env)->SetIntArrayRegion (android_java_env, 3458 break;
3447 colors,
3448 width * y, width,
3449 region);
3450 data += width / 8;
3451 }
3452 3459
3453 /* First, allocate the pixmap handle. */ 3460 case ANDROID_BITMAP_FORMAT_A_8:
3454 prev_max_handle = max_handle;
3455 pixmap = android_alloc_id ();
3456 3461
3457 if (!pixmap) 3462 /* 8-bit pixmaps are created, but in spite of that they are
3458 { 3463 employed only to represent bitmaps. */
3459 ANDROID_DELETE_LOCAL_REF ((jobject) colors);
3460 error ("Out of pixmap handles!");
3461 }
3462 3464
3463 object = (*android_java_env)->NewObject (android_java_env, 3465 foreground = (foreground ? 255 : 0);
3464 pixmap_class.class, 3466 background = (background ? 255 : 0);
3465 pixmap_class.constructor,
3466 (jshort) pixmap, colors,
3467 (jint) width, (jint) height,
3468 (jint) depth);
3469 (*android_java_env)->ExceptionClear (android_java_env);
3470 ANDROID_DELETE_LOCAL_REF ((jobject) colors);
3471 3467
3472 if (!object) 3468 for (y = 0; y < height; ++y)
3473 { 3469 {
3474 max_handle = prev_max_handle; 3470 depth_8 = (void *) ((char *) bitmap_data + y * info.stride);
3475 memory_full (0); 3471
3472 for (x = 0; x < width; ++x)
3473 depth_8[x] = ((data[x / 8] & (1 << (x % 8)))
3474 ? foreground : background);
3475
3476 data += (width + 7) / 8;
3477 }
3478
3479 break;
3480
3481 default:
3482 emacs_abort ();
3476 } 3483 }
3477 3484
3478 android_handles[pixmap].type = ANDROID_HANDLE_PIXMAP; 3485 /* Unlock the bitmap itself. */
3479 android_handles[pixmap].handle 3486 AndroidBitmap_unlockPixels (android_java_env, object);
3480 = (*android_java_env)->NewGlobalRef (android_java_env, object);
3481 ANDROID_DELETE_LOCAL_REF (object); 3487 ANDROID_DELETE_LOCAL_REF (object);
3482 3488
3483 if (!android_handles[pixmap].handle) 3489 /* Return the pixmap. */
3484 memory_full (0);
3485
3486 SAFE_FREE ();
3487 return pixmap; 3490 return pixmap;
3488} 3491}
3489 3492