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.
This commit is contained in:
Po Lu 2022-02-12 04:42:42 +00:00
parent 9de7b3f335
commit 4c6a4281a4
4 changed files with 95 additions and 65 deletions

View file

@ -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));
}

View file

@ -1174,7 +1174,6 @@ class EmacsMenuBar : public BMenuBar
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 @@ class EmacsView : public BView
}
}
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 @@ class EmacsView : public BView
}
}
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)

View file

@ -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);

View file

@ -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 ();
}
}