This source file includes following definitions.
- changeWindowBackground
- getGeometry
- destroyHandle
- setConsumer
- getAttachedConsumer
- viewLayout
- requestViewLayout
- resizeWindow
- moveWindow
- getWindowLayoutParams
- findSuitableActivityContext
- mapWindow
- unmapWindow
- lockCanvas
- damageRect
- swapBuffers
- clearWindow
- clearArea
- getBitmap
- getEventUnicodeChar
- saveUnicodeString
- eventModifiers
- onKeyDown
- onKeyUp
- onFocusChanged
- onActivityDetached
- whatButtonWasIt
- buttonForEvent
- figureChange
- motionEventModifiers
- motionEvent
- onTouchEvent
- onGenericMotionEvent
- reparentTo
- makeInputFocus
- raise
- lower
- getWindowGeometry
- noticeIconified
- noticeDeiconified
- setDontAcceptFocus
- setDontFocusOnMap
- getDontFocusOnMap
- translateCoordinates
- toggleOnScreenKeyboard
- lookupString
- setFullscreen
- defineCursor
- notifyContentRectPosition
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.gnu.emacs;
21
22 import java.lang.IllegalStateException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.HashMap;
26 import java.util.LinkedHashMap;
27 import java.util.Map;
28
29 import android.content.Context;
30
31 import android.graphics.Rect;
32 import android.graphics.Canvas;
33 import android.graphics.Bitmap;
34 import android.graphics.PixelFormat;
35
36 import android.view.View;
37 import android.view.ViewManager;
38 import android.view.Gravity;
39 import android.view.KeyEvent;
40 import android.view.MotionEvent;
41 import android.view.InputDevice;
42 import android.view.WindowManager;
43
44 import android.util.Log;
45
46 import android.os.Build;
47
48
49
50
51
52
53
54
55
56
57
58
59 public final class EmacsWindow extends EmacsHandleObject
60 implements EmacsDrawable
61 {
62 private static final String TAG = "EmacsWindow";
63
64 private static class Coordinate
65 {
66
67 int x, y;
68
69
70
71 int button;
72
73
74 int id;
75
76 public
77 Coordinate (int x, int y, int button, int id)
78 {
79 this.x = x;
80 this.y = y;
81 this.button = button;
82 this.id = id;
83 }
84 };
85
86
87 public EmacsView view;
88
89
90 private Rect rect;
91
92
93 public EmacsWindow parent;
94
95
96
97 public ArrayList<EmacsWindow> children;
98
99
100
101 private HashMap<Integer, Coordinate> pointerMap;
102
103
104 private EmacsWindowAttachmentManager.WindowConsumer attached;
105
106
107
108 private EmacsGC scratchGC;
109
110
111
112 public int lastButtonState;
113
114
115 private volatile boolean isMapped;
116
117
118 private boolean dontFocusOnMap;
119
120
121
122 private boolean overrideRedirect;
123
124
125
126 private WindowManager windowManager;
127
128
129
130
131 private long lastVolumeButtonRelease;
132
133
134
135 public LinkedHashMap<Integer, String> eventStrings;
136
137
138 public boolean fullscreen;
139
140
141
142 public volatile int background;
143
144
145 public int xPosition, yPosition;
146
147 public
148 EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
149 int width, int height, boolean overrideRedirect)
150 {
151 super (handle);
152
153 rect = new Rect (x, y, x + width, y + height);
154 pointerMap = new HashMap<Integer, Coordinate> ();
155
156
157
158 view = EmacsService.SERVICE.getEmacsView (this, View.GONE,
159 parent == null);
160 this.parent = parent;
161 this.overrideRedirect = overrideRedirect;
162
163
164 children = new ArrayList<EmacsWindow> ();
165
166 if (parent != null)
167 {
168 parent.children.add (this);
169 EmacsService.SERVICE.runOnUiThread (new Runnable () {
170 @Override
171 public void
172 run ()
173 {
174 parent.view.addView (view);
175 }
176 });
177 }
178
179 scratchGC = new EmacsGC ((short) 0);
180
181
182
183
184 eventStrings
185 = new LinkedHashMap<Integer, String> () {
186 @Override
187 protected boolean
188 removeEldestEntry (Map.Entry<Integer, String> entry)
189 {
190 return size () > 10;
191 }
192 };
193 }
194
195 public void
196 changeWindowBackground (int pixel)
197 {
198
199 scratchGC.foreground = pixel;
200 scratchGC.markDirty (false);
201
202
203 background = pixel;
204 }
205
206 public synchronized Rect
207 getGeometry ()
208 {
209 return new Rect (rect);
210 }
211
212 @Override
213 public synchronized void
214 destroyHandle () throws IllegalStateException
215 {
216 if (parent != null)
217 parent.children.remove (this);
218
219 EmacsActivity.invalidateFocus ();
220
221 if (!children.isEmpty ())
222 throw new IllegalStateException ("Trying to destroy window with "
223 + "children!");
224
225
226 EmacsService.SERVICE.runOnUiThread (new Runnable () {
227 public void
228 run ()
229 {
230 ViewManager parent;
231 EmacsWindowAttachmentManager manager;
232
233 if (EmacsActivity.focusedWindow == EmacsWindow.this)
234 EmacsActivity.focusedWindow = null;
235
236 manager = EmacsWindowAttachmentManager.MANAGER;
237 view.setVisibility (View.GONE);
238
239
240 if (windowManager != null)
241 parent = windowManager;
242 else
243 parent = (ViewManager) view.getParent ();
244 windowManager = null;
245
246 if (parent != null)
247 parent.removeView (view);
248
249 manager.detachWindow (EmacsWindow.this);
250 }
251 });
252
253 super.destroyHandle ();
254 }
255
256 public void
257 setConsumer (EmacsWindowAttachmentManager.WindowConsumer consumer)
258 {
259 attached = consumer;
260 }
261
262 public EmacsWindowAttachmentManager.WindowConsumer
263 getAttachedConsumer ()
264 {
265 return attached;
266 }
267
268 public synchronized long
269 viewLayout (int left, int top, int right, int bottom)
270 {
271 int rectWidth, rectHeight;
272
273 rect.left = left;
274 rect.top = top;
275 rect.right = right;
276 rect.bottom = bottom;
277
278 rectWidth = right - left;
279 rectHeight = bottom - top;
280
281
282
283
284 if (parent == null)
285 {
286 left = xPosition;
287 top = yPosition;
288 }
289
290 return EmacsNative.sendConfigureNotify (this.handle,
291 System.currentTimeMillis (),
292 left, top, rectWidth,
293 rectHeight);
294 }
295
296 public void
297 requestViewLayout ()
298 {
299 view.explicitlyDirtyBitmap ();
300
301 EmacsService.SERVICE.runOnUiThread (new Runnable () {
302 @Override
303 public void
304 run ()
305 {
306 if (overrideRedirect)
307
308 view.setLayoutParams (getWindowLayoutParams ());
309
310 view.mustReportLayout = true;
311 view.requestLayout ();
312 }
313 });
314 }
315
316 public synchronized void
317 resizeWindow (int width, int height)
318 {
319 rect.right = rect.left + width;
320 rect.bottom = rect.top + height;
321
322 requestViewLayout ();
323 }
324
325 public synchronized void
326 moveWindow (int x, int y)
327 {
328 int width, height;
329
330 width = rect.width ();
331 height = rect.height ();
332
333 rect.left = x;
334 rect.top = y;
335 rect.right = x + width;
336 rect.bottom = y + height;
337
338 requestViewLayout ();
339 }
340
341 private WindowManager.LayoutParams
342 getWindowLayoutParams ()
343 {
344 WindowManager.LayoutParams params;
345 int flags, type;
346 Rect rect;
347
348 flags = 0;
349 rect = getGeometry ();
350 flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
351 flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
352 type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
353
354 params
355 = new WindowManager.LayoutParams (rect.width (), rect.height (),
356 rect.left, rect.top,
357 type, flags,
358 PixelFormat.RGBA_8888);
359 params.gravity = Gravity.TOP | Gravity.LEFT;
360 return params;
361 }
362
363 private Context
364 findSuitableActivityContext ()
365 {
366
367 if (!EmacsActivity.focusedActivities.isEmpty ())
368 return EmacsActivity.focusedActivities.get (0);
369
370
371 return EmacsService.SERVICE;
372 }
373
374 public synchronized void
375 mapWindow ()
376 {
377 final int width, height;
378
379 if (isMapped)
380 return;
381
382 isMapped = true;
383 width = rect.width ();
384 height = rect.height ();
385
386 if (parent == null)
387 {
388 EmacsService.SERVICE.runOnUiThread (new Runnable () {
389 @Override
390 public void
391 run ()
392 {
393 EmacsWindowAttachmentManager manager;
394 WindowManager windowManager;
395 Context ctx;
396 Object tem;
397 WindowManager.LayoutParams params;
398
399
400 view.setVisibility (View.VISIBLE);
401
402 if (!overrideRedirect)
403 {
404 manager = EmacsWindowAttachmentManager.MANAGER;
405
406
407
408
409 manager.registerWindow (EmacsWindow.this);
410
411 if (!getDontFocusOnMap ())
412
413 view.requestFocus ();
414 }
415 else
416 {
417
418
419
420
421
422
423
424
425 ctx = findSuitableActivityContext ();
426 tem = ctx.getSystemService (Context.WINDOW_SERVICE);
427 windowManager = (WindowManager) tem;
428
429
430 params = getWindowLayoutParams ();
431 view.setLayoutParams (params);
432
433
434 try
435 {
436 view.prepareForLayout (width, height);
437 windowManager.addView (view, params);
438
439
440
441 EmacsWindow.this.windowManager = windowManager;
442 }
443 catch (Exception e)
444 {
445 Log.w (TAG,
446 "failed to attach override-redirect window, " + e);
447 }
448 }
449 }
450 });
451 }
452 else
453 {
454
455
456 EmacsService.SERVICE.runOnUiThread (new Runnable () {
457 @Override
458 public void
459 run ()
460 {
461
462
463
464
465 view.prepareForLayout (width, height);
466 view.setVisibility (View.VISIBLE);
467
468 if (!getDontFocusOnMap ())
469 view.requestFocus ();
470 }
471 });
472 }
473 }
474
475 public synchronized void
476 unmapWindow ()
477 {
478 if (!isMapped)
479 return;
480
481 isMapped = false;
482
483 view.post (new Runnable () {
484 @Override
485 public void
486 run ()
487 {
488 EmacsWindowAttachmentManager manager;
489
490 manager = EmacsWindowAttachmentManager.MANAGER;
491
492 view.setVisibility (View.GONE);
493
494
495 if (windowManager != null)
496 windowManager.removeView (view);
497 windowManager = null;
498
499
500
501 manager.detachWindow (EmacsWindow.this);
502 }
503 });
504 }
505
506 @Override
507 public Canvas
508 lockCanvas (EmacsGC gc)
509 {
510 return view.getCanvas (gc);
511 }
512
513 @Override
514 public void
515 damageRect (Rect damageRect)
516 {
517 view.damageRect (damageRect);
518 }
519
520 public void
521 swapBuffers ()
522 {
523 view.swapBuffers ();
524 }
525
526 public void
527 clearWindow ()
528 {
529 EmacsService.SERVICE.fillRectangle (this, scratchGC,
530 0, 0, rect.width (),
531 rect.height ());
532 }
533
534 public void
535 clearArea (int x, int y, int width, int height)
536 {
537 EmacsService.SERVICE.fillRectangle (this, scratchGC,
538 x, y, width, height);
539 }
540
541 @Override
542 public Bitmap
543 getBitmap ()
544 {
545 return view.getBitmap ();
546 }
547
548
549
550 @SuppressWarnings ("deprecation")
551 public int
552 getEventUnicodeChar (KeyEvent event, int state)
553 {
554 String characters;
555
556 if (event.getUnicodeChar (state) != 0)
557 return event.getUnicodeChar (state);
558
559 characters = event.getCharacters ();
560
561 if (characters != null && characters.length () == 1)
562 return characters.charAt (0);
563
564 return characters == null ? 0 : -1;
565 }
566
567 public void
568 saveUnicodeString (int serial, String string)
569 {
570 eventStrings.put (serial, string);
571 }
572
573
574
575
576
577
578
579 private int
580 eventModifiers (KeyEvent event)
581 {
582 int state;
583
584 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
585 state = event.getModifiers ();
586 else
587 {
588
589
590 state = event.getMetaState ();
591
592
593
594
595 if ((state & KeyEvent.META_ALT_LEFT_ON) != 0
596 || (state & KeyEvent.META_ALT_RIGHT_ON) != 0)
597 state |= KeyEvent.META_ALT_MASK;
598
599 if ((state & KeyEvent.META_CTRL_LEFT_ON) != 0
600 || (state & KeyEvent.META_CTRL_RIGHT_ON) != 0)
601 state |= KeyEvent.META_CTRL_MASK;
602 }
603
604 return state;
605 }
606
607
608
609 @SuppressWarnings ("deprecation")
610 public void
611 onKeyDown (int keyCode, KeyEvent event)
612 {
613 int state, state_1;
614 long serial;
615 String characters;
616
617 state = eventModifiers (event);
618
619
620
621
622
623 state_1
624 = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK
625 | KeyEvent.META_SYM_ON | KeyEvent.META_META_MASK);
626
627 synchronized (eventStrings)
628 {
629 serial
630 = EmacsNative.sendKeyPress (this.handle,
631 event.getEventTime (),
632 state, keyCode,
633 getEventUnicodeChar (event,
634 state_1));
635
636 characters = event.getCharacters ();
637
638 if (characters != null && characters.length () > 1)
639 saveUnicodeString ((int) serial, characters);
640 }
641 }
642
643 public void
644 onKeyUp (int keyCode, KeyEvent event)
645 {
646 int state, state_1;
647 long time;
648
649
650 state = eventModifiers (event);
651
652
653
654
655
656 state_1
657 = state & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK
658 | KeyEvent.META_SYM_ON | KeyEvent.META_META_MASK);
659
660 EmacsNative.sendKeyRelease (this.handle,
661 event.getEventTime (),
662 state, keyCode,
663 getEventUnicodeChar (event,
664 state_1));
665
666 if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
667 {
668
669
670
671
672 time = event.getEventTime ();
673
674 if (time - lastVolumeButtonRelease < 350)
675 EmacsNative.quit ();
676
677 lastVolumeButtonRelease = time;
678 }
679 }
680
681 public void
682 onFocusChanged (boolean gainFocus)
683 {
684 EmacsActivity.invalidateFocus ();
685 }
686
687
688
689
690
691
692
693 public void
694 onActivityDetached (boolean isFinishing)
695 {
696
697
698
699 if (isFinishing)
700 EmacsNative.sendWindowAction (this.handle, 0);
701 }
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782 private int
783 whatButtonWasIt (MotionEvent event, boolean down)
784 {
785 int eventState, notIn;
786
787
788 eventState = event.getButtonState ();
789
790
791
792 notIn = (down ? eventState & ~lastButtonState
793 : lastButtonState & ~eventState);
794
795 if ((notIn & (MotionEvent.BUTTON_PRIMARY
796 | MotionEvent.BUTTON_SECONDARY
797 | MotionEvent.BUTTON_TERTIARY)) == 0)
798
799 return 0;
800
801 if ((notIn & MotionEvent.BUTTON_PRIMARY) != 0)
802 return 1;
803
804 if ((notIn & MotionEvent.BUTTON_SECONDARY) != 0)
805 return 3;
806
807 if ((notIn & MotionEvent.BUTTON_TERTIARY) != 0)
808 return 2;
809
810
811
812
813 if ((notIn & MotionEvent.BUTTON_BACK) != 0)
814 return 8;
815
816 if ((notIn & MotionEvent.BUTTON_FORWARD) != 0)
817 return 9;
818
819
820
821 if ((notIn & MotionEvent.BUTTON_STYLUS_PRIMARY) != 0)
822 return 0;
823
824 if ((notIn & MotionEvent.BUTTON_STYLUS_SECONDARY) != 0)
825 return 0;
826
827
828 return 11;
829 }
830
831
832
833
834
835
836
837 private int
838 buttonForEvent (MotionEvent event)
839 {
840
841
842
843 if (Build.VERSION.SDK_INT
844 < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
845 return 0;
846
847 return whatButtonWasIt (event, true);
848 }
849
850
851
852
853 private Coordinate
854 figureChange (MotionEvent event)
855 {
856 int i, truncatedX, truncatedY, pointerIndex, pointerID, count;
857 Coordinate coordinate;
858
859
860 coordinate = null;
861
862 switch (event.getActionMasked ())
863 {
864 case MotionEvent.ACTION_DOWN:
865
866
867 pointerID = event.getPointerId (0);
868 coordinate = new Coordinate ((int) event.getX (0),
869 (int) event.getY (0),
870 buttonForEvent (event),
871 pointerID);
872 pointerMap.put (pointerID, coordinate);
873 break;
874
875 case MotionEvent.ACTION_UP:
876 case MotionEvent.ACTION_CANCEL:
877
878 pointerID = event.getPointerId (0);
879 coordinate = pointerMap.remove (pointerID);
880 break;
881
882 case MotionEvent.ACTION_POINTER_DOWN:
883
884
885 pointerIndex = event.getActionIndex ();
886 pointerID = event.getPointerId (pointerIndex);
887 coordinate = new Coordinate ((int) event.getX (0),
888 (int) event.getY (0),
889 buttonForEvent (event),
890 pointerID);
891 pointerMap.put (pointerID, coordinate);
892 break;
893
894 case MotionEvent.ACTION_POINTER_UP:
895
896 pointerIndex = event.getActionIndex ();
897 pointerID = event.getPointerId (pointerIndex);
898 coordinate = pointerMap.remove (pointerID);
899 break;
900
901 default:
902
903
904
905 count = event.getPointerCount ();
906 for (i = 0; i < count; ++i)
907 {
908 pointerID = event.getPointerId (i);
909
910
911 coordinate = pointerMap.get (pointerID);
912
913 if (coordinate != null)
914 {
915
916 truncatedX = (int) event.getX (i);
917 truncatedY = (int) event.getY (i);
918
919 if (truncatedX != coordinate.x
920 || truncatedY != coordinate.y)
921 {
922
923
924 coordinate.x = truncatedX;
925 coordinate.y = truncatedY;
926
927 break;
928 }
929 }
930 }
931
932
933
934
935 if (i == count)
936 coordinate = null;
937 }
938
939
940 return coordinate;
941 }
942
943
944
945
946
947 private int
948 motionEventModifiers (MotionEvent event)
949 {
950 int state;
951
952 state = event.getMetaState ();
953
954
955
956
957 if ((state & KeyEvent.META_ALT_LEFT_ON) != 0
958 || (state & KeyEvent.META_ALT_RIGHT_ON) != 0)
959 state |= KeyEvent.META_ALT_MASK;
960
961 if ((state & KeyEvent.META_CTRL_LEFT_ON) != 0
962 || (state & KeyEvent.META_CTRL_RIGHT_ON) != 0)
963 state |= KeyEvent.META_CTRL_MASK;
964
965 return state;
966 }
967
968
969
970
971
972
973
974 private void
975 motionEvent (MotionEvent event)
976 {
977 Coordinate coordinate;
978 int modifiers;
979 long time;
980
981
982
983
984
985 coordinate = figureChange (event);
986
987 if (coordinate == null)
988 return;
989
990 time = event.getEventTime ();
991
992 if (coordinate.button != 0)
993 {
994
995
996
997 modifiers = motionEventModifiers (event);
998
999 switch (event.getAction ())
1000 {
1001 case MotionEvent.ACTION_POINTER_DOWN:
1002 case MotionEvent.ACTION_DOWN:
1003 EmacsNative.sendButtonPress (this.handle, coordinate.x,
1004 coordinate.y, time, modifiers,
1005 coordinate.button);
1006 break;
1007
1008 case MotionEvent.ACTION_POINTER_UP:
1009 case MotionEvent.ACTION_UP:
1010 case MotionEvent.ACTION_CANCEL:
1011 EmacsNative.sendButtonRelease (this.handle, coordinate.x,
1012 coordinate.y, time, modifiers,
1013 coordinate.button);
1014 break;
1015
1016 case MotionEvent.ACTION_MOVE:
1017 EmacsNative.sendMotionNotify (this.handle, coordinate.x,
1018 coordinate.y, time);
1019 break;
1020 }
1021 }
1022 else
1023 {
1024
1025
1026
1027 switch (event.getActionMasked ())
1028 {
1029 case MotionEvent.ACTION_DOWN:
1030 case MotionEvent.ACTION_POINTER_DOWN:
1031
1032 EmacsNative.sendTouchDown (this.handle, coordinate.x,
1033 coordinate.y, time,
1034 coordinate.id, 0);
1035 break;
1036
1037 case MotionEvent.ACTION_UP:
1038 case MotionEvent.ACTION_POINTER_UP:
1039
1040 EmacsNative.sendTouchUp (this.handle, coordinate.x,
1041 coordinate.y, time,
1042 coordinate.id, 0);
1043 break;
1044
1045 case MotionEvent.ACTION_CANCEL:
1046
1047 EmacsNative.sendTouchUp (this.handle, coordinate.x,
1048 coordinate.y, time,
1049 coordinate.id,
1050 1 );
1051 break;
1052
1053 case MotionEvent.ACTION_MOVE:
1054
1055 EmacsNative.sendTouchMove (this.handle, coordinate.x,
1056 coordinate.y, time,
1057 coordinate.id, 0);
1058 break;
1059 }
1060 }
1061
1062 if (Build.VERSION.SDK_INT
1063 < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
1064 return;
1065
1066
1067 lastButtonState = event.getButtonState ();
1068 return;
1069 }
1070
1071 public boolean
1072 onTouchEvent (MotionEvent event)
1073 {
1074 switch (event.getActionMasked ())
1075 {
1076 case MotionEvent.ACTION_DOWN:
1077 case MotionEvent.ACTION_POINTER_DOWN:
1078 case MotionEvent.ACTION_UP:
1079 case MotionEvent.ACTION_POINTER_UP:
1080 case MotionEvent.ACTION_CANCEL:
1081 case MotionEvent.ACTION_MOVE:
1082 motionEvent (event);
1083 return true;
1084 }
1085
1086 return false;
1087 }
1088
1089 public boolean
1090 onGenericMotionEvent (MotionEvent event)
1091 {
1092 switch (event.getAction ())
1093 {
1094 case MotionEvent.ACTION_HOVER_ENTER:
1095 EmacsNative.sendEnterNotify (this.handle, (int) event.getX (),
1096 (int) event.getY (),
1097 event.getEventTime ());
1098 return true;
1099
1100 case MotionEvent.ACTION_HOVER_MOVE:
1101 EmacsNative.sendMotionNotify (this.handle, (int) event.getX (),
1102 (int) event.getY (),
1103 event.getEventTime ());
1104 return true;
1105
1106 case MotionEvent.ACTION_HOVER_EXIT:
1107
1108
1109
1110
1111
1112
1113 if ((event.getButtonState () & ~lastButtonState) == 0)
1114 EmacsNative.sendLeaveNotify (this.handle, (int) event.getX (),
1115 (int) event.getY (),
1116 event.getEventTime ());
1117
1118 return true;
1119
1120 case MotionEvent.ACTION_DOWN:
1121 case MotionEvent.ACTION_POINTER_DOWN:
1122 case MotionEvent.ACTION_UP:
1123 case MotionEvent.ACTION_POINTER_UP:
1124 case MotionEvent.ACTION_CANCEL:
1125 case MotionEvent.ACTION_MOVE:
1126
1127
1128
1129 motionEvent (event);
1130 return true;
1131
1132 case MotionEvent.ACTION_SCROLL:
1133
1134 EmacsNative.sendWheel (this.handle, (int) event.getX (),
1135 (int) event.getY (),
1136 event.getEventTime (),
1137 motionEventModifiers (event),
1138 event.getAxisValue (MotionEvent.AXIS_HSCROLL),
1139 event.getAxisValue (MotionEvent.AXIS_VSCROLL));
1140 return true;
1141 }
1142
1143 return false;
1144 }
1145
1146
1147
1148 public synchronized void
1149 reparentTo (final EmacsWindow otherWindow, int x, int y)
1150 {
1151 int width, height;
1152
1153
1154
1155 if (parent != null)
1156 parent.children.remove (this);
1157
1158 if (otherWindow != null)
1159 otherWindow.children.add (this);
1160
1161 parent = otherWindow;
1162
1163
1164 width = rect.width ();
1165 height = rect.height ();
1166 rect.left = x;
1167 rect.top = y;
1168 rect.right = x + width;
1169 rect.bottom = y + height;
1170
1171
1172
1173 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1174 @Override
1175 public void
1176 run ()
1177 {
1178 EmacsWindowAttachmentManager manager;
1179 ViewManager parent;
1180
1181
1182 manager = EmacsWindowAttachmentManager.MANAGER;
1183 manager.detachWindow (EmacsWindow.this);
1184
1185
1186
1187
1188 if (windowManager != null)
1189 parent = windowManager;
1190 else
1191 parent = (ViewManager) view.getParent ();
1192 windowManager = null;
1193
1194 if (parent != null)
1195 parent.removeView (view);
1196
1197
1198
1199 if (otherWindow != null)
1200 otherWindow.view.addView (view);
1201 else if (EmacsWindow.this.isMapped)
1202 manager.registerWindow (EmacsWindow.this);
1203
1204
1205 view.requestLayout ();
1206 }
1207 });
1208 }
1209
1210 public void
1211 makeInputFocus (long time)
1212 {
1213
1214
1215 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1216 @Override
1217 public void
1218 run ()
1219 {
1220 view.requestFocus ();
1221 }
1222 });
1223 }
1224
1225 public synchronized void
1226 raise ()
1227 {
1228
1229 if (parent == null)
1230 return;
1231
1232
1233 parent.children.remove (this);
1234 parent.children.add (this);
1235
1236
1237 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1238 @Override
1239 public void
1240 run ()
1241 {
1242 view.raise ();
1243 }
1244 });
1245 }
1246
1247 public synchronized void
1248 lower ()
1249 {
1250
1251 if (parent == null)
1252 return;
1253
1254
1255 parent.children.remove (this);
1256 parent.children.add (this);
1257
1258
1259 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1260 @Override
1261 public void
1262 run ()
1263 {
1264 view.lower ();
1265 }
1266 });
1267 }
1268
1269 public synchronized int[]
1270 getWindowGeometry ()
1271 {
1272 int[] array;
1273
1274 array = new int[4];
1275
1276 array[0] = parent != null ? rect.left : xPosition;
1277 array[1] = parent != null ? rect.top : yPosition;
1278 array[2] = rect.width ();
1279 array[3] = rect.height ();
1280
1281 return array;
1282 }
1283
1284 public void
1285 noticeIconified ()
1286 {
1287 EmacsNative.sendIconified (this.handle);
1288 }
1289
1290 public void
1291 noticeDeiconified ()
1292 {
1293 EmacsNative.sendDeiconified (this.handle);
1294 }
1295
1296 public synchronized void
1297 setDontAcceptFocus (final boolean dontAcceptFocus)
1298 {
1299
1300 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1301 @Override
1302 public void
1303 run ()
1304 {
1305 view.setFocusable (!dontAcceptFocus);
1306 view.setFocusableInTouchMode (!dontAcceptFocus);
1307 }
1308 });
1309 }
1310
1311 public synchronized void
1312 setDontFocusOnMap (final boolean dontFocusOnMap)
1313 {
1314 this.dontFocusOnMap = dontFocusOnMap;
1315 }
1316
1317 public synchronized boolean
1318 getDontFocusOnMap ()
1319 {
1320 return dontFocusOnMap;
1321 }
1322
1323 public int[]
1324 translateCoordinates (int x, int y)
1325 {
1326 int[] array;
1327
1328
1329
1330 array = new int[2];
1331 EmacsService.SERVICE.getLocationOnScreen (view, array);
1332
1333
1334
1335 array[0] += x;
1336 array[1] += y;
1337
1338
1339 return array;
1340 }
1341
1342 public void
1343 toggleOnScreenKeyboard (final boolean on)
1344 {
1345
1346
1347
1348
1349
1350
1351 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1352 @Override
1353 public void
1354 run ()
1355 {
1356 if (on)
1357 view.showOnScreenKeyboard ();
1358 else
1359 view.hideOnScreenKeyboard ();
1360 }
1361 });
1362 }
1363
1364 public String
1365 lookupString (int eventSerial)
1366 {
1367 String any;
1368
1369 synchronized (eventStrings)
1370 {
1371 any = eventStrings.remove (eventSerial);
1372 }
1373
1374 return any;
1375 }
1376
1377 public void
1378 setFullscreen (final boolean isFullscreen)
1379 {
1380 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1381 @Override
1382 public void
1383 run ()
1384 {
1385 EmacsActivity activity;
1386 Object tem;
1387
1388 fullscreen = isFullscreen;
1389 tem = getAttachedConsumer ();
1390
1391 if (tem != null)
1392 {
1393 activity = (EmacsActivity) tem;
1394 activity.syncFullscreenWith (EmacsWindow.this);
1395 }
1396 }
1397 });
1398 }
1399
1400 public void
1401 defineCursor (final EmacsCursor cursor)
1402 {
1403
1404
1405 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
1406 view.post (new Runnable () {
1407 @Override
1408 public void
1409 run ()
1410 {
1411 if (cursor != null)
1412 view.setPointerIcon (cursor.icon);
1413 else
1414 view.setPointerIcon (null);
1415 }
1416 });
1417 }
1418
1419 public synchronized void
1420 notifyContentRectPosition (int xPosition, int yPosition)
1421 {
1422 Rect geometry;
1423
1424
1425
1426 if (parent != null)
1427 return;
1428
1429
1430
1431
1432
1433 if (this.xPosition != xPosition
1434 || this.yPosition != yPosition)
1435 {
1436 this.xPosition = xPosition;
1437 this.yPosition = yPosition;
1438
1439 EmacsNative.sendConfigureNotify (this.handle,
1440 System.currentTimeMillis (),
1441 xPosition, yPosition,
1442 rect.width (), rect.height ());
1443 }
1444 }
1445 };