* java/Makefile.in (clean): Fix distclean and bootstrap-clean rules. * java/debug.sh (jdb_port): (attach_existing): (num_pids): (line): Add new options to upload a gdbserver binary to the device. * java/org/gnu/emacs/EmacsActivity.java (EmacsActivity): Make focusedActivities public. * java/org/gnu/emacs/EmacsContextMenu.java (EmacsContextMenu): New class. * java/org/gnu/emacs/EmacsDrawRectangle.java (perform): Fix bounds computation. * java/org/gnu/emacs/EmacsGC.java (markDirty): Set stroke width explicitly. * java/org/gnu/emacs/EmacsService.java (EmacsService) (getLocationOnScreen, nameKeysym): New functions. * java/org/gnu/emacs/EmacsView.java (EmacsView): Disable focus highlight. (onCreateContextMenu, popupMenu, cancelPopupMenu): New functions. * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow): Implement a kind of ``override redirect'' window for tooltips. * src/android.c (struct android_emacs_service): New method `name_keysym'. (android_run_select_thread, android_init_events): (android_select): Release select thread on semaphores instead of signals to avoid one nasty race on SIGUSR2 delivery. (android_init_emacs_service): Initialize new method. (android_create_window): Handle CW_OVERRIDE_REDIRECT. (android_move_resize_window, android_map_raised) (android_translate_coordinates, android_get_keysym_name) (android_build_string, android_exception_check): New functions. * src/android.h: Update prototypes. * src/androidfns.c (android_set_parent_frame, Fx_create_frame) (unwind_create_tip_frame, android_create_tip_frame) (android_hide_tip, compute_tip_xy, Fx_show_tip, Fx_hide_tip) (syms_of_androidfns): Implement tooltips and iconification reporting. * src/androidgui.h (enum android_window_value_mask): Add CWOverrideRedirect. (struct android_set_window_attributes): Add `override_redirect'. (ANDROID_IS_MODIFIER_KEY): Recognize Caps Lock. * src/androidmenu.c (struct android_emacs_context_menu): New struct. (android_init_emacs_context_menu, android_unwind_local_frame) (android_push_local_frame, android_menu_show, init_androidmenu): New functions. * src/androidterm.c (handle_one_android_event): Fix NULL pointer dereference. (android_fullscreen_hook): Handle fullscreen correctly. (android_draw_box_rect): Fix top line. (get_keysym_name): Implement function. (android_create_terminal): Remove scroll bar stubs and add menu hook. * src/androidterm.h: Update prototypes. * src/emacs.c (android_emacs_init): Initialize androidmenu.c. * xcompile/Makefile.in: Fix clean rules.
125 lines
3.5 KiB
Java
125 lines
3.5 KiB
Java
/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
|
|
|
|
Copyright (C) 2023 Free Software Foundation, Inc.
|
|
|
|
This file is part of GNU Emacs.
|
|
|
|
GNU Emacs is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or (at
|
|
your option) any later version.
|
|
|
|
GNU Emacs is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
package org.gnu.emacs;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Rect;
|
|
|
|
import android.util.Log;
|
|
|
|
public class EmacsDrawRectangle
|
|
{
|
|
public static void
|
|
perform (EmacsDrawable drawable, EmacsGC gc,
|
|
int x, int y, int width, int height)
|
|
{
|
|
int i;
|
|
Paint maskPaint, paint;
|
|
Canvas maskCanvas;
|
|
Bitmap maskBitmap;
|
|
Rect rect;
|
|
Rect maskRect, dstRect;
|
|
Canvas canvas;
|
|
Bitmap clipBitmap;
|
|
|
|
/* TODO implement stippling. */
|
|
if (gc.fill_style == EmacsGC.GC_FILL_OPAQUE_STIPPLED)
|
|
return;
|
|
|
|
canvas = drawable.lockCanvas ();
|
|
|
|
if (canvas == null)
|
|
return;
|
|
|
|
canvas.save ();
|
|
|
|
if (gc.real_clip_rects != null)
|
|
{
|
|
for (i = 0; i < gc.real_clip_rects.length; ++i)
|
|
canvas.clipRect (gc.real_clip_rects[i]);
|
|
}
|
|
|
|
paint = gc.gcPaint;
|
|
rect = new Rect (x + 1, y + 1, x + width, y + height);
|
|
|
|
paint.setStyle (Paint.Style.STROKE);
|
|
|
|
if (gc.clip_mask == null)
|
|
canvas.drawRect (rect, paint);
|
|
else
|
|
{
|
|
/* Drawing with a clip mask involves calculating the
|
|
intersection of the clip mask with the dst rect, and
|
|
extrapolating the corresponding part of the src rect. */
|
|
clipBitmap = gc.clip_mask.bitmap;
|
|
dstRect = new Rect (x, y, x + width, y + height);
|
|
maskRect = new Rect (gc.clip_x_origin,
|
|
gc.clip_y_origin,
|
|
(gc.clip_x_origin
|
|
+ clipBitmap.getWidth ()),
|
|
(gc.clip_y_origin
|
|
+ clipBitmap.getHeight ()));
|
|
clipBitmap = gc.clip_mask.bitmap;
|
|
|
|
if (!maskRect.setIntersect (dstRect, maskRect))
|
|
/* There is no intersection between the clip mask and the
|
|
dest rect. */
|
|
return;
|
|
|
|
/* Finally, create a temporary bitmap that is the size of
|
|
maskRect. */
|
|
|
|
maskBitmap
|
|
= Bitmap.createBitmap (maskRect.width (), maskRect.height (),
|
|
Bitmap.Config.ARGB_8888);
|
|
|
|
/* Draw the mask onto the maskBitmap. */
|
|
maskCanvas = new Canvas (maskBitmap);
|
|
maskRect.offset (-gc.clip_x_origin,
|
|
-gc.clip_y_origin);
|
|
maskCanvas.drawBitmap (gc.clip_mask.bitmap,
|
|
maskRect, new Rect (0, 0,
|
|
maskRect.width (),
|
|
maskRect.height ()),
|
|
paint);
|
|
maskRect.offset (gc.clip_x_origin,
|
|
gc.clip_y_origin);
|
|
|
|
/* Set the transfer mode to SRC_IN to preserve only the parts
|
|
of the source that overlap with the mask. */
|
|
maskPaint = new Paint ();
|
|
maskPaint.setXfermode (EmacsGC.srcInAlu);
|
|
maskPaint.setStyle (Paint.Style.STROKE);
|
|
|
|
/* Draw the source. */
|
|
maskCanvas.drawRect (maskRect, maskPaint);
|
|
|
|
/* Finally, draw the mask bitmap to the destination. */
|
|
paint.setXfermode (null);
|
|
canvas.drawBitmap (maskBitmap, null, maskRect, paint);
|
|
}
|
|
|
|
canvas.restore ();
|
|
drawable.damageRect (new Rect (x, y, x + width + 1,
|
|
y + height + 1));
|
|
}
|
|
}
|