emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master caec741c00: Implement monitor change functions on Haiku


From: Po Lu
Subject: master caec741c00: Implement monitor change functions on Haiku
Date: Mon, 23 May 2022 06:24:42 -0400 (EDT)

branch: master
commit caec741c00f907264524fafb5ba058063c898b92
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/haiku_io.c       |  2 ++
 src/haiku_support.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/haiku_support.h  |  8 +++++-
 src/haikuterm.c      |  9 +++++++
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/src/haiku_io.c b/src/haiku_io.c
index 5d0031ef71..d345527685 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 8b2015b37b..977728b5e3 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 dbb12c24aa..9597c24c5d 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 628ef2b026..59fbb9ad82 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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]