Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable cursor for the frame buffer console #79

Open
2 of 4 tasks
frno7 opened this issue May 11, 2022 · 15 comments
Open
2 of 4 tasks

Enable cursor for the frame buffer console #79

frno7 opened this issue May 11, 2022 · 15 comments
Labels
enhancement New feature or request

Comments

@frno7
Copy link
Owner

frno7 commented May 11, 2022

Do

  • display the cursor by XOR;
  • have the cursor blink, if /sys/class/graphics/fbcon/cursor_blink is nonzero;
  • figure out whether the cursor can attain shapes other than FB_TILE_CURSOR_UNDERLINE by some console command or other reasonable means;
  • figure out whether foreground and background cursor colours are supposed to do anything.

For details, see #10 (comment).

@frno7 frno7 added the enhancement New feature or request label May 11, 2022
@frno7
Copy link
Owner Author

frno7 commented May 11, 2022

We’ve now got a XOR cursor in the console. @rickgaiser, setting up the ALPHA register was simple:

        GIF_PACKAGE_AD(package) {
                .addr = gs_addr_alpha_1,
                .data.alpha_1 = {
                        .a = gs_alpha_a_cs,
                        .b = gs_alpha_b_cd,
                        .c = gs_alpha_c_fix,
                        .d = gs_alpha_d_0,
                        .fix = GS_ALPHA_ONE
                }
        };

Then it was only a matter of sending four GS packages for a sprite with the abe field set to gs_blendning_on:

        GIF_PACKAGE_TAG(package) {
                .flg = gif_reglist_mode,
                .reg0 = gif_reg_prim,
                .reg1 = gif_reg_rgbaq,
                .reg2 = gif_reg_xyz2,
                .reg3 = gif_reg_xyz2,
                .nreg = 4,
                .nloop = 1,
                .eop = 1
        };
        GIF_PACKAGE_REG(package) {
                .lo.prim = {
                        .abe = gs_blendning_on,
                        .prim = gs_sprite
                },
                .hi.rgbaq = c->fg_rgbaq
        };
        GIF_PACKAGE_REG(package) {
                .lo.xyz2 = {
                        .x = gs_fbcs_to_pcs(c->sx),
                        .y = gs_fbcs_to_pcs(c->sy + c->th - c->dy)
                },
                .hi.xyz2 = {
                        .x = gs_fbcs_to_pcs(c->sx + c->tw),
                        .y = gs_fbcs_to_pcs(c->sy + c->th)
                }
        };

The cursor shape FB_TILE_CURSOR_UNDERLINE seems hardwired by the kernel, but all shapes are available in ps2fb.c:

	const u32 ch =
		cursor->shape == FB_TILE_CURSOR_NONE        ? 0 :
		cursor->shape == FB_TILE_CURSOR_UNDERLINE   ? 1 :
		cursor->shape == FB_TILE_CURSOR_LOWER_THIRD ? th / 3 :
		cursor->shape == FB_TILE_CURSOR_LOWER_HALF  ? th / 2 :
		cursor->shape == FB_TILE_CURSOR_TWO_THIRDS  ? (2 * th) / 3 :
		cursor->shape == FB_TILE_CURSOR_BLOCK       ? th : th;

Also, the cursor isn’t blinking but it remains unclear by which logic it would. Anyhow, a reasonable cursor is displayed now. :-)

@frno7
Copy link
Owner Author

frno7 commented May 11, 2022

@rickgaiser, in addition, I think the alpha blending function, with similarities to a blitter, will be highly useful for a fully GS-accelerated X window system, eventually. :-)

@Arch91
Copy link

Arch91 commented May 11, 2022

@rickgaiser, thank you very much for that! @frno7, way to go!
@frno7, how about also to fit the GNU linux cursor tune standard? As I previously noted in the issue #10, there (in GNU standardized linux) is possible to change the background color of the cursor, the speed of it's flashing and the times after those flashing stops - on the way, by directing the value into some parameter which is/are mounted in /sys/ folder. As an example what I mean, for the first one, the cursor color, it can be changed using this command:
echo N > /sys/module/vt/parameters/cur_default
where N is the integer value from 0 to 15. And each this value corresponds to the appropriate color. Those colors should be the same as in GNU standard.
And same parameter tunes availability for the speed of flashing/blinking and for the 'times after those flashings/blinkings stops'.

@frno7
Copy link
Owner Author

frno7 commented May 11, 2022

@Arch91, I figured out how to manipulate the shape of the cursor. Amusingly, it works already: try echo -e "\e[?6c", with 6 meaning a CUR_BLOCK shape as per

#define CUR_DEF 0
#define CUR_NONE 1
#define CUR_UNDERLINE 2
#define CUR_LOWER_THIRD 3
#define CUR_LOWER_HALF 4
#define CUR_TWO_THIRDS 5
#define CUR_BLOCK 6

@frno7
Copy link
Owner Author

frno7 commented May 11, 2022

Haha, try echo -e '\033[?17;0;64c' for a big red block of a cursor! :-) See some details in Documentation/admin-guide/vga-softcursor.rst.

@frno7
Copy link
Owner Author

frno7 commented May 11, 2022

@Arch91, a cursor blinking like a Christmas tree could be a real crowd-pleaser. We should make a test suite to cover the combinations of settings. It seems most if not all settings can be applied using the echo command with various escape sequences.

@Arch91
Copy link

Arch91 commented May 12, 2022

We should make a test suite to cover the combinations of settings. It seems most if not all settings can be applied using the echo command with various escape sequences.

Yes, and there should be a tutotial which describes the all available values for the all parameters, with an examples (4 high bits - background, 4 low bits - foreground, and for the both - the first cipher turns blinking/highliting, and the last three ciphers sets the color code (what are high/low bits, where they are in the examples, where to get the color code combos appropriate the colors)). Though, I see there is not described what need to be done to certainly achieve the blinking cursor, to set the times it will blink and after that times and moments of blinkings passed it will not blinks until cursor moving, and the speed between the moments of those blinkings.
From the other side... it might be that blinking times/moments related things I described are available in Xes, not in the main terminal/console...

@frno7
Copy link
Owner Author

frno7 commented May 12, 2022

The article Cursor Appearance in the Linux Console is apparently an interpretation of Documentation/admin-guide/vga-softcursor.rst. The Wikipedia article on VGA text mode also says some things about the cursor, for example that

the VGA standard does not provide a way to alter the blink rate, although common workarounds involve hiding the cursor and using a normal character glyph to provide a so-called software cursor.

I could imagine that the kernel console would emulate blinking in software, either by periodically alternating the shape of the cursor with FB_TILE_CURSOR_NONE (to have it temporarily vanish) as in

cursor->shape == FB_TILE_CURSOR_NONE ? 0 :

or by setting mode to 0 meaning erase as in

__u32 mode; /* 0 = erase, 1 = draw */

but the kernel console doesn’t seem to do any of those two alternatives for a blinking cursor effect.

Also, the ps2fb driver already makes use of foreground fg cursor colour in

.fg_rgbaq = console_pseudo_palette(cursor->fg, par)

(which can be observed with echo -e '\033[?17;0;64c' for a red block cursor), but there’s also an background bg cursor colour setting in

__u32 bg; /* background color */

that’s maybe the colour of the upper part of the cursor?

@frno7
Copy link
Owner Author

frno7 commented May 12, 2022

Cursor blinking is on a timer function fb_flashcursor in

static void fb_flashcursor(struct work_struct *work)
{
struct fb_info *info = container_of(work, struct fb_info, queue);
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data *vc = NULL;
int c;
int mode;
int ret;
/* FIXME: we should sort out the unbind locking instead */
/* instead we just fail to flash the cursor if we can't get
* the lock instead of blocking fbcon deinit */
ret = console_trylock();
if (ret == 0)
return;
if (ops && ops->currcon != -1)
vc = vc_cons[ops->currcon].d;
if (!vc || !con_is_visible(vc) ||
registered_fb[con2fb_map[vc->vc_num]] != info ||
vc->vc_deccm != 1) {
console_unlock();
return;
}
c = scr_readw((u16 *) vc->vc_pos);
mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
CM_ERASE : CM_DRAW;
ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
get_color(vc, info, c, 0));
console_unlock();
}

and it calls tile_cursor in

static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
int softback_lines, int fg, int bg)
{
struct fb_tilecursor cursor;
int use_sw = (vc->vc_cursor_type & 0x10);
cursor.sx = vc->vc_x;
cursor.sy = vc->vc_y;
cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
cursor.fg = fg;
cursor.bg = bg;
switch (vc->vc_cursor_type & 0x0f) {
case CUR_NONE:
cursor.shape = FB_TILE_CURSOR_NONE;
break;
case CUR_UNDERLINE:
cursor.shape = FB_TILE_CURSOR_UNDERLINE;
break;
case CUR_LOWER_THIRD:
cursor.shape = FB_TILE_CURSOR_LOWER_THIRD;
break;
case CUR_LOWER_HALF:
cursor.shape = FB_TILE_CURSOR_LOWER_HALF;
break;
case CUR_TWO_THIRDS:
cursor.shape = FB_TILE_CURSOR_TWO_THIRDS;
break;
case CUR_BLOCK:
default:
cursor.shape = FB_TILE_CURSOR_BLOCK;
break;
}
info->tileops->fb_tilecursor(info, &cursor);
}

but it’s not entirely clear what, if anything, is controlling a blinking effect.

@frno7
Copy link
Owner Author

frno7 commented May 16, 2022

@Arch91, if you’re satisfied with a dirty blinker, try this 3-line piece of hack (having the new blink variable as indicated by <<<----) for the write_cb_tilecursor function:

        static bool blink;    // <<<----
        union package * const base_package = par->package.buffer;
        union package *package = base_package;
        const u32 tw = par->cb.tile.width;
        const u32 th = par->cb.tile.height;
        const u32 dy =
                blink                                       ? 0 :    // <<<----
                cursor->shape == FB_TILE_CURSOR_NONE        ? 0 :
                cursor->shape == FB_TILE_CURSOR_UNDERLINE   ? 1 :
                cursor->shape == FB_TILE_CURSOR_LOWER_THIRD ? th / 3 :
                cursor->shape == FB_TILE_CURSOR_LOWER_HALF  ? th / 2 :
                cursor->shape == FB_TILE_CURSOR_TWO_THIRDS  ? (2 * th) / 3 :
                cursor->shape == FB_TILE_CURSOR_BLOCK       ? th : th;
        const struct cb_cursor c = {
                .sx = (var->xoffset + tw * cursor->sx) % var->xres_virtual,
                .sy = (var->yoffset + th * cursor->sy) % var->yres_virtual,
                .dy = dy,
                .tw = tw,
                .th = th,
                .draw = cursor->mode,
                .fg_rgbaq = console_pseudo_palette(cursor->fg, par)
        };

        blink = !blink;    // <<<----

Then do echo -e "\e[?6c", as previously mentioned, for a big block of blinking awesomeness. :-)

@Arch91
Copy link

Arch91 commented May 16, 2022

The nearest time I only was reading your posts, guys, but today I redownloaded the source code from the main branch of the linux repository, recompiled the kernel and updated the modules in the appropriate places. Also changed to modprobe ps2fb instead of gs (the new cursor codes are not applied to the drm driver yet?..) in the initramfs init script.
@frno7, you forced me to search the place where to apply those blink inlines!) That's the kernel_source/drivers/video/fbdev/ps2fb.c file.
I wrote those three places you marked with <<<---- by looking to your post. I loaded the kernel and obtained that the cursor is not blinking. Isn't there a chance that it is blinking SO FAST so I can't notice the blinking? I used mode_option=1920x1080p@50 mode_margin=+13+0 addition for the modprobe ps2fb inline, if that matters as to be noted for my videomode choosed.

Then do echo -e "\e[?6c"

I saw just a white rectangle/block. I tried them all from 0 to 6)

try echo -e '\033[?17;0;64c' for a big red block of a cursor!

Red. Nice.

satisfied with a dirty blinker

Well, I described the perfect) Adjustable cursor blink times and after these times and moments of blinkings passed it will not blinks until cursor moving; adjustable speed between the moments of those blinkings - both of GNU standards, which means that if there could be an app which tweaks those things, then that app will be working without any edits/additions in it's source code.
But as I noted, maybe those things are not related to main terminal console. And in the console there is a non-blinking cursor only. I'm not sure about that.

And a side question. Is ps2fb driver ready for to be launched through Xvfb X-server?

@frno7
Copy link
Owner Author

frno7 commented May 16, 2022

(the new cursor codes are not applied to the non-drm driver yet?..)

No, the DRM driver is likely to become deprecated.

I loaded the kernel and obtained that the cursor is not blinking.

Did you rerun make modules_install and so on after adding the blinker?

I loaded the kernel and obtained that the cursor is not blinking. Isn't there a chance that it is blinking SO FAST so I can't notice the blinking?

Probably not too fast, no.

Then do echo -e "\e[?6c"

I saw just a white rectangle/block. I tried them all from 0 to 6)

This one should blink. Check that /sys/class/graphics/fbcon/cursor_blink is 1 also.

try echo -e '\033[?17;0;64c' for a big red block of a cursor!

Red. Nice.

This one turns off blinking, though...

Well, I described the perfect) Adjustable cursor blink times and after these times and moments of blinkings passed it will not blinks until cursor moving; adjustable speed between the moments of those blinkings - both of GNU standards, which means that if there could be an app which tweaks those things, then that app will be working without any edits/additions in it's source code. But as I noted, maybe those things are not related to main terminal console. And in the console there is a non-blinking cursor only. I'm not sure about that.

Moving the cursor should not be necessary. It should blink by itself, and at least it does for me.

And a side question. Is ps2fb driver ready for to be launched through Xvfb X-server?

Not yet, it only does text at the moment. But it's pretty effective at that. :-)

@Arch91
Copy link

Arch91 commented May 16, 2022

Did you rerun make modules_install and so on after adding the blinker?

Well, yes, that was the place where I made a mistake - my old modules were placed in initramfs(and in my target system too)/lib/modules/5.4.169 while the modules from the new kernel are now placed in initramfs/lib/modules/5.4.169+ (with plus). I removed that 5.4.169 folder before the kernel recompiling. And that blinds my eyes, I thought that after the ps2fb.c is edited, the kernel rebuilding is enough. I did not mind about that modules must be rebuilt either. Exactly that ps2fb.c related edits are for the appropriate module.
Now I saw the blinking. About 2.5-3 times in second.

By the way, if to change the cursor shape to rectangle with echo -e "\e[?6c" and then to use a nano text editor with a further quit from the editing screen - the cursor shape changes back to the underline. In different from the vi text editor -
the cursor stays unchanged before, while and after the vi using.

Moving the cursor should not be necessary. It should blink by itself, and at least it does for me.

after these times and moments of blinkings passed it will not blinks until cursor moving

I mean... other. Here is the example of the cursor behaviour in the terminal with Xes in my Fedora 30:
The time before the blinkings is 1 second - visible->half_of_sec_passed->not_visible->half_of_sec_passed->visible->...
If to do nothing/not doing the cursor moves - it blinks 10 times and becomes constantly visible UNTIL you'll push some keyboard button or escape-return to the window of that terminal.

Not yet

I dare myself an unwary question of inquire - what is insufficient in ps2fb to become a serious linux videodriver?) I'm just in curious, I beleive whatever the answer I can't influence for that driver upgradation in any imaginable by me way :/

@frno7
Copy link
Owner Author

frno7 commented May 17, 2022

Now I saw the blinking. About 2.5-3 times in second.

Nice! I made the dirty blinker default in the latest precompiled actions download. If people are annoyed, we can turn blinking off again...

By the way, if to change the cursor shape to rectangle with echo -e "\e[?6c" and then to use a nano text editor with a further quit from the editing screen - the cursor shape changes back to the underline. In different from the vi text editor - the cursor stays unchanged before, while and after the vi using.

Maybe the Nano editor is being naughty with the cursor settings? Resetting it perhaps? Bad, bad, editor.

I mean... other. Here is the example of the cursor behaviour in the terminal with Xes in my Fedora 30: The time before the blinkings is 1 second - visible->half_of_sec_passed->not_visible->half_of_sec_passed->visible->... If to do nothing/not doing the cursor moves - it blinks 10 times and becomes constantly visible UNTIL you'll push some keyboard button or escape-return to the window of that terminal.

The blinking we have now is a dirty piece of hack. As mentioned, it’s a bit of a mystery how the cursor actually is going to blink properly...

I dare myself an unwary question of inquire - what is insufficient in ps2fb to become a serious linux videodriver?) I'm just in curious, I beleive whatever the answer I can't influence for that driver upgradation in any imaginable by me way :/

The two main alternatives to the current text console, as I see it, are

A virtual frame buffer is best for compatibility with existing application software, but generally has poor performance, both in terms of speed and memory usage. For simple applications, performance may not matter, though. They may be fast enough anyway. A Graphics Synthesizer device can have excellent performance and memory usage, and make really good use of the hardware acceleration resources of the PlayStation 2, but it requires application software adjustments, which may be difficult to do.

@Arch91
Copy link

Arch91 commented May 20, 2022

Well, totally the only info I found is that

echo -e "\e[?6c"

all these seven (six and invisible) shapes are blinking by default. The blinking can be disabled by setting 0 to /sys/class/graphics/fbcon/cursor_blink so it seems that cursor_blink is 1 by default.

Adjustable cursor blink times

It is called "cursor blink rate". It someway controlled by an escape sequence, the example of the setting it to 600milliseconds:
echo '\e[16;600]'

I did not find the info about the adjusting of "when the times and moments of blinkings passed it will not blinks until cursor moving". I consider this feature is controllable by some side libraries such as terminfo or else, and maybe even when the cursor is choosed as softwared.

I may assume that the "serenity" (not what is dirty for now) cursor was not blinking because of the absent blinking rate feature. If to assume that the blinking rate is 0 while the blinking is enabled (1) then it would happy to blink, but the blinking rate is momental, so no blinking)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants