From: Po Lu Date: Mon, 23 May 2022 10:23:43 +0000 (+0000) Subject: Implement monitor change functions on Haiku X-Git-Tag: emacs-29.0.90~1910^2~487 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=caec741c00f907264524fafb5ba058063c898b92;p=emacs.git Implement monitor change functions on Haiku * src/haiku_io.c (haiku_len): Handle new event type. * src/haiku_support.cc (class EmacsScreenChangeMonitor): New class. (class Emacs, Emacs): Create new screen change monitor. (DispatchMessage): Update fullscreen state if the screen changed. (SetFullscreen): Don't punt if fullscreen mode is identical. * src/haiku_support.h (enum haiku_event_type): New event `SCREEN_CHANGE_EVENT'. (struct haiku_screen_changed_event): New struct. * src/haikuterm.c (haiku_read_socket): Handle new event. --- diff --git a/src/haiku_io.c b/src/haiku_io.c index 5d0031ef712..d3455276855 100644 --- a/src/haiku_io.c +++ b/src/haiku_io.c @@ -105,6 +105,8 @@ haiku_len (enum haiku_event_type type) return sizeof (struct haiku_menu_bar_left_event); case SCROLL_BAR_PART_EVENT: return sizeof (struct haiku_scroll_bar_part_event); + case SCREEN_CHANGED_EVENT: + return sizeof (struct haiku_screen_changed_event); } emacs_abort (); diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 8b2015b37bc..977728b5e3b 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -524,13 +524,68 @@ get_zoom_rect (BWindow *window) return frame; } +/* Invisible window used to get B_SCREEN_CHANGED events. */ +class EmacsScreenChangeMonitor : public BWindow +{ + BRect previous_screen_frame; + +public: + EmacsScreenChangeMonitor (void) : BWindow (BRect (-100, -100, 0, 0), "", + B_NO_BORDER_WINDOW_LOOK, + B_FLOATING_ALL_WINDOW_FEEL, + B_AVOID_FRONT | B_AVOID_FOCUS) + { + BScreen screen (this); + + if (!screen.IsValid ()) + return; + + previous_screen_frame = screen.Frame (); + + /* Immediately show this window upon creation. It will end up + hidden since there are no windows in its subset. */ + Show (); + + if (!LockLooper ()) + return; + + Hide (); + UnlockLooper (); + } + + void + DispatchMessage (BMessage *msg, BHandler *handler) + { + struct haiku_screen_changed_event rq; + BRect frame; + + if (msg->what == B_SCREEN_CHANGED) + { + if (msg->FindInt64 ("when", &rq.when) != B_OK) + rq.when = 0; + + if (msg->FindRect ("frame", &frame) != B_OK + || frame != previous_screen_frame) + { + haiku_write (SCREEN_CHANGED_EVENT, &rq); + + if (frame.IsValid ()) + previous_screen_frame = frame; + } + } + + BWindow::DispatchMessage (msg, handler); + } +}; + class Emacs : public BApplication { public: BMessage settings; bool settings_valid_p = false; + EmacsScreenChangeMonitor *monitor; - Emacs () : BApplication ("application/x-vnd.GNU-emacs") + Emacs (void) : BApplication ("application/x-vnd.GNU-emacs") { BPath settings_path; @@ -546,6 +601,15 @@ public: return; settings_valid_p = true; + monitor = new EmacsScreenChangeMonitor; + } + + ~Emacs (void) + { + if (monitor->LockLooper ()) + monitor->Quit (); + else + delete monitor; } void @@ -999,6 +1063,13 @@ public: } else if (msg->what == SEND_MOVE_FRAME_EVENT) FrameMoved (Frame ().LeftTop ()); + else if (msg->what == B_SCREEN_CHANGED) + { + if (fullscreen_mode != FULLSCREEN_MODE_NONE) + SetFullscreen (fullscreen_mode); + + BWindow::DispatchMessage (msg, handler); + } else BWindow::DispatchMessage (msg, handler); } @@ -1243,9 +1314,6 @@ public: { BRect zoom_rect, frame; - if (fullscreen_mode == mode) - return; - frame = ClearFullscreen (mode); switch (mode) diff --git a/src/haiku_support.h b/src/haiku_support.h index dbb12c24aa2..9597c24c5db 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -112,9 +112,15 @@ enum haiku_event_type DRAG_AND_DROP_EVENT, APP_QUIT_REQUESTED_EVENT, DUMMY_EVENT, - MENU_BAR_LEFT + SCREEN_CHANGED_EVENT, + MENU_BAR_LEFT, }; +struct haiku_screen_changed_event +{ + bigtime_t when; +}; + struct haiku_quit_requested_event { void *window; diff --git a/src/haikuterm.c b/src/haikuterm.c index 628ef2b0260..59fbb9ad82f 100644 --- a/src/haikuterm.c +++ b/src/haikuterm.c @@ -3899,6 +3899,15 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit) BMessage_delete (b->message); break; } + case SCREEN_CHANGED_EVENT: + { + struct haiku_screen_changed_event *b = buf; + + inev.kind = MONITORS_CHANGED_EVENT; + XSETTERMINAL (inev.arg, x_display_list->terminal); + inev.timestamp = b->when / 1000; + break; + } case APP_QUIT_REQUESTED_EVENT: inev.kind = SAVE_SESSION_EVENT; inev.arg = Qt;