diff options
author | Po Lu <luangruo@yahoo.com> | 2022-05-11 12:40:32 +0000 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-05-11 12:40:53 +0000 |
commit | 5079f42446aab520e20aad30f825ccbc448ba4e3 (patch) | |
tree | 68972443171942d16b5c9880dc7833e348ff5954 /src/haikufns.c | |
parent | 125cda74981fddf63f827f96844cf6d9a413aa1a (diff) | |
download | emacs-5079f42446aab520e20aad30f825ccbc448ba4e3.tar.gz |
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.
Diffstat (limited to 'src/haikufns.c')
-rw-r--r-- | src/haikufns.c | 173 |
1 files changed, 147 insertions, 26 deletions
diff --git a/src/haikufns.c b/src/haikufns.c index 8596317de25..0abb4188955 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -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 |