summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-05-21 06:28:06 +0000
committerPo Lu <luangruo@yahoo.com>2022-05-21 06:28:06 +0000
commit3e3fe06307de183a4a4f9c7ead6a0d5c5adedfa9 (patch)
treed7778fdae880662d352d702ffe3e6d6a1a71f9d9
parentb7b14e920336646428c357b370cbfaac544ce295 (diff)
downloademacs-3e3fe06307de183a4a4f9c7ead6a0d5c5adedfa9.tar.gz
emacs-3e3fe06307de183a4a4f9c7ead6a0d5c5adedfa9.tar.bz2
emacs-3e3fe06307de183a4a4f9c7ead6a0d5c5adedfa9.zip
Compute frame workareas on Haiku
* lisp/frame.el (display-monitor-attributes-list): Implement specially on Haiku as well. * src/haiku_support.cc (get_zoom_rect): New function. Extract CalculateZoomRect here. (class EmacsWindow, SetFullscreen): Use that instead of CalculateZoomRect. (be_get_explicit_workarea): New function. * src/haiku_support.h: Update prototypes. * src/haikufns.c (Fhaiku_display_monitor_attributes_list): New function. (syms_of_haikufns): Register new subr.
-rw-r--r--lisp/frame.el4
-rw-r--r--src/haiku_support.cc170
-rw-r--r--src/haiku_support.h1
-rw-r--r--src/haikufns.c52
4 files changed, 155 insertions, 72 deletions
diff --git a/lisp/frame.el b/lisp/frame.el
index 094d67688c2..27f99fb7d21 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -2376,6 +2376,8 @@ If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(&optional terminal))
(declare-function pgtk-display-monitor-attributes-list "pgtkfns.c"
(&optional terminal))
+(declare-function haiku-display-monitor-attributes-list "haikufns.c"
+ (&optional terminal))
(defun display-monitor-attributes-list (&optional display)
"Return a list of physical monitor attributes on DISPLAY.
@@ -2427,6 +2429,8 @@ monitors."
(ns-display-monitor-attributes-list display))
((eq frame-type 'pgtk)
(pgtk-display-monitor-attributes-list display))
+ ((eq frame-type 'haiku)
+ (haiku-display-monitor-attributes-list display))
(t
(let ((geometry (list 0 0 (display-pixel-width display)
(display-pixel-height display))))
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 33c68cbd465..0c8e87154b2 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -449,6 +449,80 @@ map_normal (uint32_t kc, uint32_t *ch)
key_map_lock.Unlock ();
}
+static BRect
+get_zoom_rect (BWindow *window)
+{
+ BScreen screen;
+ BDeskbar deskbar;
+ BRect screen_frame;
+ BRect frame;
+ BRect deskbar_frame;
+ BRect window_frame;
+ BRect decorator_frame;
+
+ if (!screen.IsValid ())
+ gui_abort ("Failed to calculate screen rect");
+
+ screen_frame = frame = screen.Frame ();
+ deskbar_frame = deskbar.Frame ();
+
+ if (!(modifiers () & B_SHIFT_KEY) && !deskbar.IsAutoHide ())
+ {
+ switch (deskbar.Location ())
+ {
+ case B_DESKBAR_TOP:
+ frame.top = deskbar_frame.bottom + 2;
+ break;
+
+ case B_DESKBAR_BOTTOM:
+ case B_DESKBAR_LEFT_BOTTOM:
+ case B_DESKBAR_RIGHT_BOTTOM:
+ frame.bottom = deskbar_frame.top - 2;
+ break;
+
+ case B_DESKBAR_LEFT_TOP:
+ if (!deskbar.IsExpanded ())
+ frame.top = deskbar_frame.bottom + 2;
+ else if (!deskbar.IsAlwaysOnTop ()
+ && !deskbar.IsAutoRaise ())
+ frame.left = deskbar_frame.right + 2;
+ break;
+
+ default:
+ if (deskbar.IsExpanded ()
+ && !deskbar.IsAlwaysOnTop ()
+ && !deskbar.IsAutoRaise ())
+ frame.right = deskbar_frame.left - 2;
+ }
+ }
+
+ if (window)
+ {
+ window_frame = window->Frame ();
+ decorator_frame = window->DecoratorFrame ();
+
+ frame.top += (window_frame.top
+ - decorator_frame.top);
+ frame.bottom -= (decorator_frame.bottom
+ - window_frame.bottom);
+ frame.left += (window_frame.left
+ - decorator_frame.left);
+ frame.right -= (decorator_frame.right
+ - window_frame.right);
+
+ if (frame.top > deskbar_frame.bottom
+ || frame.bottom < deskbar_frame.top)
+ {
+ frame.left = screen_frame.left + (window_frame.left
+ - decorator_frame.left);
+ frame.right = screen_frame.right - (decorator_frame.right
+ - window_frame.right);
+ }
+ }
+
+ return frame;
+}
+
class Emacs : public BApplication
{
public:
@@ -593,77 +667,6 @@ public:
SetFeel (B_NORMAL_WINDOW_FEEL);
}
- BRect
- CalculateZoomRect (void)
- {
- BScreen screen (this);
- BDeskbar deskbar;
- BRect screen_frame;
- BRect frame;
- BRect deskbar_frame;
- BRect window_frame;
- BRect decorator_frame;
-
- if (!screen.IsValid ())
- gui_abort ("Failed to calculate screen rect");
-
- screen_frame = frame = screen.Frame ();
- deskbar_frame = deskbar.Frame ();
-
- if (!(modifiers () & B_SHIFT_KEY) && !deskbar.IsAutoHide ())
- {
- switch (deskbar.Location ())
- {
- case B_DESKBAR_TOP:
- frame.top = deskbar_frame.bottom + 2;
- break;
-
- case B_DESKBAR_BOTTOM:
- case B_DESKBAR_LEFT_BOTTOM:
- case B_DESKBAR_RIGHT_BOTTOM:
- frame.bottom = deskbar_frame.top - 2;
- break;
-
- case B_DESKBAR_LEFT_TOP:
- if (!deskbar.IsExpanded ())
- frame.top = deskbar_frame.bottom + 2;
- else if (!deskbar.IsAlwaysOnTop ()
- && !deskbar.IsAutoRaise ())
- frame.left = deskbar_frame.right + 2;
- break;
-
- default:
- if (deskbar.IsExpanded ()
- && !deskbar.IsAlwaysOnTop ()
- && !deskbar.IsAutoRaise ())
- frame.right = deskbar_frame.left - 2;
- }
- }
-
- window_frame = Frame ();
- decorator_frame = DecoratorFrame ();
-
- frame.top += (window_frame.top
- - decorator_frame.top);
- frame.bottom -= (decorator_frame.bottom
- - window_frame.bottom);
- frame.left += (window_frame.left
- - decorator_frame.left);
- frame.right -= (decorator_frame.right
- - window_frame.right);
-
- if (frame.top > deskbar_frame.bottom
- || frame.bottom < deskbar_frame.top)
- {
- frame.left = screen_frame.left + (window_frame.left
- - decorator_frame.left);
- frame.right = screen_frame.right - (decorator_frame.right
- - window_frame.right);
- }
-
- return frame;
- }
-
void
UpwardsSubset (EmacsWindow *w)
{
@@ -1248,7 +1251,7 @@ public:
{
case FULLSCREEN_MODE_MAXIMIZED:
pre_zoom_rect = frame;
- zoom_rect = CalculateZoomRect ();
+ zoom_rect = get_zoom_rect (this);
BWindow::Zoom (zoom_rect.LeftTop (),
BE_RECT_WIDTH (zoom_rect) - 1,
BE_RECT_HEIGHT (zoom_rect) - 1);
@@ -5210,3 +5213,26 @@ be_set_window_fullscreen_mode (void *window, enum haiku_fullscreen_mode mode)
w->SetFullscreen (mode);
w->UnlockLooper ();
}
+
+bool
+be_get_explicit_workarea (int *x, int *y, int *width, int *height)
+{
+ BDeskbar deskbar;
+ BRect zoom;
+ deskbar_location location;
+
+ location = deskbar.Location ();
+
+ if (location != B_DESKBAR_TOP
+ && location != B_DESKBAR_BOTTOM)
+ return false;
+
+ zoom = get_zoom_rect (NULL);
+
+ *x = zoom.left;
+ *y = zoom.top;
+ *width = BE_RECT_WIDTH (zoom);
+ *height = BE_RECT_HEIGHT (zoom);
+
+ return true;
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 163685572f6..dbb12c24aa2 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -702,6 +702,7 @@ extern void be_set_window_fullscreen_mode (void *, enum haiku_fullscreen_mode);
extern void be_lock_window (void *);
extern void be_unlock_window (void *);
+extern bool be_get_explicit_workarea (int *, int *, int *, int *);
#ifdef __cplusplus
}
diff --git a/src/haikufns.c b/src/haikufns.c
index 427ca7762da..7b1abb5cdc7 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -3021,6 +3021,57 @@ call this function yourself. */)
return Qnil;
}
+DEFUN ("haiku-display-monitor-attributes-list",
+ Fhaiku_display_monitor_attributes_list,
+ Shaiku_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the display TERMINAL.
+
+The optional argument TERMINAL specifies which display to ask about.
+TERMINAL should be a terminal object, a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object terminal)
+{
+ struct MonitorInfo monitor;
+ struct haiku_display_info *dpyinfo;
+ Lisp_Object frames, tail, tem;
+
+ dpyinfo = check_haiku_display_info (terminal);
+ frames = Qnil;
+
+ FOR_EACH_FRAME (tail, tem)
+ {
+ maybe_quit ();
+
+ if (FRAME_HAIKU_P (XFRAME (tem))
+ && !FRAME_TOOLTIP_P (XFRAME (tem)))
+ frames = Fcons (tem, frames);
+ }
+
+ monitor.geom.x = 0;
+ monitor.geom.y = 0;
+ be_get_screen_dimensions ((int *) &monitor.geom.width,
+ (int *) &monitor.geom.height);
+
+ monitor.mm_width = (monitor.geom.width
+ / (dpyinfo->resx / 25.4));
+ monitor.mm_height = (monitor.geom.height
+ / (dpyinfo->resy / 25.4));
+ monitor.name = (char *) "BeOS monitor";
+
+ if (!be_get_explicit_workarea ((int *) &monitor.work.x,
+ (int *) &monitor.work.y,
+ (int *) &monitor.work.width,
+ (int *) &monitor.work.height))
+ monitor.work = monitor.geom;
+
+ return make_monitor_attribute_list (&monitor, 1, 0,
+ make_vector (1, frames),
+ "fallback");
+}
+
frame_parm_handler haiku_frame_parm_handlers[] =
{
gui_set_autoraise,
@@ -3126,6 +3177,7 @@ syms_of_haikufns (void)
defsubr (&Sx_display_save_under);
defsubr (&Shaiku_frame_restack);
defsubr (&Shaiku_save_session_reply);
+ defsubr (&Shaiku_display_monitor_attributes_list);
tip_timer = Qnil;
staticpro (&tip_timer);