emacs-diffs
[Top][All Lists]
Advanced

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

master 119f613cf5: Allow actually setting cursor colors on Haiku


From: Po Lu
Subject: master 119f613cf5: Allow actually setting cursor colors on Haiku
Date: Thu, 12 May 2022 23:14:58 -0400 (EDT)

branch: master
commit 119f613cf5a39db1712c87ebcc21d7600ef79e5f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Allow actually setting cursor colors on Haiku
    
    * src/haiku_support.cc (be_create_pixmap_cursor): New function.
    * src/haiku_support.h: Update prototypes.
    
    * src/haikufns.c (haiku_create_frame): Change default cursor
    color to "font-color".
    (haiku_create_tip_frame): Likewise.
    
    (struct user_cursor_bitmap_info): New struct.
    (cursor_bitmaps): New list of bitmaps corresponding to cursors.
    (haiku_create_colored_cursor): New function.
    (haiku_free_custom_cursors): Set current cursor to the default
    cursor before freeing the original value.
    (haiku_set_mouse_color): Actually recolor cursors based on
    built-in bitmaps.
    
    * src/haikuterm.c (haiku_defined_color): Clean up coding style.
---
 src/haiku_support.cc |  18 ++++++
 src/haiku_support.h  |   1 +
 src/haikufns.c       | 152 +++++++++++++++++++++++++++++++++++++++++++--------
 src/haikuterm.c      |   7 +--
 4 files changed, 149 insertions(+), 29 deletions(-)

diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 39e8daa826..c0bd3c1b0e 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -5122,3 +5122,21 @@ be_roster_launch (const char *type, const char *file, 
char **cargs,
                                   ? INT_MAX : nargs),
                            cargs, team_id);
 }
+
+void *
+be_create_pixmap_cursor (void *bitmap, int x, int y)
+{
+  BBitmap *bm;
+  BCursor *cursor;
+
+  bm = (BBitmap *) bitmap;
+  cursor = new BCursor (bm, BPoint (x, y));
+
+  if (cursor->InitCheck () != B_OK)
+    {
+      delete cursor;
+      return NULL;
+    }
+
+  return cursor;
+}
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 3ea6e838d7..b9cbd6ca4c 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -563,6 +563,7 @@ extern void *BCursor_create_i_beam (void);
 extern void *BCursor_create_progress_cursor (void);
 extern void *BCursor_create_grab (void);
 extern void BCursor_delete (void *);
+extern void *be_create_pixmap_cursor (void *, int, int);
 
 extern void *BScrollBar_make_for_view (void *, int, int, int, int, int, void 
*);
 extern void BScrollBar_delete (void *);
diff --git a/src/haikufns.c b/src/haikufns.c
index 13432785bd..9bf672f1d8 100644
--- a/src/haikufns.c
+++ b/src/haikufns.c
@@ -34,6 +34,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "haiku_support.h"
 #include "termhooks.h"
 
+#include "bitmaps/leftptr.xbm"
+#include "bitmaps/leftpmsk.xbm"
+
 #include <stdlib.h>
 
 #include <kernel/OS.h>
@@ -763,7 +766,7 @@ 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"),
+  gui_default_parameter (f, parms, Qmouse_color, build_string ("font-color"),
                          "pointerColor", "Foreground", RES_TYPE_STRING);
   gui_default_parameter (f, parms, Qline_spacing, Qnil,
                          "lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
@@ -1056,7 +1059,10 @@ haiku_create_tip_frame (Lisp_Object parms)
 
   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"),
+
+  /* FIXME: is there a better method to tell Emacs to not recolor the
+     cursors other than setting the color to a special value?  */
+  gui_default_parameter (f, parms, Qmouse_color, build_string ("font-color"),
                          "pointerColor", "Foreground", RES_TYPE_STRING);
   gui_default_parameter (f, parms, Qcursor_color, build_string ("black"),
                          "cursorColor", "Foreground", RES_TYPE_STRING);
@@ -1787,6 +1793,23 @@ struct user_cursor_info
   ptrdiff_t default_offset;
 };
 
+struct user_cursor_bitmap_info
+{
+  /* The name of a bitmap to use instead of the font cursor if a
+     cursor color was set.  */
+  const void *bits;
+
+  /* The mask for that bitmap.  */
+  const void *mask;
+
+  /* The dimensions of the cursor bitmap.  */
+  int width, height;
+
+  /* The position inside the cursor bitmap corresponding to the
+     position of the mouse pointer.  */
+  int x, y;
+};
+
 #define INIT_USER_CURSOR(lisp, cursor)                 \
   { (lisp), offsetof (struct haiku_output, cursor),    \
       offsetof (struct haiku_display_info, cursor) }
@@ -1811,7 +1834,70 @@ struct user_cursor_info custom_cursors[] =
     INIT_USER_CURSOR (NULL,                            no_cursor),
   };
 
-/* Free all cursors not default in F.  */
+struct user_cursor_bitmap_info cursor_bitmaps[] =
+  {
+    { NULL, NULL, 0, 0, 0, 0 },                                /* text_cursor 
*/
+    { left_ptr_bits, left_ptrmsk_bits, 16, 16, 4, 1 }, /* nontext_cursor */
+    { left_ptr_bits, left_ptrmsk_bits, 16, 16, 4, 1 }, /* modeline_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* hand_cursor 
*/
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
hourglass_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
horizontal_drag_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
vertical_drag_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
left_edge_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
top_left_corner_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
top_edge_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
top_right_corner_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
right_edge_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
bottom_right_corner_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
bottom_edge_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* 
bottom_left_corner_cursor */
+    { NULL, NULL, 0, 0, 0, 0 },                                /* no_cursor */
+  };
+
+static void *
+haiku_create_colored_cursor (struct user_cursor_bitmap_info *info,
+                            uint32_t foreground, uint32_t background)
+{
+  const char *bits, *mask;
+  void *bitmap, *cursor;
+  int width, height, bytes_per_line, x, y;
+
+  bits = info->bits;
+  mask = info->mask;
+  width = info->width;
+  height = info->height;
+  bytes_per_line = (width + 7) / 8;
+
+  bitmap = BBitmap_new (width, height, false);
+
+  if (!bitmap)
+    memory_full (SIZE_MAX);
+
+  for (y = 0; y < height; ++y)
+    {
+      for (x = 0; x < width; ++x)
+       {
+         if (mask[x / 8] >> (x % 8) & 1)
+           haiku_put_pixel (bitmap, x, y,
+                            (bits[x / 8] >> (x % 8) & 1
+                             ? (foreground | 255u << 24)
+                             : (background | 255u << 24)));
+         else
+           haiku_put_pixel (bitmap, x, y, 0);
+       }
+
+      mask += bytes_per_line;
+      bits += bytes_per_line;
+    }
+
+  cursor = be_create_pixmap_cursor (bitmap, info->x, info->y);
+  BBitmap_free (bitmap);
+
+  return cursor;
+}
+
+/* Free all cursors on F that were allocated specifically for the
+   frame.  */
 void
 haiku_free_custom_cursors (struct frame *f)
 {
@@ -1833,13 +1919,12 @@ haiku_free_custom_cursors (struct frame *f)
       display_cursor = (Emacs_Cursor *) ((char *) dpyinfo
                                         + cursor->default_offset);
 
-      if (*frame_cursor != *display_cursor
-         && *frame_cursor)
+      if (*frame_cursor != *display_cursor && *frame_cursor)
        {
-         BCursor_delete (*frame_cursor);
-
          if (output->current_cursor == *frame_cursor)
            output->current_cursor = *display_cursor;
+
+         BCursor_delete (*frame_cursor);
        }
 
       *frame_cursor = *display_cursor;
@@ -1850,8 +1935,21 @@ 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;
+  Emacs_Cursor *frame_cursor, old, *recolored;
+  int i, n, rc;
+  bool color_specified_p;
+  Emacs_Color color;
+
+  CHECK_STRING (arg);
+  color_specified_p = true;
+
+  if (!strcmp (SSDATA (arg), "font-color"))
+    color_specified_p = false;
+  else
+    rc = haiku_get_color (SSDATA (arg), &color);
+
+  if (color_specified_p && rc)
+    signal_error ("Invalid color", arg);
 
   output = FRAME_OUTPUT_DATA (f);
 
@@ -1876,24 +1974,30 @@ haiku_set_mouse_color (struct frame *f, Lisp_Object 
arg, Lisp_Object oldval)
          n = XFIXNUM (*custom_cursors[i].lisp_cursor);
 
          /* Create and set the custom cursor.  */
-         block_input ();
          *frame_cursor = BCursor_from_id (n);
-         unblock_input ();
+       }
+      else if (color_specified_p && cursor_bitmaps[i].bits)
+       {
+         recolored
+           = haiku_create_colored_cursor (&cursor_bitmaps[i], color.pixel,
+                                          FRAME_BACKGROUND_PIXEL (f));
 
-         /* 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;
+         if (recolored)
+           *frame_cursor = recolored;
+       }
+    }
 
-                 block_input ();
-                 BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
-                                        *frame_cursor);
-                 unblock_input ();
-               }
-           }
+  /* This function can be called before the frame's window is
+     created.  */
+  if (FRAME_HAIKU_WINDOW (f))
+    {
+      if (output->current_cursor == old
+         && old != *frame_cursor)
+       {
+         output->current_cursor = *frame_cursor;
+
+         BView_set_view_cursor (FRAME_HAIKU_VIEW (f),
+                                *frame_cursor);
        }
     }
 
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 49121629b3..3ef3f58495 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -577,11 +577,8 @@ haiku_query_frame_background_color (struct frame *f, 
Emacs_Color *bgcolor)
 }
 
 static bool
-haiku_defined_color (struct frame *f,
-                    const char *name,
-                    Emacs_Color *color,
-                    bool alloc,
-                    bool make_index)
+haiku_defined_color (struct frame *f, const char *name,
+                    Emacs_Color *color, bool alloc, bool make_index)
 {
   return !haiku_get_color (name, color);
 }



reply via email to

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