]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement monitor change functions on Haiku
authorPo Lu <luangruo@yahoo.com>
Mon, 23 May 2022 10:23:43 +0000 (10:23 +0000)
committerPo Lu <luangruo@yahoo.com>
Mon, 23 May 2022 10:23:59 +0000 (10:23 +0000)
* 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
src/haiku_support.cc
src/haiku_support.h
src/haikuterm.c

index 5d0031ef712ac6e331db92677d22e74f0e88aca7..d3455276855426dc3f7cd3564d2c68348610b429 100644 (file)
@@ -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 ();
index 8b2015b37bc48751b055a40669c3067037f14443..977728b5e3bd1471cdc02f412e9ab0c5c7d03783 100644 (file)
@@ -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)
index dbb12c24aa2670a7ca83e9071b8b3f89eae64849..9597c24c5db648d36506a467daea791949bdbb47 100644 (file)
@@ -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;
index 628ef2b026007490c8472626b755f211403f951e..59fbb9ad82fbadcae91684aaf30b8c73062b036f 100644 (file)
@@ -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;