aboutsummaryrefslogtreecommitdiffstats
path: root/java/org
diff options
context:
space:
mode:
authorPo Lu2023-01-14 22:12:16 +0800
committerPo Lu2023-01-14 22:12:16 +0800
commit2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a (patch)
tree3ab31df90bd435009d2d42b636ce3baf33bd2b28 /java/org
parent28a9baccd4c8e997895d3adb3cfce4a11fa29896 (diff)
downloademacs-2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a.tar.gz
emacs-2b87ab7b27163fbd7b6b64c5a44e26b0e692c00a.zip
Update Android port
* 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.
Diffstat (limited to 'java/org')
-rw-r--r--java/org/gnu/emacs/EmacsActivity.java2
-rw-r--r--java/org/gnu/emacs/EmacsContextMenu.java213
-rw-r--r--java/org/gnu/emacs/EmacsDrawRectangle.java2
-rw-r--r--java/org/gnu/emacs/EmacsGC.java1
-rw-r--r--java/org/gnu/emacs/EmacsService.java43
-rw-r--r--java/org/gnu/emacs/EmacsView.java47
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java161
7 files changed, 448 insertions, 21 deletions
diff --git a/java/org/gnu/emacs/EmacsActivity.java b/java/org/gnu/emacs/EmacsActivity.java
index 2b661024842..4cd286d1e89 100644
--- a/java/org/gnu/emacs/EmacsActivity.java
+++ b/java/org/gnu/emacs/EmacsActivity.java
@@ -43,7 +43,7 @@ public class EmacsActivity extends Activity
43 private FrameLayout layout; 43 private FrameLayout layout;
44 44
45 /* List of activities with focus. */ 45 /* List of activities with focus. */
46 private static List<EmacsActivity> focusedActivities; 46 public static List<EmacsActivity> focusedActivities;
47 47
48 /* The currently focused window. */ 48 /* The currently focused window. */
49 public static EmacsWindow focusedWindow; 49 public static EmacsWindow focusedWindow;
diff --git a/java/org/gnu/emacs/EmacsContextMenu.java b/java/org/gnu/emacs/EmacsContextMenu.java
new file mode 100644
index 00000000000..8d7ae08b257
--- /dev/null
+++ b/java/org/gnu/emacs/EmacsContextMenu.java
@@ -0,0 +1,213 @@
1/* Communication module for Android terminals. -*- c-file-style: "GNU" -*-
2
3Copyright (C) 2023 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or (at
10your option) any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20package org.gnu.emacs;
21
22import java.util.List;
23import java.util.ArrayList;
24
25import android.content.Context;
26import android.content.Intent;
27
28import android.os.Bundle;
29
30import android.view.Menu;
31import android.view.MenuItem;
32import android.view.View;
33
34import android.widget.PopupMenu;
35
36/* Context menu implementation. This object is built from JNI and
37 describes a menu hiearchy. Then, `inflate' can turn it into an
38 Android menu, which can be turned into a popup (or other kind of)
39 menu. */
40
41public class EmacsContextMenu
42{
43 private class Item
44 {
45 public int itemID;
46 public String itemName;
47 public EmacsContextMenu subMenu;
48 public boolean isEnabled;
49 };
50
51 public List<Item> menuItems;
52 public String title;
53 private EmacsContextMenu parent;
54
55 /* Create a context menu with no items inside and the title TITLE,
56 which may be NULL. */
57
58 public static EmacsContextMenu
59 createContextMenu (String title)
60 {
61 EmacsContextMenu menu;
62
63 menu = new EmacsContextMenu ();
64 menu.menuItems = new ArrayList<Item> ();
65 menu.title = title;
66
67 return menu;
68 }
69
70 /* Add a normal menu item to the context menu with the id ITEMID and
71 the name ITEMNAME. Enable it if ISENABLED, else keep it
72 disabled. */
73
74 public void
75 addItem (int itemID, String itemName, boolean isEnabled)
76 {
77 Item item;
78
79 item = new Item ();
80 item.itemID = itemID;
81 item.itemName = itemName;
82 item.isEnabled = isEnabled;
83
84 menuItems.add (item);
85 }
86
87 /* Create a disabled menu item with the name ITEMNAME. */
88
89 public void
90 addPane (String itemName)
91 {
92 Item item;
93
94 item = new Item ();
95 item.itemName = itemName;
96
97 menuItems.add (item);
98 }
99
100 /* Add a submenu to the context menu with the specified title and
101 item name. */
102
103 public EmacsContextMenu
104 addSubmenu (String itemName, String title)
105 {
106 EmacsContextMenu submenu;
107 Item item;
108
109 item = new Item ();
110 item.itemID = 0;
111 item.itemName = itemName;
112 item.subMenu = createContextMenu (title);
113 item.subMenu.parent = this;
114
115 menuItems.add (item);
116 return item.subMenu;
117 }
118
119 /* Add the contents of this menu to MENU. */
120
121 private void
122 inflateMenuItems (Menu menu)
123 {
124 Intent intent;
125 MenuItem menuItem;
126 Menu submenu;
127
128 for (Item item : menuItems)
129 {
130 if (item.subMenu != null)
131 {
132 /* This is a submenu. Create the submenu and add the
133 contents of the menu to it. */
134 submenu = menu.addSubMenu (item.itemName);
135 inflateMenuItems (submenu);
136 }
137 else
138 {
139 menuItem = menu.add (item.itemName);
140
141 /* If the item ID is zero, then disable the item. */
142 if (item.itemID == 0 || !item.isEnabled)
143 menuItem.setEnabled (false);
144 }
145 }
146 }
147
148 /* Enter the items in this context menu to MENU. Create each menu
149 item with an Intent containing a Bundle, where the key
150 "emacs:menu_item_hi" maps to the high 16 bits of the
151 corresponding item ID, and the key "emacs:menu_item_low" maps to
152 the low 16 bits of the item ID. */
153
154 public void
155 expandTo (Menu menu)
156 {
157 inflateMenuItems (menu);
158 }
159
160 /* Return the parent or NULL. */
161
162 public EmacsContextMenu
163 parent ()
164 {
165 return parent;
166 }
167
168 /* Like display, but does the actual work and runs in the main
169 thread. */
170
171 private boolean
172 display1 (EmacsWindow window, int xPosition, int yPosition)
173 {
174 return window.view.popupMenu (this, xPosition, yPosition);
175 }
176
177 /* Display this context menu on WINDOW, at xPosition and
178 yPosition. */
179
180 public boolean
181 display (final EmacsWindow window, final int xPosition,
182 final int yPosition)
183 {
184 Runnable runnable;
185 final Holder<Boolean> rc;
186
187 rc = new Holder<Boolean> ();
188
189 runnable = new Runnable () {
190 @Override
191 public void
192 run ()
193 {
194 synchronized (this)
195 {
196 rc.thing = display1 (window, xPosition, yPosition);
197 notify ();
198 }
199 }
200 };
201
202 try
203 {
204 runnable.wait ();
205 }
206 catch (InterruptedException e)
207 {
208 EmacsNative.emacsAbort ();
209 }
210
211 return rc.thing;
212 }
213};
diff --git a/java/org/gnu/emacs/EmacsDrawRectangle.java b/java/org/gnu/emacs/EmacsDrawRectangle.java
index b42e9556e8c..84ff498847b 100644
--- a/java/org/gnu/emacs/EmacsDrawRectangle.java
+++ b/java/org/gnu/emacs/EmacsDrawRectangle.java
@@ -59,7 +59,7 @@ public class EmacsDrawRectangle
59 } 59 }
60 60
61 paint = gc.gcPaint; 61 paint = gc.gcPaint;
62 rect = new Rect (x, y, x + width, y + height); 62 rect = new Rect (x + 1, y + 1, x + width, y + height);
63 63
64 paint.setStyle (Paint.Style.STROKE); 64 paint.setStyle (Paint.Style.STROKE);
65 65
diff --git a/java/org/gnu/emacs/EmacsGC.java b/java/org/gnu/emacs/EmacsGC.java
index caa5c91edd4..c579625f3f7 100644
--- a/java/org/gnu/emacs/EmacsGC.java
+++ b/java/org/gnu/emacs/EmacsGC.java
@@ -93,6 +93,7 @@ public class EmacsGC extends EmacsHandleObject
93 else 93 else
94 real_clip_rects = clip_rects; 94 real_clip_rects = clip_rects;
95 95
96 gcPaint.setStrokeWidth (1f);
96 gcPaint.setColor (foreground | 0xff000000); 97 gcPaint.setColor (foreground | 0xff000000);
97 gcPaint.setXfermode (function == GC_XOR 98 gcPaint.setXfermode (function == GC_XOR
98 ? xorAlu : srcInAlu); 99 ? xorAlu : srcInAlu);
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index c008300dd3a..f935b63fa0d 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -29,6 +29,7 @@ import android.graphics.Point;
29 29
30import android.view.View; 30import android.view.View;
31import android.view.InputDevice; 31import android.view.InputDevice;
32import android.view.KeyEvent;
32 33
33import android.annotation.TargetApi; 34import android.annotation.TargetApi;
34import android.app.Service; 35import android.app.Service;
@@ -150,13 +151,13 @@ public class EmacsService extends Service
150 /* Functions from here on must only be called from the Emacs 151 /* Functions from here on must only be called from the Emacs
151 thread. */ 152 thread. */
152 153
153 void 154 public void
154 runOnUiThread (Runnable runnable) 155 runOnUiThread (Runnable runnable)
155 { 156 {
156 handler.post (runnable); 157 handler.post (runnable);
157 } 158 }
158 159
159 EmacsView 160 public EmacsView
160 getEmacsView (final EmacsWindow window, final int visibility, 161 getEmacsView (final EmacsWindow window, final int visibility,
161 final boolean isFocusedByDefault) 162 final boolean isFocusedByDefault)
162 { 163 {
@@ -197,6 +198,38 @@ public class EmacsService extends Service
197 } 198 }
198 199
199 public void 200 public void
201 getLocationOnScreen (final EmacsView view, final int[] coordinates)
202 {
203 Runnable runnable;
204
205 runnable = new Runnable () {
206 public void
207 run ()
208 {
209 synchronized (this)
210 {
211 view.getLocationOnScreen (coordinates);
212 notify ();
213 }
214 }
215 };
216
217 synchronized (runnable)
218 {
219 runOnUiThread (runnable);
220
221 try
222 {
223 runnable.wait ();
224 }
225 catch (InterruptedException e)
226 {
227 EmacsNative.emacsAbort ();
228 }
229 }
230 }
231
232 public void
200 fillRectangle (EmacsDrawable drawable, EmacsGC gc, 233 fillRectangle (EmacsDrawable drawable, EmacsGC gc,
201 int x, int y, int width, int height) 234 int x, int y, int width, int height)
202 { 235 {
@@ -368,4 +401,10 @@ public class EmacsService extends Service
368 401
369 return false; 402 return false;
370 } 403 }
404
405 public String
406 nameKeysym (int keysym)
407 {
408 return KeyEvent.keyCodeToString (keysym);
409 }
371}; 410};
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 41acabab97b..1391f630be0 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -21,6 +21,7 @@ package org.gnu.emacs;
21 21
22import android.content.res.ColorStateList; 22import android.content.res.ColorStateList;
23 23
24import android.view.ContextMenu;
24import android.view.View; 25import android.view.View;
25import android.view.KeyEvent; 26import android.view.KeyEvent;
26import android.view.MotionEvent; 27import android.view.MotionEvent;
@@ -73,6 +74,12 @@ public class EmacsView extends ViewGroup
73 next call to getBitmap. */ 74 next call to getBitmap. */
74 private Rect bitmapDirty; 75 private Rect bitmapDirty;
75 76
77 /* Whether or not a popup is active. */
78 private boolean popupActive;
79
80 /* The current context menu. */
81 private EmacsContextMenu contextMenu;
82
76 public 83 public
77 EmacsView (EmacsWindow window) 84 EmacsView (EmacsWindow window)
78 { 85 {
@@ -98,6 +105,10 @@ public class EmacsView extends ViewGroup
98 /* Get rid of the foreground and background tint. */ 105 /* Get rid of the foreground and background tint. */
99 setBackgroundTintList (null); 106 setBackgroundTintList (null);
100 setForegroundTintList (null); 107 setForegroundTintList (null);
108
109 /* Get rid of the default focus highlight. */
110 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O)
111 setDefaultFocusHighlightEnabled (false);
101 } 112 }
102 113
103 private void 114 private void
@@ -423,4 +434,40 @@ public class EmacsView extends ViewGroup
423 removeView (surfaceView); 434 removeView (surfaceView);
424 addView (surfaceView, 0); 435 addView (surfaceView, 0);
425 } 436 }
437
438 @Override
439 protected void
440 onCreateContextMenu (ContextMenu menu)
441 {
442 if (contextMenu == null)
443 return;
444
445 contextMenu.expandTo (menu);
446 }
447
448 public boolean
449 popupMenu (EmacsContextMenu menu, int xPosition,
450 int yPosition)
451 {
452 if (popupActive)
453 return false;
454
455 contextMenu = menu;
456
457 /* On API 21 or later, use showContextMenu (float, float). */
458 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)
459 return showContextMenu ((float) xPosition, (float) yPosition);
460 else
461 return showContextMenu ();
462 }
463
464 public void
465 cancelPopupMenu ()
466 {
467 if (!popupActive)
468 throw new IllegalStateException ("cancelPopupMenu called without"
469 + " popupActive set");
470
471 contextMenu = null;
472 }
426}; 473};
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java
index 1f8596dba50..6effa79d1a4 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -24,16 +24,22 @@ import java.util.ArrayList;
24import java.util.List; 24import java.util.List;
25import java.util.HashMap; 25import java.util.HashMap;
26 26
27import android.content.Context;
28
27import android.graphics.Rect; 29import android.graphics.Rect;
28import android.graphics.Canvas; 30import android.graphics.Canvas;
29import android.graphics.Bitmap; 31import android.graphics.Bitmap;
30import android.graphics.Point; 32import android.graphics.Point;
33import android.graphics.PixelFormat;
31 34
32import android.view.View; 35import android.view.View;
36import android.view.ViewManager;
33import android.view.ViewGroup; 37import android.view.ViewGroup;
38import android.view.Gravity;
34import android.view.KeyEvent; 39import android.view.KeyEvent;
35import android.view.MotionEvent; 40import android.view.MotionEvent;
36import android.view.InputDevice; 41import android.view.InputDevice;
42import android.view.WindowManager;
37 43
38import android.content.Intent; 44import android.content.Intent;
39import android.util.Log; 45import android.util.Log;
@@ -110,9 +116,17 @@ public class EmacsWindow extends EmacsHandleObject
110 not the window should be focusable. */ 116 not the window should be focusable. */
111 private boolean dontFocusOnMap, dontAcceptFocus; 117 private boolean dontFocusOnMap, dontAcceptFocus;
112 118
119 /* Whether or not the window is override-redirect. An
120 override-redirect window always has its own system window. */
121 private boolean overrideRedirect;
122
123 /* The window manager that is the parent of this window. NULL if
124 there is no such window manager. */
125 private WindowManager windowManager;
126
113 public 127 public
114 EmacsWindow (short handle, final EmacsWindow parent, int x, int y, 128 EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
115 int width, int height) 129 int width, int height, boolean overrideRedirect)
116 { 130 {
117 super (handle); 131 super (handle);
118 132
@@ -124,6 +138,7 @@ public class EmacsWindow extends EmacsHandleObject
124 view = EmacsService.SERVICE.getEmacsView (this, View.GONE, 138 view = EmacsService.SERVICE.getEmacsView (this, View.GONE,
125 parent == null); 139 parent == null);
126 this.parent = parent; 140 this.parent = parent;
141 this.overrideRedirect = overrideRedirect;
127 142
128 /* Create the list of children. */ 143 /* Create the list of children. */
129 children = new ArrayList<EmacsWindow> (); 144 children = new ArrayList<EmacsWindow> ();
@@ -180,7 +195,7 @@ public class EmacsWindow extends EmacsHandleObject
180 public void 195 public void
181 run () 196 run ()
182 { 197 {
183 View parent; 198 ViewManager parent;
184 EmacsWindowAttachmentManager manager; 199 EmacsWindowAttachmentManager manager;
185 200
186 if (EmacsActivity.focusedWindow == EmacsWindow.this) 201 if (EmacsActivity.focusedWindow == EmacsWindow.this)
@@ -189,10 +204,15 @@ public class EmacsWindow extends EmacsHandleObject
189 manager = EmacsWindowAttachmentManager.MANAGER; 204 manager = EmacsWindowAttachmentManager.MANAGER;
190 view.setVisibility (View.GONE); 205 view.setVisibility (View.GONE);
191 206
192 parent = (View) view.getParent (); 207 /* If the window manager is set, use that instead. */
208 if (windowManager != null)
209 parent = windowManager;
210 else
211 parent = (ViewManager) view.getParent ();
212 windowManager = null;
193 213
194 if (parent != null) 214 if (parent != null)
195 ((ViewGroup) parent).removeView (view); 215 parent.removeView (view);
196 216
197 manager.detachWindow (EmacsWindow.this); 217 manager.detachWindow (EmacsWindow.this);
198 } 218 }
@@ -247,6 +267,10 @@ public class EmacsWindow extends EmacsHandleObject
247 public void 267 public void
248 run () 268 run ()
249 { 269 {
270 if (overrideRedirect)
271 /* Set the layout parameters again. */
272 view.setLayoutParams (getWindowLayoutParams ());
273
250 view.mustReportLayout = true; 274 view.mustReportLayout = true;
251 view.requestLayout (); 275 view.requestLayout ();
252 } 276 }
@@ -284,6 +308,39 @@ public class EmacsWindow extends EmacsHandleObject
284 } 308 }
285 } 309 }
286 310
311 private WindowManager.LayoutParams
312 getWindowLayoutParams ()
313 {
314 WindowManager.LayoutParams params;
315 int flags, type;
316 Rect rect;
317
318 flags = 0;
319 rect = getGeometry ();
320 flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
321 flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
322 type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
323
324 params
325 = new WindowManager.LayoutParams (rect.width (), rect.height (),
326 rect.left, rect.top,
327 type, flags,
328 PixelFormat.RGBA_8888);
329 params.gravity = Gravity.TOP | Gravity.LEFT;
330 return params;
331 }
332
333 private Context
334 findSuitableActivityContext ()
335 {
336 /* Find a recently focused activity. */
337 if (!EmacsActivity.focusedActivities.isEmpty ())
338 return EmacsActivity.focusedActivities.get (0);
339
340 /* Return the service context, which probably won't work. */
341 return EmacsService.SERVICE;
342 }
343
287 public void 344 public void
288 mapWindow () 345 mapWindow ()
289 { 346 {
@@ -300,20 +357,60 @@ public class EmacsWindow extends EmacsHandleObject
300 run () 357 run ()
301 { 358 {
302 EmacsWindowAttachmentManager manager; 359 EmacsWindowAttachmentManager manager;
360 WindowManager windowManager;
361 Context ctx;
362 Object tem;
363 WindowManager.LayoutParams params;
303 364
304 /* Make the view visible, first of all. */ 365 /* Make the view visible, first of all. */
305 view.setVisibility (View.VISIBLE); 366 view.setVisibility (View.VISIBLE);
306 367
307 manager = EmacsWindowAttachmentManager.MANAGER; 368 if (!overrideRedirect)
308 369 {
309 /* If parent is the root window, notice that there are new 370 manager = EmacsWindowAttachmentManager.MANAGER;
310 children available for interested activites to pick 371
311 up. */ 372 /* If parent is the root window, notice that there are new
312 manager.registerWindow (EmacsWindow.this); 373 children available for interested activites to pick
313 374 up. */
314 if (!getDontFocusOnMap ()) 375 manager.registerWindow (EmacsWindow.this);
315 /* Eventually this should check no-focus-on-map. */ 376
316 view.requestFocus (); 377 if (!getDontFocusOnMap ())
378 /* Eventually this should check no-focus-on-map. */
379 view.requestFocus ();
380 }
381 else
382 {
383 /* But if the window is an override-redirect window,
384 then:
385
386 - Find an activity that is currently active.
387
388 - Map the window as a panel on top of that
389 activity using the system window manager. */
390
391 ctx = findSuitableActivityContext ();
392 tem = ctx.getSystemService (Context.WINDOW_SERVICE);
393 windowManager = (WindowManager) tem;
394
395 /* Calculate layout parameters. */
396 params = getWindowLayoutParams ();
397 view.setLayoutParams (params);
398
399 /* Attach the view. */
400 try
401 {
402 windowManager.addView (view, params);
403
404 /* Record the window manager being used in the
405 EmacsWindow object. */
406 EmacsWindow.this.windowManager = windowManager;
407 }
408 catch (Exception e)
409 {
410 Log.w (TAG,
411 "failed to attach override-redirect window, " + e);
412 }
413 }
317 } 414 }
318 }); 415 });
319 } 416 }
@@ -355,6 +452,11 @@ public class EmacsWindow extends EmacsHandleObject
355 452
356 view.setVisibility (View.GONE); 453 view.setVisibility (View.GONE);
357 454
455 /* Detach the view from the window manager if possible. */
456 if (windowManager != null)
457 windowManager.removeView (view);
458 windowManager = null;
459
358 /* Now that the window is unmapped, unregister it as 460 /* Now that the window is unmapped, unregister it as
359 well. */ 461 well. */
360 manager.detachWindow (EmacsWindow.this); 462 manager.detachWindow (EmacsWindow.this);
@@ -756,17 +858,23 @@ public class EmacsWindow extends EmacsHandleObject
756 run () 858 run ()
757 { 859 {
758 EmacsWindowAttachmentManager manager; 860 EmacsWindowAttachmentManager manager;
759 View parent; 861 ViewManager parent;
760 862
761 /* First, detach this window if necessary. */ 863 /* First, detach this window if necessary. */
762 manager = EmacsWindowAttachmentManager.MANAGER; 864 manager = EmacsWindowAttachmentManager.MANAGER;
763 manager.detachWindow (EmacsWindow.this); 865 manager.detachWindow (EmacsWindow.this);
764 866
765 /* Also unparent this view. */ 867 /* Also unparent this view. */
766 parent = (View) view.getParent (); 868
869 /* If the window manager is set, use that instead. */
870 if (windowManager != null)
871 parent = windowManager;
872 else
873 parent = (ViewManager) view.getParent ();
874 windowManager = null;
767 875
768 if (parent != null) 876 if (parent != null)
769 ((ViewGroup) parent).removeView (view); 877 parent.removeView (view);
770 878
771 /* Next, either add this window as a child of the new 879 /* Next, either add this window as a child of the new
772 parent's view, or make it available again. */ 880 parent's view, or make it available again. */
@@ -899,4 +1007,23 @@ public class EmacsWindow extends EmacsHandleObject
899 { 1007 {
900 return dontFocusOnMap; 1008 return dontFocusOnMap;
901 } 1009 }
1010
1011 public int[]
1012 translateCoordinates (int x, int y)
1013 {
1014 int[] array;
1015
1016 /* This is supposed to translate coordinates to the root
1017 window. */
1018 array = new int[2];
1019 EmacsService.SERVICE.getLocationOnScreen (view, array);
1020
1021 /* Now, the coordinates of the view should be in array. Offset X
1022 and Y by them. */
1023 array[0] += x;
1024 array[1] += y;
1025
1026 /* Return the resulting coordinates. */
1027 return array;
1028 }
902}; 1029};