public inbox for linux-serial@vger.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: deller@gmx.de, gregkh@linuxfoundation.org, jirislaby@kernel.org,
	simona@ffwll.ch, sam@ravnborg.org
Cc: linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, linux-serial@vger.kernel.org,
	Thomas Zimmermann <tzimmermann@suse.de>
Subject: [PATCH 09/10] fbcon: Fill cursor mask in helper function
Date: Fri, 27 Mar 2026 13:49:42 +0100	[thread overview]
Message-ID: <20260327130431.59481-10-tzimmermann@suse.de> (raw)
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>

Fbcon creates a cursor shape on the fly from the user-configured
settings. The logic to create a glyph with the cursor's bitmap mask
is duplicated in four places. In the cases that involve console
rotation, the implementation further rotates the cursor glyph for
displaying.

Consolidate all cursor-mask creation in a single helper. Update the
callers accordingly. For console rotation, use the glyph helpers to
rotate the created cursor glyph to the correct orientation.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/video/fbdev/core/bitblit.c   | 35 ++-----------------
 drivers/video/fbdev/core/fbcon.c     | 40 ++++++++++++++++++++++
 drivers/video/fbdev/core/fbcon.h     |  2 ++
 drivers/video/fbdev/core/fbcon_ccw.c | 51 ++++++----------------------
 drivers/video/fbdev/core/fbcon_cw.c  | 51 ++++++----------------------
 drivers/video/fbdev/core/fbcon_ud.c  | 50 +++++++--------------------
 6 files changed, 78 insertions(+), 151 deletions(-)

diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 7478accea8ec..65681dcc5930 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -329,46 +329,17 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    vc->vc_cursor_type != par->p->cursor_shape ||
 	    par->cursor_state.mask == NULL ||
 	    par->cursor_reset) {
-		char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
-		int cur_height, size, i = 0;
-		u8 msk = 0xff;
+		unsigned char *mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
 
 		if (!mask)
 			return;
+		fbcon_fill_cursor_mask(par, vc, mask);
 
 		kfree(par->cursor_state.mask);
-		par->cursor_state.mask = mask;
+		par->cursor_state.mask = (const char *)mask;
 
 		par->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
-
-		switch (CUR_SIZE(par->p->cursor_shape)) {
-		case CUR_NONE:
-			cur_height = 0;
-			break;
-		case CUR_UNDERLINE:
-			cur_height = (vc->vc_font.height < 10) ? 1 : 2;
-			break;
-		case CUR_LOWER_THIRD:
-			cur_height = vc->vc_font.height/3;
-			break;
-		case CUR_LOWER_HALF:
-			cur_height = vc->vc_font.height >> 1;
-			break;
-		case CUR_TWO_THIRDS:
-			cur_height = (vc->vc_font.height << 1)/3;
-			break;
-		case CUR_BLOCK:
-		default:
-			cur_height = vc->vc_font.height;
-			break;
-		}
-		size = (vc->vc_font.height - cur_height) * w;
-		while (size--)
-			mask[i++] = ~msk;
-		size = cur_height * w;
-		while (size--)
-			mask[i++] = msk;
 	}
 
 	par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 8641b0b3edc4..345d9aa193f0 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -446,6 +446,46 @@ static void fbcon_del_cursor_work(struct fb_info *info)
 	cancel_delayed_work_sync(&par->cursor_work);
 }
 
+void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask)
+{
+	static const unsigned char pattern = 0xff;
+	unsigned int pitch = vc_font_pitch(&vc->vc_font);
+	unsigned int cur_height, size;
+
+	switch (CUR_SIZE(vc->vc_cursor_type)) {
+	case CUR_NONE:
+		cur_height = 0;
+		break;
+	case CUR_UNDERLINE:
+		if (vc->vc_font.height < 10)
+			cur_height = 1;
+		else
+			cur_height = 2;
+		break;
+	case CUR_LOWER_THIRD:
+		cur_height = vc->vc_font.height / 3;
+		break;
+	case CUR_LOWER_HALF:
+		cur_height = vc->vc_font.height / 2;
+		break;
+	case CUR_TWO_THIRDS:
+		cur_height = (vc->vc_font.height * 2) / 3;
+		break;
+	case CUR_BLOCK:
+	default:
+		cur_height = vc->vc_font.height;
+		break;
+	}
+
+	size = (vc->vc_font.height - cur_height) * pitch;
+	while (size--)
+		*mask++ = (unsigned char)~pattern;
+
+	size = cur_height * pitch;
+	while (size--)
+		*mask++ = pattern;
+}
+
 #ifndef MODULE
 static int __init fb_console_setup(char *this_opt)
 {
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 1793f34a6c84..bb0727b70631 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -192,6 +192,8 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
 extern void fbcon_set_bitops_ur(struct fbcon_par *par);
 extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 
+void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask);
+
 #define FBCON_ATTRIBUTE_UNDERLINE 1
 #define FBCON_ATTRIBUTE_REVERSE   2
 #define FBCON_ATTRIBUTE_BOLD      4
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 72453a2aaca8..723d9a33067f 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -296,57 +296,26 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    vc->vc_cursor_type != par->p->cursor_shape ||
 	    par->cursor_state.mask == NULL ||
 	    par->cursor_reset) {
-		char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
-						 GFP_ATOMIC);
-		int cur_height, size, i = 0;
-		int width = font_glyph_pitch(vc->vc_font.width);
+		unsigned char *tmp, *mask;
 
-		if (!mask)
+		tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+		if (!tmp)
 			return;
+		fbcon_fill_cursor_mask(par, vc, tmp);
 
-		tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC);
-
-		if (!tmp) {
-			kfree(mask);
+		mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
+		if (!mask) {
+			kfree(tmp);
 			return;
 		}
+		font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+		kfree(tmp);
 
 		kfree(par->cursor_state.mask);
-		par->cursor_state.mask = mask;
+		par->cursor_state.mask = (const char *)mask;
 
 		par->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
-
-		switch (CUR_SIZE(par->p->cursor_shape)) {
-		case CUR_NONE:
-			cur_height = 0;
-			break;
-		case CUR_UNDERLINE:
-			cur_height = (vc->vc_font.height < 10) ? 1 : 2;
-			break;
-		case CUR_LOWER_THIRD:
-			cur_height = vc->vc_font.height/3;
-			break;
-		case CUR_LOWER_HALF:
-			cur_height = vc->vc_font.height >> 1;
-			break;
-		case CUR_TWO_THIRDS:
-			cur_height = (vc->vc_font.height << 1)/3;
-			break;
-		case CUR_BLOCK:
-		default:
-			cur_height = vc->vc_font.height;
-			break;
-		}
-
-		size = (vc->vc_font.height - cur_height) * width;
-		while (size--)
-			tmp[i++] = 0;
-		size = cur_height * width;
-		while (size--)
-			tmp[i++] = 0xff;
-		font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask);
-		kfree(tmp);
 	}
 
 	par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 5690fc1d7854..732d093d462f 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -279,57 +279,26 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    vc->vc_cursor_type != par->p->cursor_shape ||
 	    par->cursor_state.mask == NULL ||
 	    par->cursor_reset) {
-		char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
-						 GFP_ATOMIC);
-		int cur_height, size, i = 0;
-		int width = font_glyph_pitch(vc->vc_font.width);
+		unsigned char *tmp, *mask;
 
-		if (!mask)
+		tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+		if (!tmp)
 			return;
+		fbcon_fill_cursor_mask(par, vc, tmp);
 
-		tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC);
-
-		if (!tmp) {
-			kfree(mask);
+		mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
+		if (!mask) {
+			kfree(tmp);
 			return;
 		}
+		font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+		kfree(tmp);
 
 		kfree(par->cursor_state.mask);
-		par->cursor_state.mask = mask;
+		par->cursor_state.mask = (const char *)mask;
 
 		par->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
-
-		switch (CUR_SIZE(par->p->cursor_shape)) {
-		case CUR_NONE:
-			cur_height = 0;
-			break;
-		case CUR_UNDERLINE:
-			cur_height = (vc->vc_font.height < 10) ? 1 : 2;
-			break;
-		case CUR_LOWER_THIRD:
-			cur_height = vc->vc_font.height/3;
-			break;
-		case CUR_LOWER_HALF:
-			cur_height = vc->vc_font.height >> 1;
-			break;
-		case CUR_TWO_THIRDS:
-			cur_height = (vc->vc_font.height << 1)/3;
-			break;
-		case CUR_BLOCK:
-		default:
-			cur_height = vc->vc_font.height;
-			break;
-		}
-
-		size = (vc->vc_font.height - cur_height) * width;
-		while (size--)
-			tmp[i++] = 0;
-		size = cur_height * width;
-		while (size--)
-			tmp[i++] = 0xff;
-		font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask);
-		kfree(tmp);
 	}
 
 	par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index f7cd89c42b01..a1981fa4701a 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -326,50 +326,26 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    vc->vc_cursor_type != par->p->cursor_shape ||
 	    par->cursor_state.mask == NULL ||
 	    par->cursor_reset) {
-		char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
-		int cur_height, size, i = 0;
-		u8 msk = 0xff;
+		unsigned char *tmp, *mask;
 
-		if (!mask)
+		tmp = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+		if (!tmp)
 			return;
+		fbcon_fill_cursor_mask(par, vc, tmp);
+
+		mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+		if (!mask) {
+			kfree(tmp);
+			return;
+		}
+		font_glyph_rotate_180(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+		kfree(tmp);
 
 		kfree(par->cursor_state.mask);
-		par->cursor_state.mask = mask;
+		par->cursor_state.mask = (const char *)mask;
 
 		par->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
-
-		switch (CUR_SIZE(par->p->cursor_shape)) {
-		case CUR_NONE:
-			cur_height = 0;
-			break;
-		case CUR_UNDERLINE:
-			cur_height = (vc->vc_font.height < 10) ? 1 : 2;
-			break;
-		case CUR_LOWER_THIRD:
-			cur_height = vc->vc_font.height/3;
-			break;
-		case CUR_LOWER_HALF:
-			cur_height = vc->vc_font.height >> 1;
-			break;
-		case CUR_TWO_THIRDS:
-			cur_height = (vc->vc_font.height << 1)/3;
-			break;
-		case CUR_BLOCK:
-		default:
-			cur_height = vc->vc_font.height;
-			break;
-		}
-
-		size = cur_height * w;
-
-		while (size--)
-			mask[i++] = msk;
-
-		size = (vc->vc_font.height - cur_height) * w;
-
-		while (size--)
-			mask[i++] = ~msk;
 	}
 
 	par->cursor_state.enable = enable && !use_sw;
-- 
2.53.0


  parent reply	other threads:[~2026-03-27 13:04 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-27 12:49 [PATCH 00/10] fbcon,fonts: Refactor framebuffer console rotation Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 01/10] fbcon: Avoid OOB font access if console rotation fails Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 02/10] vt: Implement helpers for struct vc_font in source file Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 03/10] lib/fonts: Provide helpers for calculating glyph pitch and size Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 04/10] lib/fonts: Clean up Makefile Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 05/10] lib/fonts: Implement glyph rotation Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 06/10] lib/fonts: Refactor glyph-pattern helpers Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 07/10] lib/fonts: Refactor glyph-rotation helpers Thomas Zimmermann
2026-03-27 12:49 ` [PATCH 08/10] lib/fonts: Implement font rotation Thomas Zimmermann
2026-03-27 12:49 ` Thomas Zimmermann [this message]
2026-03-27 12:49 ` [PATCH 10/10] fbcon: Put font-rotation state into separate struct Thomas Zimmermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260327130431.59481-10-tzimmermann@suse.de \
    --to=tzimmermann@suse.de \
    --cc=deller@gmx.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jirislaby@kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=sam@ravnborg.org \
    --cc=simona@ffwll.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox