emacs-diffs
[Top][All Lists]
Advanced

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

master 4c6a4281a4: Implement visual bell on Haiku like on X


From: Po Lu
Subject: master 4c6a4281a4: Implement visual bell on Haiku like on X
Date: Fri, 11 Feb 2022 23:45:55 -0500 (EST)

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

    Implement visual bell on Haiku like on X
    
    * src/haiku_draw_support.cc
    (BView_FillRectangleForVisibleBell): Delete function.
    (BView_InvertRect): New function.
    
    * src/haiku_support.cc (class EmacsView): Delete field
    `visible_bell_color' and visible bell related methods.
    (EmacsView_do_visible_bell): Delete function.
    * src/haiku_support.h: Update prototypes.
    
    * src/haikuterm.c (haiku_flash): Implement using
    `BView_InvertRect'.
    (haiku_beep): Use `haiku_flash' instead.
---
 src/haiku_draw_support.cc |   7 ++--
 src/haiku_support.cc      |  39 -----------------
 src/haiku_support.h       |  10 ++---
 src/haikuterm.c           | 104 +++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 95 insertions(+), 65 deletions(-)

diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
index 270a619b89..f8df298958 100644
--- a/src/haiku_draw_support.cc
+++ b/src/haiku_draw_support.cc
@@ -479,10 +479,9 @@ BView_SetHighColorForVisibleBell (void *view, uint32_t 
color)
 }
 
 void
-BView_FillRectangleForVisibleBell (void *view, int x, int y, int width, int 
height)
+BView_InvertRect (void *view, int x, int y, int width, int height)
 {
-  BView *vw = (BView *) view;
-  BRect rect = BRect (x, y, x + width - 1, y + height - 1);
+  BView *vw = get_view (view);
 
-  vw->FillRect (rect);
+  vw->InvertRect (BRect (x, y, x + width - 1, y + height - 1));
 }
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 71aa323b07..28bf2ac8b6 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -1174,7 +1174,6 @@ public:
 class EmacsView : public BView
 {
 public:
-  uint32_t visible_bell_color = 0;
   uint32_t previous_buttons = 0;
   int looper_locked_count = 0;
   BRegion sb_region;
@@ -1313,30 +1312,12 @@ public:
       }
   }
 
-  void
-  Pulse (void)
-  {
-    visible_bell_color = 0;
-    SetFlags (Flags () & ~B_PULSE_NEEDED);
-    Window ()->SetPulseRate (0);
-    Invalidate ();
-  }
-
   void
   Draw (BRect expose_bounds)
   {
     struct haiku_expose_event rq;
     EmacsWindow *w = (EmacsWindow *) Window ();
 
-    if (visible_bell_color > 0)
-      {
-       PushState ();
-       BView_SetHighColorForVisibleBell (this, visible_bell_color);
-       FillRect (Frame ());
-       PopState ();
-       return;
-      }
-
     if (w->shown_flag && offscreen_draw_view)
       {
        PushState ();
@@ -1372,18 +1353,6 @@ public:
       }
   }
 
-  void
-  DoVisibleBell (uint32_t color)
-  {
-    if (!LockLooper ())
-      gui_abort ("Failed to lock looper during visible bell");
-    visible_bell_color = color | (255 << 24);
-    SetFlags (Flags () | B_PULSE_NEEDED);
-    Window ()->SetPulseRate (100 * 1000);
-    Invalidate ();
-    UnlockLooper ();
-  }
-
   void
   FlipBuffers (void)
   {
@@ -3054,14 +3023,6 @@ be_app_quit (void)
     }
 }
 
-/* Temporarily fill VIEW with COLOR.  */
-void
-EmacsView_do_visible_bell (void *view, uint32_t color)
-{
-  EmacsView *vw = (EmacsView *) view;
-  vw->DoVisibleBell (color);
-}
-
 /* Zoom WINDOW.  */
 void
 BWindow_zoom (void *window)
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 369a4b6bb4..e50d347009 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -472,10 +472,6 @@ extern "C"
   extern void
   BView_SetHighColorForVisibleBell (void *view, uint32_t color);
 
-  extern void
-  BView_FillRectangleForVisibleBell (void *view, int x, int y, int width,
-                                    int height);
-
   extern void
   BView_SetLowColor (void *view, uint32_t color);
 
@@ -538,6 +534,9 @@ extern "C"
                  int vx, int vy, int vwidth, int vheight,
                  uint32_t color);
 
+  extern void
+  BView_InvertRect (void *view, int x, int y, int width, int height);
+
   extern void *
   BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color,
                            double rot, int desw, int desh);
@@ -794,9 +793,6 @@ extern "C"
   extern void
   c_unbind_to_nil_from_cxx (ptrdiff_t idx);
 
-  extern void
-  EmacsView_do_visible_bell (void *view, uint32_t color);
-
   extern void
   BWindow_zoom (void *window);
 
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 117d8df2e5..3de215bc88 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3380,6 +3380,94 @@ haiku_free_pixmap (struct frame *f, Emacs_Pixmap pixmap)
   BBitmap_free (pixmap);
 }
 
+static void
+haiku_flash (struct frame *f)
+{
+  /* Get the height not including a menu bar widget.  */
+  int height = FRAME_PIXEL_HEIGHT (f);
+  /* Height of each line to flash.  */
+  int flash_height = FRAME_LINE_HEIGHT (f);
+  /* These will be the left and right margins of the rectangles.  */
+  int flash_left = FRAME_INTERNAL_BORDER_WIDTH (f);
+  int flash_right = FRAME_PIXEL_WIDTH (f) - FRAME_INTERNAL_BORDER_WIDTH (f);
+  int width = flash_right - flash_left;
+  void *view = FRAME_HAIKU_VIEW (f);
+  struct timespec delay, wakeup, current, timeout;
+
+  delay = make_timespec (0, 150 * 1000 * 1000);
+  wakeup = timespec_add (current_timespec (), delay);
+
+  BView_draw_lock (view);
+  BView_StartClip (view);
+  /* If window is tall, flash top and bottom line.  */
+  if (height > 3 * FRAME_LINE_HEIGHT (f))
+    {
+      BView_InvertRect (view, flash_left,
+                       (FRAME_INTERNAL_BORDER_WIDTH (f)
+                        + FRAME_TOP_MARGIN_HEIGHT (f)),
+                       width, flash_height);
+
+      BView_InvertRect (view, flash_left,
+                       (height - flash_height
+                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                       width, flash_height);
+    }
+  else
+    /* If it is short, flash it all.  */
+    BView_InvertRect (view, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+  BView_EndClip (view);
+  BView_draw_unlock (view);
+
+  flush_frame (f);
+
+  if (EmacsView_double_buffered_p (view))
+    haiku_flip_buffers (f);
+
+  /* Keep waiting until past the time wakeup or any input gets
+     available.  */
+  while (!detect_input_pending ())
+    {
+      current = current_timespec ();
+
+      /* Break if result would not be positive.  */
+      if (timespec_cmp (wakeup, current) <= 0)
+       break;
+
+      /* How long `select' should wait.  */
+      timeout = make_timespec (0, 10 * 1000 * 1000);
+
+      /* Try to wait that long--but we might wake up sooner.  */
+      pselect (0, NULL, NULL, NULL, &timeout, NULL);
+    }
+
+  BView_draw_lock (view);
+  BView_StartClip (view);
+  /* If window is tall, flash top and bottom line.  */
+  if (height > 3 * FRAME_LINE_HEIGHT (f))
+    {
+      BView_InvertRect (view, flash_left,
+                       (FRAME_INTERNAL_BORDER_WIDTH (f)
+                        + FRAME_TOP_MARGIN_HEIGHT (f)),
+                       width, flash_height);
+
+      BView_InvertRect (view, flash_left,
+                       (height - flash_height
+                        - FRAME_INTERNAL_BORDER_WIDTH (f)),
+                       width, flash_height);
+    }
+  else
+    /* If it is short, flash it all.  */
+    BView_InvertRect (view, flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
+                     width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
+  BView_EndClip (view);
+  BView_draw_unlock (view);
+
+  flush_frame (f);
+  if (EmacsView_double_buffered_p (view))
+    haiku_flip_buffers (f);
+}
+
 static void
 haiku_beep (struct frame *f)
 {
@@ -3389,21 +3477,7 @@ haiku_beep (struct frame *f)
       if (view)
        {
          block_input ();
-         BView_draw_lock (view);
-         if (!EmacsView_double_buffered_p (view))
-           {
-             BView_SetHighColorForVisibleBell (view, FRAME_FOREGROUND_PIXEL 
(f));
-             BView_FillRectangleForVisibleBell (view, 0, 0, FRAME_PIXEL_WIDTH 
(f),
-                                                FRAME_PIXEL_HEIGHT (f));
-             SET_FRAME_GARBAGED (f);
-             expose_frame (f, 0, 0, 0, 0);
-           }
-         else
-           {
-             EmacsView_do_visible_bell (view, FRAME_FOREGROUND_PIXEL (f));
-             haiku_flip_buffers (f);
-           }
-         BView_draw_unlock (view);
+         haiku_flash (f);
          unblock_input ();
        }
     }



reply via email to

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