diff options
Diffstat (limited to 'src/androidterm.c')
| -rw-r--r-- | src/androidterm.c | 443 |
1 files changed, 435 insertions, 8 deletions
diff --git a/src/androidterm.c b/src/androidterm.c index 0279da4f58d..05fe7f01bf9 100644 --- a/src/androidterm.c +++ b/src/androidterm.c | |||
| @@ -41,6 +41,11 @@ struct android_display_info *x_display_list; | |||
| 41 | 41 | ||
| 42 | #include <android/log.h> | 42 | #include <android/log.h> |
| 43 | 43 | ||
| 44 | /* Non-zero means that a HELP_EVENT has been generated since Emacs | ||
| 45 | start. */ | ||
| 46 | |||
| 47 | static bool any_help_event_p; | ||
| 48 | |||
| 44 | enum | 49 | enum |
| 45 | { | 50 | { |
| 46 | ANDROID_EVENT_NORMAL, | 51 | ANDROID_EVENT_NORMAL, |
| @@ -261,6 +266,94 @@ android_detect_focus_change (struct android_display_info *dpyinfo, | |||
| 261 | } | 266 | } |
| 262 | } | 267 | } |
| 263 | 268 | ||
| 269 | static bool | ||
| 270 | android_note_mouse_movement (struct frame *frame, | ||
| 271 | struct android_motion_event *event) | ||
| 272 | { | ||
| 273 | struct android_display_info *dpyinfo; | ||
| 274 | Emacs_Rectangle *r; | ||
| 275 | |||
| 276 | if (!FRAME_ANDROID_OUTPUT (frame)) | ||
| 277 | return false; | ||
| 278 | |||
| 279 | dpyinfo = FRAME_DISPLAY_INFO (frame); | ||
| 280 | dpyinfo->last_mouse_motion_frame = frame; | ||
| 281 | dpyinfo->last_mouse_motion_x = event->x; | ||
| 282 | dpyinfo->last_mouse_motion_y = event->y; | ||
| 283 | dpyinfo->last_mouse_movement_time = event->time; | ||
| 284 | |||
| 285 | /* Has the mouse moved off the glyph it was on at the last sighting? */ | ||
| 286 | r = &dpyinfo->last_mouse_glyph; | ||
| 287 | if (frame != dpyinfo->last_mouse_glyph_frame | ||
| 288 | || event->x < r->x || event->x >= r->x + r->width | ||
| 289 | || event->y < r->y || event->y >= r->y + r->height) | ||
| 290 | { | ||
| 291 | frame->mouse_moved = true; | ||
| 292 | /* TODO | ||
| 293 | dpyinfo->last_mouse_scroll_bar = NULL; */ | ||
| 294 | note_mouse_highlight (frame, event->x, event->y); | ||
| 295 | /* Remember which glyph we're now on. */ | ||
| 296 | remember_mouse_glyph (frame, event->x, event->y, r); | ||
| 297 | dpyinfo->last_mouse_glyph_frame = frame; | ||
| 298 | return true; | ||
| 299 | } | ||
| 300 | |||
| 301 | return false; | ||
| 302 | } | ||
| 303 | |||
| 304 | static struct frame * | ||
| 305 | mouse_or_wdesc_frame (struct android_display_info *dpyinfo, int wdesc) | ||
| 306 | { | ||
| 307 | struct frame *lm_f = (gui_mouse_grabbed (dpyinfo) | ||
| 308 | ? dpyinfo->last_mouse_frame | ||
| 309 | : NULL); | ||
| 310 | |||
| 311 | if (lm_f && !EQ (track_mouse, Qdropping) | ||
| 312 | && !EQ (track_mouse, Qdrag_source)) | ||
| 313 | return lm_f; | ||
| 314 | else | ||
| 315 | { | ||
| 316 | struct frame *w_f = android_window_to_frame (dpyinfo, wdesc); | ||
| 317 | |||
| 318 | /* Do not return a tooltip frame. */ | ||
| 319 | if (!w_f || FRAME_TOOLTIP_P (w_f)) | ||
| 320 | return EQ (track_mouse, Qdropping) ? lm_f : NULL; | ||
| 321 | else | ||
| 322 | /* When dropping it would be probably nice to raise w_f | ||
| 323 | here. */ | ||
| 324 | return w_f; | ||
| 325 | } | ||
| 326 | } | ||
| 327 | |||
| 328 | static Lisp_Object | ||
| 329 | android_construct_mouse_click (struct input_event *result, | ||
| 330 | struct android_button_event *event, | ||
| 331 | struct frame *f) | ||
| 332 | { | ||
| 333 | struct android_display_info *dpyinfo; | ||
| 334 | int x, y; | ||
| 335 | |||
| 336 | dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 337 | x = event->x; | ||
| 338 | y = event->y; | ||
| 339 | |||
| 340 | /* Make the event type NO_EVENT; we'll change that when we decide | ||
| 341 | otherwise. */ | ||
| 342 | result->kind = MOUSE_CLICK_EVENT; | ||
| 343 | result->code = event->button - 1; | ||
| 344 | result->timestamp = event->time; | ||
| 345 | result->modifiers = (android_android_to_emacs_modifiers (dpyinfo, | ||
| 346 | event->state) | ||
| 347 | | (event->type == ANDROID_BUTTON_RELEASE | ||
| 348 | ? up_modifier : down_modifier)); | ||
| 349 | |||
| 350 | XSETINT (result->x, x); | ||
| 351 | XSETINT (result->y, y); | ||
| 352 | XSETFRAME (result->frame_or_window, f); | ||
| 353 | result->arg = Qnil; | ||
| 354 | return Qnil; | ||
| 355 | } | ||
| 356 | |||
| 264 | static int | 357 | static int |
| 265 | handle_one_android_event (struct android_display_info *dpyinfo, | 358 | handle_one_android_event (struct android_display_info *dpyinfo, |
| 266 | union android_event *event, int *finish, | 359 | union android_event *event, int *finish, |
| @@ -270,17 +363,20 @@ handle_one_android_event (struct android_display_info *dpyinfo, | |||
| 270 | struct frame *f, *any, *mouse_frame; | 363 | struct frame *f, *any, *mouse_frame; |
| 271 | Mouse_HLInfo *hlinfo; | 364 | Mouse_HLInfo *hlinfo; |
| 272 | union buffered_input_event inev; | 365 | union buffered_input_event inev; |
| 273 | int modifiers, count; | 366 | int modifiers, count, do_help; |
| 274 | 367 | ||
| 275 | /* It is okay for this to not resemble handle_one_xevent so much. | 368 | /* It is okay for this to not resemble handle_one_xevent so much. |
| 276 | Differences in event handling code are much less nasty than | 369 | Differences in event handling code are much less nasty than |
| 277 | stuble differences in the graphics code. */ | 370 | stuble differences in the graphics code. */ |
| 278 | 371 | ||
| 279 | count = 0; | 372 | do_help = count = 0; |
| 280 | hlinfo = &dpyinfo->mouse_highlight; | 373 | hlinfo = &dpyinfo->mouse_highlight; |
| 281 | *finish = ANDROID_EVENT_NORMAL; | 374 | *finish = ANDROID_EVENT_NORMAL; |
| 282 | any = android_window_to_frame (dpyinfo, event->xany.window); | 375 | any = android_window_to_frame (dpyinfo, event->xany.window); |
| 283 | 376 | ||
| 377 | if (any && any->wait_event_type == event->type) | ||
| 378 | any->wait_event_type = 0; /* Indicates we got it. */ | ||
| 379 | |||
| 284 | EVENT_INIT (inev.ie); | 380 | EVENT_INIT (inev.ie); |
| 285 | 381 | ||
| 286 | switch (event->type) | 382 | switch (event->type) |
| @@ -410,6 +506,213 @@ handle_one_android_event (struct android_display_info *dpyinfo, | |||
| 410 | /* A new frame must be created. */; | 506 | /* A new frame must be created. */; |
| 411 | } | 507 | } |
| 412 | 508 | ||
| 509 | case ANDROID_ENTER_NOTIFY: | ||
| 510 | f = any; | ||
| 511 | |||
| 512 | if (f) | ||
| 513 | android_note_mouse_movement (f, &event->xmotion); | ||
| 514 | goto OTHER; | ||
| 515 | |||
| 516 | case ANDROID_MOTION_NOTIFY: | ||
| 517 | f = any; | ||
| 518 | |||
| 519 | if (f) | ||
| 520 | { | ||
| 521 | /* Maybe generate a SELECT_WINDOW_EVENT for | ||
| 522 | `mouse-autoselect-window' but don't let popup menus | ||
| 523 | interfere with this (Bug#1261). */ | ||
| 524 | if (!NILP (Vmouse_autoselect_window) | ||
| 525 | && !popup_activated () | ||
| 526 | /* Don't switch if we're currently in the minibuffer. | ||
| 527 | This tries to work around problems where the | ||
| 528 | minibuffer gets unselected unexpectedly, and where | ||
| 529 | you then have to move your mouse all the way down to | ||
| 530 | the minibuffer to select it. */ | ||
| 531 | && !MINI_WINDOW_P (XWINDOW (selected_window)) | ||
| 532 | /* With `focus-follows-mouse' non-nil create an event | ||
| 533 | also when the target window is on another frame. */ | ||
| 534 | && (f == XFRAME (selected_frame) | ||
| 535 | || !NILP (focus_follows_mouse))) | ||
| 536 | { | ||
| 537 | static Lisp_Object last_mouse_window; | ||
| 538 | Lisp_Object window | ||
| 539 | = window_from_coordinates (f, event->xmotion.x, | ||
| 540 | event->xmotion.y, 0, | ||
| 541 | false, false); | ||
| 542 | |||
| 543 | /* A window will be autoselected only when it is not | ||
| 544 | selected now and the last mouse movement event was | ||
| 545 | not in it. The remainder of the code is a bit vague | ||
| 546 | wrt what a "window" is. For immediate autoselection, | ||
| 547 | the window is usually the entire window but for GTK | ||
| 548 | where the scroll bars don't count. For delayed | ||
| 549 | autoselection the window is usually the window's text | ||
| 550 | area including the margins. */ | ||
| 551 | if (WINDOWP (window) | ||
| 552 | && !EQ (window, last_mouse_window) | ||
| 553 | && !EQ (window, selected_window)) | ||
| 554 | { | ||
| 555 | inev.ie.kind = SELECT_WINDOW_EVENT; | ||
| 556 | inev.ie.frame_or_window = window; | ||
| 557 | } | ||
| 558 | |||
| 559 | /* Remember the last window where we saw the mouse. */ | ||
| 560 | last_mouse_window = window; | ||
| 561 | } | ||
| 562 | |||
| 563 | if (!android_note_mouse_movement (f, &event->xmotion)) | ||
| 564 | help_echo_string = previous_help_echo_string; | ||
| 565 | } | ||
| 566 | |||
| 567 | /* If the contents of the global variable help_echo_string | ||
| 568 | has changed, generate a HELP_EVENT. */ | ||
| 569 | if (!NILP (help_echo_string) | ||
| 570 | || !NILP (previous_help_echo_string)) | ||
| 571 | do_help = 1; | ||
| 572 | |||
| 573 | if (f) | ||
| 574 | android_flush_dirty_back_buffer_on (f); | ||
| 575 | |||
| 576 | goto OTHER; | ||
| 577 | |||
| 578 | case ANDROID_LEAVE_NOTIFY: | ||
| 579 | f = any; | ||
| 580 | |||
| 581 | if (f) | ||
| 582 | { | ||
| 583 | /* Now clear dpyinfo->last_mouse_motion_frame, or | ||
| 584 | gui_redo_mouse_highlight will end up highlighting the | ||
| 585 | last known position of the mouse if a tooltip frame is | ||
| 586 | later unmapped. */ | ||
| 587 | |||
| 588 | if (f == dpyinfo->last_mouse_motion_frame) | ||
| 589 | dpyinfo->last_mouse_motion_frame = NULL; | ||
| 590 | |||
| 591 | /* Something similar applies to | ||
| 592 | dpyinfo->last_mouse_glyph_frame. */ | ||
| 593 | if (f == dpyinfo->last_mouse_glyph_frame) | ||
| 594 | dpyinfo->last_mouse_glyph_frame = NULL; | ||
| 595 | |||
| 596 | if (f == hlinfo->mouse_face_mouse_frame) | ||
| 597 | { | ||
| 598 | /* If we move outside the frame, then we're | ||
| 599 | certainly no longer on any text in the frame. */ | ||
| 600 | clear_mouse_face (hlinfo); | ||
| 601 | hlinfo->mouse_face_mouse_frame = 0; | ||
| 602 | android_flush_dirty_back_buffer_on (f); | ||
| 603 | } | ||
| 604 | |||
| 605 | /* Generate a nil HELP_EVENT to cancel a help-echo. | ||
| 606 | Do it only if there's something to cancel. | ||
| 607 | Otherwise, the startup message is cleared when | ||
| 608 | the mouse leaves the frame. */ | ||
| 609 | if (any_help_event_p | ||
| 610 | /* But never if `mouse-drag-and-drop-region' is in | ||
| 611 | progress, since that results in the tooltip being | ||
| 612 | dismissed when the mouse moves on top. */ | ||
| 613 | && !((EQ (track_mouse, Qdrag_source) | ||
| 614 | || EQ (track_mouse, Qdropping)) | ||
| 615 | && gui_mouse_grabbed (dpyinfo))) | ||
| 616 | do_help = -1; | ||
| 617 | } | ||
| 618 | |||
| 619 | goto OTHER; | ||
| 620 | |||
| 621 | case ANDROID_BUTTON_PRESS: | ||
| 622 | case ANDROID_BUTTON_RELEASE: | ||
| 623 | /* If we decide we want to generate an event to be seen | ||
| 624 | by the rest of Emacs, we put it here. */ | ||
| 625 | |||
| 626 | f = any; | ||
| 627 | |||
| 628 | Lisp_Object tab_bar_arg = Qnil; | ||
| 629 | bool tab_bar_p = false; | ||
| 630 | bool tool_bar_p = false; | ||
| 631 | |||
| 632 | dpyinfo->last_mouse_glyph_frame = NULL; | ||
| 633 | |||
| 634 | f = mouse_or_wdesc_frame (dpyinfo, event->xbutton.window); | ||
| 635 | |||
| 636 | if (f) | ||
| 637 | { | ||
| 638 | /* Is this in the tab-bar? */ | ||
| 639 | if (WINDOWP (f->tab_bar_window) | ||
| 640 | && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window))) | ||
| 641 | { | ||
| 642 | Lisp_Object window; | ||
| 643 | int x = event->xbutton.x; | ||
| 644 | int y = event->xbutton.y; | ||
| 645 | |||
| 646 | window = window_from_coordinates (f, x, y, 0, true, true); | ||
| 647 | tab_bar_p = EQ (window, f->tab_bar_window); | ||
| 648 | |||
| 649 | if (tab_bar_p) | ||
| 650 | { | ||
| 651 | tab_bar_arg = handle_tab_bar_click | ||
| 652 | (f, x, y, (event->xbutton.type | ||
| 653 | == ANDROID_BUTTON_PRESS), | ||
| 654 | android_android_to_emacs_modifiers (dpyinfo, | ||
| 655 | event->xbutton.state)); | ||
| 656 | android_flush_dirty_back_buffer_on (f); | ||
| 657 | } | ||
| 658 | } | ||
| 659 | |||
| 660 | /* Is this in the tool-bar? */ | ||
| 661 | if (WINDOWP (f->tool_bar_window) | ||
| 662 | && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window))) | ||
| 663 | { | ||
| 664 | Lisp_Object window; | ||
| 665 | int x = event->xbutton.x; | ||
| 666 | int y = event->xbutton.y; | ||
| 667 | |||
| 668 | window = window_from_coordinates (f, x, y, 0, true, true); | ||
| 669 | tool_bar_p = (EQ (window, f->tool_bar_window) | ||
| 670 | && ((event->xbutton.type | ||
| 671 | != ANDROID_BUTTON_RELEASE) | ||
| 672 | || f->last_tool_bar_item != -1)); | ||
| 673 | |||
| 674 | if (tool_bar_p && event->xbutton.button < 4) | ||
| 675 | { | ||
| 676 | handle_tool_bar_click | ||
| 677 | (f, x, y, (event->xbutton.type | ||
| 678 | == ANDROID_BUTTON_PRESS), | ||
| 679 | android_android_to_emacs_modifiers (dpyinfo, | ||
| 680 | event->xbutton.state)); | ||
| 681 | android_flush_dirty_back_buffer_on (f); | ||
| 682 | } | ||
| 683 | } | ||
| 684 | |||
| 685 | if (!(tab_bar_p && NILP (tab_bar_arg)) && !tool_bar_p) | ||
| 686 | { | ||
| 687 | android_construct_mouse_click (&inev.ie, &event->xbutton, f); | ||
| 688 | |||
| 689 | if (!NILP (tab_bar_arg)) | ||
| 690 | inev.ie.arg = tab_bar_arg; | ||
| 691 | } | ||
| 692 | } | ||
| 693 | else | ||
| 694 | { | ||
| 695 | /* TODO: scroll bars */ | ||
| 696 | } | ||
| 697 | |||
| 698 | if (event->type == ANDROID_BUTTON_PRESS) | ||
| 699 | { | ||
| 700 | dpyinfo->grabbed |= (1 << event->xbutton.button); | ||
| 701 | dpyinfo->last_mouse_frame = f; | ||
| 702 | if (f && !tab_bar_p) | ||
| 703 | f->last_tab_bar_item = -1; | ||
| 704 | if (f && !tool_bar_p) | ||
| 705 | f->last_tool_bar_item = -1; | ||
| 706 | } | ||
| 707 | else | ||
| 708 | dpyinfo->grabbed &= ~(1 << event->xbutton.button); | ||
| 709 | |||
| 710 | /* Ignore any mouse motion that happened before this event; | ||
| 711 | any subsequent mouse-movement Emacs events should reflect | ||
| 712 | only motion after the ButtonPress/Release. */ | ||
| 713 | if (f != 0) | ||
| 714 | f->mouse_moved = false; | ||
| 715 | |||
| 413 | goto OTHER; | 716 | goto OTHER; |
| 414 | 717 | ||
| 415 | default: | 718 | default: |
| @@ -423,6 +726,30 @@ handle_one_android_event (struct android_display_info *dpyinfo, | |||
| 423 | count++; | 726 | count++; |
| 424 | } | 727 | } |
| 425 | 728 | ||
| 729 | if (do_help | ||
| 730 | && !(hold_quit && hold_quit->kind != NO_EVENT)) | ||
| 731 | { | ||
| 732 | Lisp_Object frame; | ||
| 733 | |||
| 734 | if (f) | ||
| 735 | XSETFRAME (frame, f); | ||
| 736 | else | ||
| 737 | frame = Qnil; | ||
| 738 | |||
| 739 | if (do_help > 0) | ||
| 740 | { | ||
| 741 | any_help_event_p = true; | ||
| 742 | gen_help_event (help_echo_string, frame, help_echo_window, | ||
| 743 | help_echo_object, help_echo_pos); | ||
| 744 | } | ||
| 745 | else | ||
| 746 | { | ||
| 747 | help_echo_string = Qnil; | ||
| 748 | gen_help_event (Qnil, frame, Qnil, Qnil, 0); | ||
| 749 | } | ||
| 750 | count++; | ||
| 751 | } | ||
| 752 | |||
| 426 | return count; | 753 | return count; |
| 427 | } | 754 | } |
| 428 | 755 | ||
| @@ -562,7 +889,32 @@ android_mouse_position (struct frame **fp, int insist, | |||
| 562 | enum scroll_bar_part *part, Lisp_Object *x, | 889 | enum scroll_bar_part *part, Lisp_Object *x, |
| 563 | Lisp_Object *y, Time *timestamp) | 890 | Lisp_Object *y, Time *timestamp) |
| 564 | { | 891 | { |
| 565 | /* TODO */ | 892 | Lisp_Object tail, frame; |
| 893 | struct android_display_info *dpyinfo; | ||
| 894 | |||
| 895 | dpyinfo = FRAME_DISPLAY_INFO (*fp); | ||
| 896 | |||
| 897 | /* This is the best implementation possible on Android, where the | ||
| 898 | system doesn't let Emacs obtain any information about the mouse | ||
| 899 | pointer at all. */ | ||
| 900 | |||
| 901 | if (dpyinfo->last_mouse_motion_frame) | ||
| 902 | { | ||
| 903 | *fp = dpyinfo->last_mouse_motion_frame; | ||
| 904 | *timestamp = dpyinfo->last_mouse_movement_time; | ||
| 905 | *x = make_fixnum (dpyinfo->last_mouse_motion_x); | ||
| 906 | *y = make_fixnum (dpyinfo->last_mouse_motion_y); | ||
| 907 | *bar_window = Qnil; | ||
| 908 | *part = scroll_bar_nowhere; | ||
| 909 | |||
| 910 | FOR_EACH_FRAME (tail, frame) | ||
| 911 | { | ||
| 912 | if (FRAME_ANDROID_P (XFRAME (frame))) | ||
| 913 | XFRAME (frame)->mouse_moved = false; | ||
| 914 | } | ||
| 915 | |||
| 916 | dpyinfo->last_mouse_motion_frame->mouse_moved = false; | ||
| 917 | } | ||
| 566 | } | 918 | } |
| 567 | 919 | ||
| 568 | static Lisp_Object | 920 | static Lisp_Object |
| @@ -679,6 +1031,45 @@ android_iconify_frame (struct frame *f) | |||
| 679 | } | 1031 | } |
| 680 | 1032 | ||
| 681 | static void | 1033 | static void |
| 1034 | android_wait_for_event (struct frame *f, int eventtype) | ||
| 1035 | { | ||
| 1036 | if (!FLOATP (Vandroid_wait_for_event_timeout)) | ||
| 1037 | return; | ||
| 1038 | |||
| 1039 | int level = interrupt_input_blocked; | ||
| 1040 | struct timespec tmo, tmo_at, time_now; | ||
| 1041 | |||
| 1042 | f->wait_event_type = eventtype; | ||
| 1043 | |||
| 1044 | /* Default timeout is 0.1 second. Hopefully not noticeable. */ | ||
| 1045 | double timeout = XFLOAT_DATA (Vandroid_wait_for_event_timeout); | ||
| 1046 | time_t timeout_seconds = (time_t) timeout; | ||
| 1047 | tmo = make_timespec (timeout_seconds, | ||
| 1048 | (long int) ((timeout - timeout_seconds) | ||
| 1049 | * 1000 * 1000 * 1000)); | ||
| 1050 | tmo_at = timespec_add (current_timespec (), tmo); | ||
| 1051 | |||
| 1052 | while (f->wait_event_type) | ||
| 1053 | { | ||
| 1054 | pending_signals = true; | ||
| 1055 | totally_unblock_input (); | ||
| 1056 | /* XTread_socket is called after unblock. */ | ||
| 1057 | block_input (); | ||
| 1058 | interrupt_input_blocked = level; | ||
| 1059 | |||
| 1060 | time_now = current_timespec (); | ||
| 1061 | if (timespec_cmp (tmo_at, time_now) < 0) | ||
| 1062 | break; | ||
| 1063 | |||
| 1064 | tmo = timespec_sub (tmo_at, time_now); | ||
| 1065 | if (android_select (0, NULL, NULL, NULL, &tmo, NULL) == 0) | ||
| 1066 | break; /* Timeout */ | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | f->wait_event_type = 0; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static void | ||
| 682 | android_set_window_size_1 (struct frame *f, bool change_gravity, | 1073 | android_set_window_size_1 (struct frame *f, bool change_gravity, |
| 683 | int width, int height) | 1074 | int width, int height) |
| 684 | { | 1075 | { |
| @@ -688,11 +1079,29 @@ android_set_window_size_1 (struct frame *f, bool change_gravity, | |||
| 688 | android_resize_window (FRAME_ANDROID_WINDOW (f), width, | 1079 | android_resize_window (FRAME_ANDROID_WINDOW (f), width, |
| 689 | height); | 1080 | height); |
| 690 | 1081 | ||
| 691 | /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to | ||
| 692 | receive in the ConfigureNotify event; if we get what we asked | ||
| 693 | for, then the event won't cause the screen to become garbaged, so | ||
| 694 | we have to make sure to do it here. */ | ||
| 695 | SET_FRAME_GARBAGED (f); | 1082 | SET_FRAME_GARBAGED (f); |
| 1083 | |||
| 1084 | if (FRAME_VISIBLE_P (f)) | ||
| 1085 | { | ||
| 1086 | android_wait_for_event (f, ANDROID_CONFIGURE_NOTIFY); | ||
| 1087 | |||
| 1088 | if (CONSP (frame_size_history)) | ||
| 1089 | frame_size_history_extra (f, build_string ("set_window_size_1 visible"), | ||
| 1090 | FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), | ||
| 1091 | width, height, f->new_width, f->new_height); | ||
| 1092 | } | ||
| 1093 | else | ||
| 1094 | { | ||
| 1095 | if (CONSP (frame_size_history)) | ||
| 1096 | frame_size_history_extra (f, build_string ("set_window_size_1 " | ||
| 1097 | "invisible"), | ||
| 1098 | FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f), | ||
| 1099 | width, height, f->new_width, f->new_height); | ||
| 1100 | |||
| 1101 | adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width), | ||
| 1102 | FRAME_PIXEL_TO_TEXT_HEIGHT (f, height), | ||
| 1103 | 5, 0, Qx_set_window_size_1); | ||
| 1104 | } | ||
| 696 | } | 1105 | } |
| 697 | 1106 | ||
| 698 | void | 1107 | void |
| @@ -792,7 +1201,6 @@ android_new_font (struct frame *f, Lisp_Object font_object, int fontset) | |||
| 792 | static bool | 1201 | static bool |
| 793 | android_bitmap_icon (struct frame *f, Lisp_Object file) | 1202 | android_bitmap_icon (struct frame *f, Lisp_Object file) |
| 794 | { | 1203 | { |
| 795 | /* TODO */ | ||
| 796 | return false; | 1204 | return false; |
| 797 | } | 1205 | } |
| 798 | 1206 | ||
| @@ -841,6 +1249,13 @@ android_free_frame_resources (struct frame *f) | |||
| 841 | if (f == hlinfo->mouse_face_mouse_frame) | 1249 | if (f == hlinfo->mouse_face_mouse_frame) |
| 842 | reset_mouse_highlight (hlinfo); | 1250 | reset_mouse_highlight (hlinfo); |
| 843 | 1251 | ||
| 1252 | /* These two need to be freed now that they are used to compute the | ||
| 1253 | mouse position, I think. */ | ||
| 1254 | if (f == dpyinfo->last_mouse_motion_frame) | ||
| 1255 | dpyinfo->last_mouse_motion_frame = NULL; | ||
| 1256 | if (f == dpyinfo->last_mouse_frame) | ||
| 1257 | dpyinfo->last_mouse_frame = NULL; | ||
| 1258 | |||
| 844 | unblock_input (); | 1259 | unblock_input (); |
| 845 | } | 1260 | } |
| 846 | 1261 | ||
| @@ -3233,6 +3648,18 @@ syms_of_androidterm (void) | |||
| 3233 | { | 3648 | { |
| 3234 | Fprovide (Qandroid, Qnil); | 3649 | Fprovide (Qandroid, Qnil); |
| 3235 | 3650 | ||
| 3651 | DEFVAR_LISP ("android-wait-for-event-timeout", | ||
| 3652 | Vandroid_wait_for_event_timeout, | ||
| 3653 | doc: /* How long to wait for Android events. | ||
| 3654 | |||
| 3655 | Emacs will wait up to this many seconds to receive events after | ||
| 3656 | making changes which affect the state of the graphical interface. | ||
| 3657 | Under some situations this can take an indefinite amount of time, | ||
| 3658 | so it is important to limit the wait. | ||
| 3659 | |||
| 3660 | If set to a non-float value, there will be no wait at all. */); | ||
| 3661 | Vandroid_wait_for_event_timeout = make_float (0.1); | ||
| 3662 | |||
| 3236 | DEFVAR_BOOL ("x-use-underline-position-properties", | 3663 | DEFVAR_BOOL ("x-use-underline-position-properties", |
| 3237 | x_use_underline_position_properties, | 3664 | x_use_underline_position_properties, |
| 3238 | doc: /* SKIP: real doc in xterm.c. */); | 3665 | doc: /* SKIP: real doc in xterm.c. */); |