Add support for changing pointer types on Haiku

* doc/lispref/frames.texi (Pointer Shape): Document that the
pointer shape can now be changed on some window systems other
than X.

* lisp/term/haiku-win.el (x-pointer-X-cursor, x-pointer-arrow)
(x-pointer-bottom-left-corner, x-pointer-bottom-right-corner)
(x-pointer-bottom-side, x-pointer-clock, x-pointer-cross)
(x-pointer-cross-reverse, x-pointer-crosshair)
(x-pointer-diamond-cross, x-pointer-hand1, x-pointer-hand2)
(x-pointer-left-side, x-pointer-right-side)
(x-pointer-sb-down-arrow, x-pointer-sb-left-arrow)
(x-pointer-sb-right-arrow, x-pointer-sb-up-arrow, x-pointer-target)
(x-pointer-top-left-corner, x-pointer-top-right-corner)
(x-pointer-top-side, x-pointer-watch, x-pointer-invisible): New
pointer constants.

* src/haiku_support.cc (BCursor_from_id): Accept int instead of
enum.
* src/haiku_support.h: Update prototypes.

* src/haikufns.c (haiku_create_frame): Stop manually assigning
cursors and set default value of the mouse color property.
(haiku_free_frame_resources): Free custom cursors too.
(struct user_cursor_info, INIT_USER_CURSOR): New struct.
(haiku_free_custom_cursors): New function.
(haiku_set_mouse_color): New param handler.
(haiku_frame_parm_handlers): Add param handler.
(syms_of_haikufns): New cursor shape variables from X.

* src/haikuterm.h: Update prototypes.
This commit is contained in:
Po Lu 2022-05-11 12:40:32 +00:00
parent 125cda7498
commit 5079f42446
6 changed files with 184 additions and 30 deletions

View file

@ -3877,8 +3877,9 @@ in the buffer. The default is to use the @code{arrow} (non-text)
pointer style.
@end defopt
When using X, you can specify what the @code{text} pointer style
really looks like by setting the variable @code{x-pointer-shape}.
When using some window systems, you can specify what the @code{text}
pointer style really looks like by setting the variable
@code{x-pointer-shape}.
@defvar x-pointer-shape
This variable specifies the pointer shape to use ordinarily in the

View file

@ -392,6 +392,37 @@ take effect on menu items until the menu bar is updated again."
;; the Deskbar will not, so kill ourself here.
(unless cancel-shutdown (kill-emacs))))
;;;; Cursors.
;; We use the same interface as X, but the cursor numbers are
;; different, and there are also less cursors.
(defconst x-pointer-X-cursor 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-arrow 1) ; B_CURSOR_ID_SYSTEM_DEFAULT
(defconst x-pointer-bottom-left-corner 22) ; B_CURSOR_ID_RESIZE_SOUTH_WEST
(defconst x-pointer-bottom-right-corner 21) ; B_CURSOR_ID_RESIZE_SOUTH_EAST
(defconst x-pointer-bottom-side 17) ; B_CURSOR_ID_RESIZE_SOUTH
(defconst x-pointer-clock 14) ; B_CURSOR_ID_PROGRESS
(defconst x-pointer-cross 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-cross-reverse 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-crosshair 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-diamond-cross 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-hand1 7) ; B_CURSOR_ID_GRAB
(defconst x-pointer-hand2 8) ; B_CURSOR_ID_GRABBING
(defconst x-pointer-left-side 18) ; B_CURSOR_ID_RESIZE_WEST
(defconst x-pointer-right-side 16) ; B_CURSOR_ID_RESIZE_EAST
(defconst x-pointer-sb-down-arrow 17) ; B_CURSOR_ID_RESIZE_SOUTH
(defconst x-pointer-sb-left-arrow 18) ; B_CURSOR_ID_RESIZE_WEST
(defconst x-pointer-sb-right-arrow 16) ; B_CURSOR_ID_RESIZE_EAST
(defconst x-pointer-sb-up-arrow 16) ; B_CURSOR_ID_RESIZE_NORTH
(defconst x-pointer-target 5) ; B_CURSOR_ID_CROSS_HAIR
(defconst x-pointer-top-left-corner 20) ; B_CURSOR_ID_RESIZE_NORTH_WEST
(defconst x-pointer-top-right-corner 19) ; B_CURSOR_ID_RESIZE_NORTH_EAST
(defconst x-pointer-top-side 16) ; B_CURSOR_ID_RESIZE_NORTH
(defconst x-pointer-watch 14) ; B_CURSOR_ID_PROGRESS
(defconst x-pointer-invisible 12) ; B_CURSOR_ID_NO_CURSOR
(provide 'haiku-win)
(provide 'term/haiku-win)

View file

@ -3392,7 +3392,7 @@ BCursor_create_modeline (void)
}
void *
BCursor_from_id (enum haiku_cursor cursor)
BCursor_from_id (int cursor)
{
return new BCursor ((enum BCursorID) cursor);
}

View file

@ -557,7 +557,7 @@ extern void be_get_screen_dimensions (int *, int *);
/* Functions for creating and freeing cursors. */
extern void *BCursor_create_default (void);
extern void *BCursor_from_id (enum haiku_cursor);
extern void *BCursor_from_id (int);
extern void *BCursor_create_modeline (void);
extern void *BCursor_create_i_beam (void);
extern void *BCursor_create_progress_cursor (void);

View file

@ -763,6 +763,8 @@ haiku_create_frame (Lisp_Object parms)
"foreground", "Foreground", RES_TYPE_STRING);
gui_default_parameter (f, parms, Qbackground_color, build_string ("white"),
"background", "Background", RES_TYPE_STRING);
gui_default_parameter (f, parms, Qmouse_color, build_string ("black"),
"pointerColor", "Foreground", RES_TYPE_STRING);
gui_default_parameter (f, parms, Qline_spacing, Qnil,
"lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
gui_default_parameter (f, parms, Qleft_fringe, Qnil,
@ -820,33 +822,11 @@ haiku_create_frame (Lisp_Object parms)
RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || (!EQ (tem, Qunbound) && !NILP (tem));
block_input ();
#define ASSIGN_CURSOR(cursor) \
(FRAME_OUTPUT_DATA (f)->cursor = dpyinfo->cursor)
ASSIGN_CURSOR (text_cursor);
ASSIGN_CURSOR (nontext_cursor);
ASSIGN_CURSOR (modeline_cursor);
ASSIGN_CURSOR (hand_cursor);
ASSIGN_CURSOR (hourglass_cursor);
ASSIGN_CURSOR (horizontal_drag_cursor);
ASSIGN_CURSOR (vertical_drag_cursor);
ASSIGN_CURSOR (left_edge_cursor);
ASSIGN_CURSOR (top_left_corner_cursor);
ASSIGN_CURSOR (top_edge_cursor);
ASSIGN_CURSOR (top_right_corner_cursor);
ASSIGN_CURSOR (right_edge_cursor);
ASSIGN_CURSOR (bottom_right_corner_cursor);
ASSIGN_CURSOR (bottom_edge_cursor);
ASSIGN_CURSOR (bottom_left_corner_cursor);
ASSIGN_CURSOR (no_cursor);
FRAME_OUTPUT_DATA (f)->current_cursor = dpyinfo->text_cursor;
#undef ASSIGN_CURSOR
f->terminal->reference_count++;
FRAME_OUTPUT_DATA (f)->window = BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
block_input ();
FRAME_OUTPUT_DATA (f)->window
= BWindow_new (&FRAME_OUTPUT_DATA (f)->view);
unblock_input ();
if (!FRAME_OUTPUT_DATA (f)->window)
@ -1567,6 +1547,7 @@ haiku_free_frame_resources (struct frame *f)
dpyinfo = FRAME_DISPLAY_INFO (f);
free_frame_faces (f);
haiku_free_custom_cursors (f);
/* Free scroll bars */
for (bar = FRAME_SCROLL_BARS (f); !NILP (bar); bar = b->next)
@ -1792,6 +1773,133 @@ haiku_set_sticky (struct frame *f, Lisp_Object new_value,
unblock_input ();
}
struct user_cursor_info
{
/* A pointer to the Lisp_Object describing the cursor. */
Lisp_Object *lisp_cursor;
/* The offset of the cursor in the `struct haiku_output' of each
frame. */
ptrdiff_t output_offset;
/* The offset of the default value of the cursor in the display
info structure. */
ptrdiff_t default_offset;
};
#define INIT_USER_CURSOR(lisp, cursor) \
{ (lisp), offsetof (struct haiku_output, cursor), \
offsetof (struct haiku_display_info, cursor) }
struct user_cursor_info custom_cursors[] =
{
INIT_USER_CURSOR (&Vx_pointer_shape, text_cursor),
INIT_USER_CURSOR (NULL, nontext_cursor),
INIT_USER_CURSOR (NULL, modeline_cursor),
INIT_USER_CURSOR (&Vx_sensitive_text_pointer_shape, hand_cursor),
INIT_USER_CURSOR (&Vx_hourglass_pointer_shape, hourglass_cursor),
INIT_USER_CURSOR (NULL, horizontal_drag_cursor),
INIT_USER_CURSOR (NULL, vertical_drag_cursor),
INIT_USER_CURSOR (NULL, left_edge_cursor),
INIT_USER_CURSOR (NULL, top_left_corner_cursor),
INIT_USER_CURSOR (NULL, top_edge_cursor),
INIT_USER_CURSOR (NULL, top_right_corner_cursor),
INIT_USER_CURSOR (NULL, right_edge_cursor),
INIT_USER_CURSOR (NULL, bottom_right_corner_cursor),
INIT_USER_CURSOR (NULL, bottom_edge_cursor),
INIT_USER_CURSOR (NULL, bottom_left_corner_cursor),
INIT_USER_CURSOR (NULL, no_cursor),
};
/* Free all cursors not default in F. */
void
haiku_free_custom_cursors (struct frame *f)
{
struct user_cursor_info *cursor;
struct haiku_output *output;
struct haiku_display_info *dpyinfo;
Emacs_Cursor *frame_cursor;
Emacs_Cursor *display_cursor;
int i;
output = FRAME_OUTPUT_DATA (f);
dpyinfo = FRAME_DISPLAY_INFO (f);
for (i = 0; i < ARRAYELTS (custom_cursors); ++i)
{
cursor = &custom_cursors[i];
frame_cursor = (Emacs_Cursor *) ((char *) output
+ cursor->output_offset);
display_cursor = (Emacs_Cursor *) ((char *) dpyinfo
+ cursor->default_offset);
if (*frame_cursor != *display_cursor
&& *frame_cursor)
{
BCursor_delete (*frame_cursor);
if (output->current_cursor == *frame_cursor)
output->current_cursor = *display_cursor;
}
*frame_cursor = *display_cursor;
}
}
static void
haiku_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
struct haiku_output *output;
Emacs_Cursor *frame_cursor, old;
int i, n;
output = FRAME_OUTPUT_DATA (f);
/* This will also reset all the cursors back to their default
values. */
haiku_free_custom_cursors (f);
for (i = 0; i < ARRAYELTS (custom_cursors); ++i)
{
frame_cursor = (Emacs_Cursor *) ((char *) output
+ custom_cursors[i].output_offset);
old = *frame_cursor;
if (custom_cursors[i].lisp_cursor
&& FIXNUMP (*custom_cursors[i].lisp_cursor))
{
if (!RANGED_FIXNUMP (0, *custom_cursors[i].lisp_cursor,
28)) /* 28 is the largest Haiku cursor ID. */
signal_error ("Invalid cursor",
*custom_cursors[i].lisp_cursor);
n = XFIXNUM (*custom_cursors[i].lisp_cursor);
/* Create and set the custom cursor. */
block_input ();
*frame_cursor = BCursor_from_id (n);
unblock_input ();
/* This function can be called before the frame's window is
created. */
if (FRAME_HAIKU_WINDOW (f))
{
if (output->current_cursor == old)
{
output->current_cursor = *frame_cursor;
block_input ();
BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
*frame_cursor);
unblock_input ();
}
}
}
}
update_face_from_frame_parameter (f, Qmouse_color, arg);
}
DEFUN ("haiku-set-mouse-absolute-pixel-position",
@ -2701,7 +2809,7 @@ frame_parm_handler haiku_frame_parm_handlers[] =
gui_set_right_divider_width,
gui_set_bottom_divider_width,
haiku_set_menu_bar_lines,
NULL, /* set mouse color */
haiku_set_mouse_color,
haiku_explicitly_set_name,
gui_set_scroll_bar_width,
gui_set_scroll_bar_height,
@ -2805,6 +2913,19 @@ syms_of_haikufns (void)
doc: /* SKIP: real doc in xfns.c. */);
Vx_cursor_fore_pixel = Qnil;
DEFVAR_LISP ("x-pointer-shape", Vx_pointer_shape,
doc: /* SKIP: real doc in xfns.c. */);
Vx_pointer_shape = Qnil;
DEFVAR_LISP ("x-hourglass-pointer-shape", Vx_hourglass_pointer_shape,
doc: /* SKIP: real doc in xfns.c. */);
Vx_hourglass_pointer_shape = Qnil;
DEFVAR_LISP ("x-sensitive-text-pointer-shape",
Vx_sensitive_text_pointer_shape,
doc: /* SKIP: real doc in xfns.c. */);
Vx_sensitive_text_pointer_shape = Qnil;
DEFVAR_LISP ("haiku-allowed-ui-colors", Vhaiku_allowed_ui_colors,
doc: /* Vector of UI colors that Emacs can look up from the system.
If this is set up incorrectly, Emacs can crash when encoutering an

View file

@ -304,6 +304,7 @@ extern void haiku_set_cursor_type (struct frame *, Lisp_Object, Lisp_Object);
extern void haiku_set_internal_border_width (struct frame *, Lisp_Object, Lisp_Object);
extern void haiku_change_tab_bar_height (struct frame *, int);
extern void haiku_change_tool_bar_height (struct frame *, int);
extern void haiku_free_custom_cursors (struct frame *);
extern void haiku_query_color (uint32_t, Emacs_Color *);